@@ -199,14 +199,13 @@ class CPointsMap :
199199 const size_t N = obj.size ();
200200 this ->clear ();
201201 this ->reserve (N);
202- for (size_t i = 0 ; i < N; i++) insertPointFrom (obj, i);
202+ this ->registerPointFieldsFrom (obj);
203+ for (size_t i = 0 ; i < N; i++)
204+ {
205+ insertPointFrom (obj, i);
206+ }
203207 }
204208
205- /* * Auxiliary method called from within \a addFrom() automatically, to
206- * finish the copying of class-specific data */
207- virtual void addFrom_classSpecific (
208- const CPointsMap& anotherMap, size_t nPreviousPoints, const bool filterOutPointsAtZero) = 0;
209-
210209 public:
211210 /* * @} */
212211 // --------------------------------------------
@@ -357,6 +356,30 @@ class CPointsMap :
357356 insertAnotherMap (&anotherMap, mrpt::poses::CPose3D::Identity ());
358357 }
359358
359+ /* * @name Register/unregister custom data fields
360+ @{ */
361+
362+ /* * Registers a new data channel of type `float`.
363+ * If the map is not empty, the new channel is filled with default values (0)
364+ * to match the current point count.
365+ * \return true if the field could effectively be added to the underlying point map class.
366+ * \sa hasPointField(), getPointFieldNames_float()
367+ */
368+ virtual bool registerField_float (const std::string& fieldName)
369+ {
370+ return fieldName == " x" || fieldName == " y" || fieldName == " z" ;
371+ }
372+
373+ /* * Registers a new data channel of type `uint16_t`.
374+ * If the map is not empty, the new channel is filled with default values (0)
375+ * to match the current point count.
376+ * \return true if the field could effectively be added to the underlying point map class.
377+ * \sa hasPointField(), getPointFieldNames_uint16()
378+ */
379+ virtual bool registerField_uint16 (const std::string& fieldName) { return false ; }
380+
381+ /* * @} */
382+
360383 // --------------------------------------------------
361384 /* * @name File input/output methods
362385 @{ */
@@ -745,16 +768,34 @@ class CPointsMap :
745768 }
746769
747770 /* * Must be called before insertPointFrom() to make sure we have the required fields.
771+ * \return true if ALL fields could be added, false if some would be missing because the
772+ * underlying point cloud class cannot hold them.
748773 */
749- void copyPointFieldsFrom (const mrpt::maps::CPointsMap& source)
774+ bool registerPointFieldsFrom (const mrpt::maps::CPointsMap& source)
750775 {
751- //
752- xx;
776+ bool allAdded = true ;
777+ for (const auto & f : source.getPointFieldNames_float ())
778+ {
779+ if (!this ->hasPointField (f))
780+ {
781+ const bool added = registerField_float (f);
782+ allAdded = allAdded && added;
783+ }
784+ }
785+ for (const auto & f : source.getPointFieldNames_uint16 ())
786+ {
787+ if (!this ->hasPointField (f))
788+ {
789+ const bool added = this ->registerField_uint16 (f);
790+ allAdded = allAdded && added;
791+ }
792+ }
793+ return allAdded;
753794 }
754795
755796 /* * Generic method to copy *all* applicable point properties from
756797 * one map to another, e.g. timestamp, intensity, etc.
757- * \note Before calling this in a loop, make sure of calling copyPointFieldsFrom ()
798+ * \note Before calling this in a loop, make sure of calling registerPointFieldsFrom ()
758799 */
759800 void insertPointFrom (const mrpt::maps::CPointsMap& source, size_t sourcePointIndex)
760801 {
@@ -768,11 +809,11 @@ class CPointsMap :
768809 // Optional fields: only if they already exist on both maps:
769810 for (const auto & f : this ->getPointFieldNames_float ())
770811 {
771- insertPointField_float (f, this -> getPointField_float (i, f));
812+ insertPointField_float (f, source. getPointField_float (i, f));
772813 }
773814 for (const auto & f : this ->getPointFieldNames_uint16 ())
774815 {
775- insertPointField_uint16 (f, this -> getPointField_uint16 (i, f));
816+ insertPointField_uint16 (f, source. getPointField_uint16 (i, f));
776817 }
777818 mark_as_modified ();
778819 }
@@ -1009,22 +1050,6 @@ class CPointsMap :
10091050 */
10101051 void getVisualizationInto (mrpt::opengl::CSetOfObjects& outObj) const override ;
10111052
1012- /* * This method returns the largest distance from the origin to any of the
1013- * points, such as a sphere centered at the origin with this radius cover
1014- * ALL the points in the map (the results are buffered, such as, if the map
1015- * is not modified, the second call will be much faster than the first one).
1016- */
1017- float getLargestDistanceFromOrigin () const ;
1018-
1019- /* * Like \a getLargestDistanceFromOrigin() but returns in \a output_is_valid
1020- * = false if the distance was not already computed, skipping its
1021- * computation then, unlike getLargestDistanceFromOrigin() */
1022- float getLargestDistanceFromOriginNoRecompute (bool & output_is_valid) const
1023- {
1024- output_is_valid = m_largestDistanceFromOriginIsUpdated;
1025- return m_largestDistanceFromOrigin;
1026- }
1027-
10281053 /* * Computes the bounding box of all the points, or (0,0 ,0,0, 0,0) if there
10291054 * are no points.
10301055 * Results are cached unless the map is somehow modified to avoid repeated
@@ -1212,7 +1237,6 @@ class CPointsMap :
12121237 * kd-tree cache, and such. */
12131238 inline void mark_as_modified () const
12141239 {
1215- m_largestDistanceFromOriginIsUpdated = false ;
12161240 m_boundingBoxIsUpdated = false ;
12171241 kdtree_mark_as_outdated ();
12181242 }
@@ -1277,16 +1301,6 @@ class CPointsMap :
12771301 /* * Cache of sin/cos values for the latest 2D scan geometries. */
12781302 mrpt::obs::CSinCosLookUpTableFor2DScans m_scans_sincos_cache;
12791303
1280- /* * Auxiliary variables used in "getLargestDistanceFromOrigin"
1281- * \sa getLargestDistanceFromOrigin
1282- */
1283- mutable float m_largestDistanceFromOrigin{0 };
1284-
1285- /* * Auxiliary variables used in "getLargestDistanceFromOrigin"
1286- * \sa getLargestDistanceFromOrigin
1287- */
1288- mutable bool m_largestDistanceFromOriginIsUpdated;
1289-
12901304 mutable bool m_boundingBoxIsUpdated;
12911305 mutable mrpt::math::TBoundingBoxf m_boundingBox;
12921306
@@ -1300,9 +1314,6 @@ class CPointsMap :
13001314 const mrpt::obs::CObservation& obs,
13011315 const std::optional<const mrpt::poses::CPose3D>& robotPose = std::nullopt ) override ;
13021316
1303- /* * Helper method for ::copyFrom() */
1304- void base_copyFrom (const CPointsMap& obj);
1305-
13061317 /* * @name PLY Import virtual methods to implement in base classes
13071318 @{ */
13081319 /* * In a base class, reserve memory to prepare subsequent calls to
0 commit comments