15 #include <mrpt/containers/yaml.h>
16 #include <mrpt/maps/CSimplePointsMap.h>
17 #include <mrpt/math/ops_containers.h>
18 #include <mrpt/random/RandomGenerators.h>
27 const mrpt::containers::yaml& c)
47 MRPT_LOG_DEBUG_STREAM(
"Loading these params:\n" << c);
64 mrpt::maps::CPointsMap::Ptr outPc =
68 mrpt::maps::CPointsMap* pcPtr =
nullptr;
70 itLy != inOut.
layers.end())
75 "Layer '%s' must be of point cloud type.",
84 "Input layer '%s' not found on input map.",
95 const auto& rawPc = *pcPtr;
97 mrpt::maps::CSimplePointsMap pc;
98 pc.reserve(rawPc.size());
100 const auto& xs = rawPc.getPointsBufferRef_x();
101 const auto& ys = rawPc.getPointsBufferRef_y();
102 const auto& zs = rawPc.getPointsBufferRef_z();
103 for (
size_t i = 0; i < xs.size(); i++)
108 pc.mark_as_modified();
111 outPc->reserve(outPc->size() + pc.size() / 10);
120 auto rng = mrpt::random::CRandomGenerator();
124 auto lambdaInsertPt = [&outPc](
float x,
float y,
float z)
125 { outPc->insertPointFast(
x, y, z); };
127 size_t nonEmptyVoxels = 0;
133 if (vxl.
indices.empty())
return;
141 auto mean = mrpt::math::TPoint3Df(0, 0, 0);
142 const float inv_n = (1.0f / vxl.
indices.size());
143 for (
size_t i = 0; i < vxl.
indices.size(); i++)
145 const auto pt_idx = vxl.
indices[i];
146 mean.x += xs[pt_idx];
147 mean.y += ys[pt_idx];
148 mean.z += zs[pt_idx];
154 std::optional<float> minSqrErr;
155 std::optional<size_t> bestIdx;
157 for (
size_t i = 0; i < vxl.
indices.size(); i++)
159 const auto pt_idx = vxl.
indices[i];
160 const float sqrErr = mrpt::square(xs[pt_idx] - mean.x) +
161 mrpt::square(ys[pt_idx] - mean.y) +
162 mrpt::square(zs[pt_idx] - mean.z);
164 if (!minSqrErr.has_value() || sqrErr < *minSqrErr)
171 lambdaInsertPt(xs[*bestIdx], ys[*bestIdx], zs[*bestIdx]);
176 lambdaInsertPt(mean.x, mean.y, mean.z);
182 const auto idxInVoxel =
184 ? (rng.drawUniform64bit() % vxl.
indices.size())
187 const auto pt_idx = vxl.
indices.at(idxInVoxel);
188 lambdaInsertPt(xs[pt_idx], ys[pt_idx], zs[pt_idx]);
192 outPc->mark_as_modified();
194 MRPT_LOG_DEBUG_STREAM(
"Voxel counts: total=" << nonEmptyVoxels);