Skip to content

Commit 14d7327

Browse files
committed
Import new insert point with context
1 parent e32e918 commit 14d7327

File tree

2 files changed

+100
-18
lines changed

2 files changed

+100
-18
lines changed

modules/mrpt_maps/include/mrpt/maps/CPointsMap.h

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,16 @@ class CPointsMap :
176176
m_z[index] = z;
177177
}
178178

179-
/** The virtual method for \a insertPoint() *without* calling
180-
* mark_as_modified() */
181-
virtual void insertPointFast(float x, float y, float z = 0) = 0;
179+
/** Low-level method for \a insertPoint() *without* calling mark_as_modified().
180+
* Note that for derived classes having more per-point fields, you must ensure adding those fields
181+
* after this to keep the length of all vectors consistent.
182+
*/
183+
void insertPointFast(float x, float y, float z)
184+
{
185+
m_x.push_back(x);
186+
m_y.push_back(y);
187+
m_z.push_back(z);
188+
}
182189

183190
/** Get all the data fields for one point as a vector: depending on the
184191
* implementation class this can be [X Y Z] or [X Y Z R G B], etc...
@@ -205,9 +212,10 @@ class CPointsMap :
205212
this->clear();
206213
this->reserve(N);
207214
this->registerPointFieldsFrom(obj);
215+
const auto ctx = this->prepareForInsertPointsFrom(obj);
208216
for (size_t i = 0; i < N; i++)
209217
{
210-
insertPointFrom(obj, i);
218+
insertPointFrom(obj, i, ctx);
211219
}
212220
}
213221

@@ -803,28 +811,56 @@ class CPointsMap :
803811
return allAdded;
804812
}
805813

814+
/** Insert context for insertPointFrom().
815+
* \sa prepareForInsertPointsFrom()
816+
*/
817+
struct InsertCtx
818+
{
819+
// For XYZ
820+
const mrpt::aligned_std_vector<float>* xs_src = nullptr;
821+
const mrpt::aligned_std_vector<float>* ys_src = nullptr;
822+
const mrpt::aligned_std_vector<float>* zs_src = nullptr;
823+
824+
// Optional field mappings (only fields present in both maps)
825+
struct FloatFieldMapping
826+
{
827+
const mrpt::aligned_std_vector<float>* src_buf = nullptr;
828+
mrpt::aligned_std_vector<float>* dst_buf = nullptr;
829+
};
830+
std::vector<FloatFieldMapping> float_fields;
831+
832+
struct UInt16FieldMapping
833+
{
834+
const mrpt::aligned_std_vector<uint16_t>* src_buf = nullptr;
835+
mrpt::aligned_std_vector<uint16_t>* dst_buf = nullptr;
836+
};
837+
std::vector<UInt16FieldMapping> uint16_fields;
838+
};
839+
840+
/** Prepare efficient data structures for repeated insertion from another point map with
841+
* insertPointFrom() */
842+
InsertCtx prepareForInsertPointsFrom(const CPointsMap& source) const;
843+
806844
/** Generic method to copy *all* applicable point properties from
807845
* one map to another, e.g. timestamp, intensity, etc.
808846
* \note Before calling this in a loop, make sure of calling registerPointFieldsFrom()
809847
*/
810-
void insertPointFrom(const mrpt::maps::CPointsMap& source, size_t sourcePointIndex)
848+
void insertPointFrom(const CPointsMap& source, size_t sourcePointIndex, const InsertCtx& ctx)
811849
{
812-
const auto i = sourcePointIndex; // shortcut
813-
// mandatory fields: XYZ
814-
const auto& xs = source.getPointsBufferRef_x();
815-
const auto& ys = source.getPointsBufferRef_y();
816-
const auto& zs = source.getPointsBufferRef_z();
817-
insertPointFast(xs[i], ys[i], zs[i]);
818-
819-
// Optional fields: only if they already exist on both maps:
820-
for (const auto& f : this->getPointFieldNames_float_except_xyz())
850+
const size_t i = sourcePointIndex;
851+
insertPointFast((*ctx.xs_src)[i], (*ctx.ys_src)[i], (*ctx.zs_src)[i]);
852+
853+
// Optional fields
854+
for (auto& f : ctx.float_fields)
821855
{
822-
insertPointField_float(f, source.getPointField_float(i, f));
856+
f.dst_buf->push_back((*f.src_buf)[i]);
823857
}
824-
for (const auto& f : this->getPointFieldNames_uint16())
858+
859+
for (auto& f : ctx.uint16_fields)
825860
{
826-
insertPointField_uint16(f, source.getPointField_uint16(i, f));
861+
f.dst_buf->push_back((*f.src_buf)[i]);
827862
}
863+
828864
mark_as_modified();
829865
}
830866

@@ -1176,7 +1212,9 @@ class CPointsMap :
11761212
clear();
11771213
reserve(N);
11781214
for (size_t i = 0; i < N; ++i)
1215+
{
11791216
this->insertPointFast(cloud.points[i].x, cloud.points[i].y, cloud.points[i].z);
1217+
}
11801218
}
11811219

11821220
/** @} */

modules/mrpt_maps/src/maps/CPointsMap.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,8 @@ void CPointsMap::insertAnotherMap(
15281528
// matrix multiplications:
15291529
const bool identity_tf = (otherPose == CPose3D::Identity());
15301530

1531+
const auto ctx = this->prepareForInsertPointsFrom(*otherMap);
1532+
15311533
mrpt::math::TPoint3Df pt;
15321534
for (size_t srcIdx = 0; srcIdx < N_other; srcIdx++)
15331535
{
@@ -1542,7 +1544,7 @@ void CPointsMap::insertAnotherMap(
15421544
if (pt.x != pt.x) continue;
15431545

15441546
// Add to this map:
1545-
this->insertPointFrom(*otherMap, srcIdx);
1547+
this->insertPointFrom(*otherMap, srcIdx, ctx);
15461548

15471549
// and overwrite the XYZ, if needed:
15481550
if (!identity_tf)
@@ -2056,6 +2058,48 @@ std::vector<std::string_view> CPointsMap::getPointFieldNames_float_except_xyz()
20562058
return result;
20572059
}
20582060

2061+
CPointsMap::InsertCtx CPointsMap::prepareForInsertPointsFrom(const CPointsMap& source) const
2062+
{
2063+
InsertCtx ctx;
2064+
2065+
// Mandatory XYZ
2066+
ctx.xs_src = &source.getPointsBufferRef_x();
2067+
ctx.ys_src = &source.getPointsBufferRef_y();
2068+
ctx.zs_src = &source.getPointsBufferRef_z();
2069+
2070+
// Optional fields: match by name but store direct pointers
2071+
const auto src_float_names = source.getPointFieldNames_float_except_xyz();
2072+
const auto dst_float_names = this->getPointFieldNames_float_except_xyz();
2073+
2074+
for (const auto& name : dst_float_names)
2075+
{
2076+
if (auto it = std::find(src_float_names.begin(), src_float_names.end(), name);
2077+
it != src_float_names.end())
2078+
{
2079+
ctx.float_fields.push_back(
2080+
{source.getPointsBufferRef_float_field(name),
2081+
const_cast<mrpt::aligned_std_vector<float>*>(
2082+
this->getPointsBufferRef_float_field(name))});
2083+
}
2084+
}
2085+
2086+
const auto src_u16_names = source.getPointFieldNames_uint16();
2087+
const auto dst_u16_names = this->getPointFieldNames_uint16();
2088+
for (const auto& name : dst_u16_names)
2089+
{
2090+
if (auto it = std::find(src_u16_names.begin(), src_u16_names.end(), name);
2091+
it != src_u16_names.end())
2092+
{
2093+
ctx.uint16_fields.push_back(
2094+
{source.getPointsBufferRef_uint_field(name),
2095+
const_cast<mrpt::aligned_std_vector<uint16_t>*>(
2096+
this->getPointsBufferRef_uint_field(name))});
2097+
}
2098+
}
2099+
2100+
return ctx;
2101+
}
2102+
20592103
// =========== API of the NearestNeighborsCapable virtual interface ======
20602104
// See docs in base class
20612105
void CPointsMap::nn_prepare_for_2d_queries() const

0 commit comments

Comments
 (0)