103 featureLabels(featureLabels),
104 descriptorLabels(descriptorLabels)
116 const size_t pointCount):
117 featureLabels(featureLabels),
118 descriptorLabels(descriptorLabels),
119 timeLabels(timeLabels)
133 featureLabels(featureLabels)
140 featureLabels(featureLabels),
141 descriptors(descriptors),
142 descriptorLabels(descriptorLabels)
149 featureLabels(featureLabels),
150 descriptors(descriptors),
151 descriptorLabels(descriptorLabels),
153 timeLabels(timeLabels)
167 const size_t nbRows =
features.rows();
168 return (nbRows == 0) ? 0 : (nbRows - 1);
204 bool isEqual =
false;
228 const int nbPoints1 = this->
features.cols();
229 const int nbPoints2 = dp.
features.cols();
230 const int nbPointsTotal = nbPoints1 + nbPoints2;
232 const int dimFeat = this->
features.rows();
235 stringstream errorMsg;
236 errorMsg <<
"Cannot concatenate DataPoints because the dimension of the features are not the same. Actual dimension: " << dimFeat <<
" New dimension: " << dp.
features.rows();
241 this->
features.conservativeResize(Eigen::NoChange, nbPointsTotal);
257 template<
typename MatrixType>
260 const int nbPoints1 = data->cols();
261 const int nbPoints2 = extraData.cols();
262 const int nbPointsTotal = nbPoints1 + nbPoints2;
265 if (*labels == extraLabels)
267 if (labels->size() > 0)
270 data->conservativeResize(Eigen::NoChange, nbPointsTotal);
271 data->rightCols(nbPoints2) = extraData;
280 for(BOOST_AUTO(it, labels->begin()); it != labels->end(); ++it)
282 for(BOOST_AUTO(jt, extraLabels.begin()); jt != extraLabels.end(); ++jt)
284 if (it->text == jt->text)
286 if (it->span != jt->span)
288 (boost::format(
"The field %1% has dimension %2% in this, different than dimension %3% in that") % it->text % it->span % jt->span).str()
290 newLabels.push_back(*it);
297 if (newLabels.size() > 0)
302 assert(newLabels == filledLabels);
306 for(BOOST_AUTO(it, newLabels.begin()); it != newLabels.end(); ++it)
308 Eigen::Block<MatrixType> view(newData.block(row, 0, it->span, newData.cols()));
309 view.leftCols(nbPoints1) =
getViewByName(it->text, *labels, *data);
310 view.rightCols(nbPoints2) =
getViewByName(it->text, extraLabels, extraData);
320 *data = MatrixType();
330 features.conservativeResize(Eigen::NoChange, pointCount);
332 descriptors.conservativeResize(Eigen::NoChange, pointCount);
334 if (
times.cols() > 0)
335 times.conservativeResize(Eigen::NoChange, pointCount);
342 const int nbPoints(
features.cols());
356 if (
times.cols() > 0)
382 if (
times.cols() > 0)
400 if (
times.cols() > 0)
411 if (
times.cols() > 0)
440 addField<Matrix>(
"pad", Matrix::Ones(1,
features.cols()), featureLabels,
features);
729 (boost::format(
"Point cloud has degenerate %2% dimensions of rows=0, cols=%1%") % dataCols % dataName).str()
731 if (labels.size() > 0)
733 (boost::format(
"Point cloud has no %2% data but %1% descriptor labels") % labels.size() % dataName).str()
741 (boost::format(
"Point cloud has %1% points in features but %2% points in %3%") %
features.cols() % dataCols % dataName).str()
746 for (BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
749 if (dataRows != descDim)
751 (boost::format(
"Labels from %3% return %1% total dimensions but there are %2% in the %3% matrix") % descDim % dataRows % dataName).str()
760 template<
typename MatrixType>
769 (boost::format(
"The existing field %1% has dimension %2%, different than requested dimension %3%") % name % descDim % dim).str()
775 const int oldDim(data.rows());
776 const int totalDim(oldDim + dim);
777 const int pointCount(
features.cols());
778 data.conservativeResize(totalDim, pointCount);
779 labels.push_back(
Label(name, dim));
785 template<
typename MatrixType>
788 typedef vector<bool> BoolVector;
789 BoolVector present(newLabels.size(),
false);
792 size_t additionalDim(0);
793 for (
size_t i = 0; i < newLabels.size(); ++i)
795 const string& newName(newLabels[i].text);
796 const size_t newSpan(newLabels[i].span);
797 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
799 if (it->text == newName)
801 if (it->span != newSpan)
803 (boost::format(
"The existing field %1% has dimension %2%, different than requested dimension %3%") % newName % it->span % newSpan).str()
810 additionalDim += newSpan;
814 const int oldDim(data.rows());
815 const int totalDim(oldDim + additionalDim);
816 const int pointCount(
features.cols());
817 data.conservativeResize(totalDim, pointCount);
818 for (
size_t i = 0; i < newLabels.size(); ++i)
821 labels.push_back(newLabels[i]);
827 template<
typename MatrixType>
830 const int newFieldDim = newField.rows();
831 const int newPointCount = newField.cols();
832 const int pointCount =
features.cols();
834 if (newField.rows() == 0)
842 if(fieldDim == newFieldDim)
845 if(pointCount == newPointCount)
848 data.block(row, 0, fieldDim, pointCount) = newField;
852 stringstream errorMsg;
853 errorMsg <<
"The field " << name <<
" cannot be added because the number of points is not the same. Old point count: " << pointCount <<
"new: " << newPointCount;
859 stringstream errorMsg;
860 errorMsg <<
"The field " << name <<
" already exists but could not be added because the dimension is not the same. Old dim: " << fieldDim <<
" new: " << newFieldDim;
866 if(pointCount == newPointCount || pointCount == 0)
868 const int oldFieldDim(data.rows());
869 const int totalDim = oldFieldDim + newFieldDim;
870 data.conservativeResize(totalDim, newPointCount);
871 data.bottomRows(newFieldDim) = newField;
872 labels.push_back(
Label(name, newFieldDim));
876 stringstream errorMsg;
877 errorMsg <<
"The field " << name <<
" cannot be added because the number of points is not the same. Old point count: " << pointCount <<
" new: " << newPointCount;
884 template<
typename MatrixType>
890 const unsigned keepAfterId = deleteId + span;
891 const unsigned lastId = data.rows() - 1;
892 const unsigned sizeKeep = data.rows() - keepAfterId;
893 const unsigned nbPoints = data.cols();
897 if(keepAfterId <= lastId)
899 data.block(deleteId, 0, sizeKeep, nbPoints) = data.block(keepAfterId, 0, sizeKeep, nbPoints);
903 data.conservativeResize(data.rows()-span, nbPoints);
906 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
908 if (it->text == name)
921 template<
typename MatrixType>
925 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
927 if (it->text == name)
931 if (viewRow >=
int(it->span))
933 (boost::format(
"Requesting row %1% of field %2% that only has %3% rows") % viewRow % name % it->span).str()
935 return data.block(row + viewRow, 0, 1, data.cols());
938 return data.block(row, 0, it->span, data.cols());
948 template<
typename MatrixType>
952 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
954 if (it->text == name)
958 if (viewRow >=
int(it->span))
960 (boost::format(
"Requesting row %1% of field %2% that only has %3% rows") % viewRow % name % it->span).str()
962 return data.block(row + viewRow, 0, 1, data.cols());
965 return data.block(row, 0, it->span, data.cols());
976 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
978 if (it->text == name)
980 if (dim == 0 || it->span == dim)
994 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
996 if (it->text == name)
1004 template<
typename T>
1008 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
1010 if (it->text == name)
1022 template<
typename T>
unsigned getFieldStartingRow(const std::string &name, const Labels &labels) const
Return the starting row of a feature or a descriptor with a given name. Return 0 if the name is not f...
void removeField(const std::string &name, Labels &labels, MatrixType &data) const
Remove a descriptor or feature by name, no copy is done.
Matrix getFeatureCopyByName(const std::string &name) const
Get feature by name, return a matrix containing a copy of the requested feature.
void allocateDescriptor(const std::string &name, const unsigned dim)
Makes sure a descriptor of a given name exists, if present, check its dimensions. ...
void allocateTime(const std::string &name, const unsigned dim)
Makes sure a time of a given name exists, if present, check its dimensions.
void allocateTimes(const Labels &newLabels)
Make sure a vector of time of given names exist.
const Eigen::Block< const Int64Matrix > TimeConstView
a view on a const time
unsigned getTimeDimension(const std::string &name) const
Return the dimension of a time with a given name. Return 0 if the name is not found.
void assertConsistency(const std::string &dataName, const int dataRows, const int dataCols, const Labels &labels) const
Assert if a matrix is not consistent with features.
unsigned getTimeDim() const
Return the total number of times.
Matrix descriptors
descriptors of points in the cloud, might be empty
void removeTime(const std::string &name)
Remove a descriptor by name, the whole matrix will be copied.
bool timeExists(const std::string &name) const
Look if a time with a given name exist.
Eigen::Block< Int64Matrix > TimeView
A view on a time.
void setColFrom(Index thisCol, const DataPoints &that, Index thatCol)
Set column thisCol equal to column thatCol of that, copy features and descriptors if any...
void assertDescriptorConsistency() const
Assert if descriptors are not consistent with features.
ConstView getFeatureRowViewByName(const std::string &name, const unsigned row) const
Get a const view on a feature row by name and number, throw an exception if it does not exist...
Matrix::Index Index
An index to a row or a column.
ConstView getDescriptorViewByName(const std::string &name) const
Get a const view on a descriptor by name, throw an exception if it does not exist.
unsigned getNbPoints() const
Return the number of points contained in the point cloud.
unsigned getFeatureStartingRow(const std::string &name) const
Return the starting row of a feature with a given name. Return 0 if the name is not found...
unsigned getNbGroupedDescriptors() const
Return the number of grouped descriptors (e.g., normals can have 3 components but would count as only...
void swap(linb::any &lhs, linb::any &rhs) noexcept
Labels featureLabels
labels of features
TimeConstView getTimeRowViewByName(const std::string &name, const unsigned row) const
Get a const view on a time row by name and number, throw an exception if it does not exist...
void concatenateLabelledMatrix(Labels *labels, MatrixType *data, const Labels extraLabels, const MatrixType extraData)
Add another matrix after the current one. Faster merge will be achieved if all labels are the same...
unsigned getDescriptorDimension(const std::string &name) const
Return the dimension of a descriptor with a given name. Return 0 if the name is not found...
bool fieldExists(const std::string &name, const unsigned dim, const Labels &labels) const
Look if a descriptor or a feature with a given name and dimension exist.
void allocateFields(const Labels &newLabels, Labels &labels, MatrixType &data) const
Make sure a vector of fields of given names exist.
Labels timeLabels
labels of times.
The name for a certain number of dim.
unsigned getDescriptorStartingRow(const std::string &name) const
Return the starting row of a descriptor with a given name. Return 0 if the name is not found...
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > Matrix
A dense matrix over ScalarType.
TimeConstView getTimeViewByName(const std::string &name) const
Get a const view on a time by name, throw an exception if it does not exist.
Matrix getDescriptorCopyByName(const std::string &name) const
Get descriptor by name, return a matrix containing a copy of the requested descriptor.
unsigned getHomogeneousDim() const
Return the dimension of the point cloud in homogeneous coordinates (one more than Euclidean dimension...
void removeDescriptor(const std::string &name)
Remove a descriptor by name, the whole matrix will be copied.
const Eigen::Block< const Matrix > ConstView
A view on a const feature or const descriptor.
DataPoints::Labels Labels
void concatenate(const DataPoints &dp)
Add another point cloud after the current one. Faster merge will be achieved if all descriptor and ti...
Functions and classes that are dependant on scalar type are defined in this templatized class...
InvalidField(const std::string &reason)
Construct the exception with an error message.
unsigned getTimeStartingRow(const std::string &name) const
Return the starting row of a time with a given name. Return 0 if the name is not found.
bool featureExists(const std::string &name) const
Look if a feature with a given name exist.
bool descriptorExists(const std::string &name) const
Look if a descriptor with a given name exist.
bool contains(const std::string &text) const
Return whether there is a label named text.
void swapCols(Index iCol, Index jCol)
Swap column i and j in the point cloud, swap also features and descriptors if any. Assumes sizes are similar.
Eigen::Matrix< std::int64_t, Eigen::Dynamic, Eigen::Dynamic > Int64Matrix
A dense signed 64-bits matrix.
Eigen::Block< MatrixType > getViewByName(const std::string &name, const Labels &labels, MatrixType &data, const int viewRow=-1) const
ConstView getDescriptorRowViewByName(const std::string &name, const unsigned row) const
Get a const view on a descriptor row by name and number, throw an exception if it does not exist...
bool operator==(const DataPoints &that) const
Return whether two point-clouds are identical (same data and same labels)
void allocateFeatures(const Labels &newLabels)
Make sure a vector of features of given names exist.
DataPoints()
Construct an empty point cloud.
void conservativeResize(Index pointCount)
Resize the cloud to pointCount points, conserving existing ones.
void addFeature(const std::string &name, const Matrix &newFeature)
Add a feature by name, remove first if already exists. The 'pad' field will stay at the end for homog...
size_t span
number of data dimensions the label spans
const Eigen::Block< const MatrixType > getConstViewByName(const std::string &name, const Labels &labels, const MatrixType &data, const int viewRow=-1) const
void assertTimesConsistency() const
Assert if times are not consistent with features.
Eigen::Block< Matrix > View
A view on a feature or descriptor.
unsigned getFieldDimension(const std::string &name, const Labels &labels) const
Return the dimension of a feature or a descriptor with a given name. Return 0 if the name is not foun...
An exception thrown when one tries to access features or descriptors unexisting or of wrong dimension...
void allocateFeature(const std::string &name, const unsigned dim)
Makes sure a feature of a given name exists, if present, check its dimensions.
Int64Matrix times
time associated to each points, might be empty
std::vector< Label >::const_iterator const_iterator
alias
void addTime(const std::string &name, const Int64Matrix &newTime)
Add a time by name, remove first if already exists.
static void swapDataPoints(DataPoints &a, DataPoints &b)
Exchange in place point clouds a and b, with no data copy.
void allocateField(const std::string &name, const unsigned dim, Labels &labels, MatrixType &data) const
Make sure a field of a given name exists, if present, check its dimensions.
size_t totalDim() const
Return the sum of the spans of each label.
Matrix features
features of points in the cloud
DataPoints createSimilarEmpty() const
Create an empty DataPoints of similar dimensions and labels for features, descriptors and times...
unsigned getFeatureDimension(const std::string &name) const
Return the dimension of a feature with a given name. Return 0 if the name is not found.
unsigned getDescriptorDim() const
Return the total number of descriptors.
void addDescriptor(const std::string &name, const Matrix &newDescriptor)
Add a descriptor by name, remove first if already exists.
Labels()
Construct empty Labels.
void addField(const std::string &name, const MatrixType &newField, Labels &labels, MatrixType &data) const
Add a descriptor or feature by name, remove first if already exists.
void allocateDescriptors(const Labels &newLabels)
Make sure a vector of descriptors of given names exist.
unsigned getEuclideanDim() const
Return the dimension of the point cloud.
std::string text
name of the label
Label(const std::string &text="", const size_t span=0)
Construct a label from a given name and number of data dimensions it spans.
Int64Matrix getTimeCopyByName(const std::string &name) const
Get time by name, return a matrix containing a copy of the requested time.
void removeFeature(const std::string &name)
Remove a feature by name, the whole matrix will be copied.
bool operator==(const Label &that) const
Return whether two labels are equals.
Labels descriptorLabels
labels of descriptors
ConstView getFeatureViewByName(const std::string &name) const
Get a const view on a feature by name, throw an exception if it does not exist.