59 return (this->text == that.
text) && (this->span == that.
span);
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)
203 bool isEqual =
false;
227 const int nbPoints1 = this->
features.cols();
228 const int nbPoints2 = dp.
features.cols();
229 const int nbPointsTotal = nbPoints1 + nbPoints2;
231 const int dimFeat = this->
features.rows();
234 stringstream errorMsg;
235 errorMsg <<
"Cannot concatenate DataPoints because the dimension of the features are not the same. Actual dimension: " << dimFeat <<
" New dimension: " << dp.
features.rows();
240 this->
features.conservativeResize(Eigen::NoChange, nbPointsTotal);
256 template<
typename MatrixType>
259 const int nbPoints1 = data->cols();
260 const int nbPoints2 = extraData.cols();
261 const int nbPointsTotal = nbPoints1 + nbPoints2;
264 if (*labels == extraLabels)
266 if (labels->size() > 0)
269 data->conservativeResize(Eigen::NoChange, nbPointsTotal);
270 data->rightCols(nbPoints2) = extraData;
279 for(BOOST_AUTO(it, labels->begin()); it != labels->end(); ++it)
281 for(BOOST_AUTO(jt, extraLabels.begin()); jt != extraLabels.end(); ++jt)
283 if (it->text == jt->text)
285 if (it->span != jt->span)
287 (boost::format(
"The field %1% has dimension %2% in this, different than dimension %3% in that") % it->text % it->span % jt->span).str()
289 newLabels.push_back(*it);
296 if (newLabels.size() > 0)
301 assert(newLabels == filledLabels);
305 for(BOOST_AUTO(it, newLabels.begin()); it != newLabels.end(); ++it)
307 Eigen::Block<MatrixType> view(newData.block(row, 0, it->span, newData.cols()));
308 view.leftCols(nbPoints1) =
getViewByName(it->text, *labels, *data);
309 view.rightCols(nbPoints2) =
getViewByName(it->text, extraLabels, extraData);
319 *data = MatrixType();
329 features.conservativeResize(Eigen::NoChange, pointCount);
331 descriptors.conservativeResize(Eigen::NoChange, pointCount);
333 if (
times.cols() > 0)
334 times.conservativeResize(Eigen::NoChange, pointCount);
341 const int nbPoints(
features.cols());
355 if (
times.cols() > 0)
381 if (
times.cols() > 0)
399 if (
times.cols() > 0)
410 if (
times.cols() > 0)
439 addField<Matrix>(
"pad", Matrix::Ones(1,
features.cols()), featureLabels,
features);
728 (boost::format(
"Point cloud has degenerate %2% dimensions of rows=0, cols=%1%") % dataCols % dataName).str()
730 if (labels.size() > 0)
732 (boost::format(
"Point cloud has no %2% data but %1% descriptor labels") % labels.size() % dataName).str()
740 (boost::format(
"Point cloud has %1% points in features but %2% points in %3%") %
features.cols() % dataCols % dataName).str()
745 for (BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
748 if (dataRows != descDim)
750 (boost::format(
"Labels from %3% return %1% total dimensions but there are %2% in the %3% matrix") % descDim % dataRows % dataName).str()
759 template<
typename MatrixType>
768 (boost::format(
"The existing field %1% has dimension %2%, different than requested dimension %3%") % name % descDim % dim).str()
774 const int oldDim(data.rows());
775 const int totalDim(oldDim + dim);
776 const int pointCount(
features.cols());
777 data.conservativeResize(totalDim, pointCount);
778 labels.push_back(
Label(name, dim));
784 template<
typename MatrixType>
787 typedef vector<bool> BoolVector;
788 BoolVector present(newLabels.size(),
false);
791 size_t additionalDim(0);
792 for (
size_t i = 0; i < newLabels.size(); ++i)
794 const string& newName(newLabels[i].text);
795 const size_t newSpan(newLabels[i].span);
796 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
798 if (it->text == newName)
800 if (it->span != newSpan)
802 (boost::format(
"The existing field %1% has dimension %2%, different than requested dimension %3%") % newName % it->span % newSpan).str()
809 additionalDim += newSpan;
813 const int oldDim(data.rows());
814 const int totalDim(oldDim + additionalDim);
815 const int pointCount(
features.cols());
816 data.conservativeResize(totalDim, pointCount);
817 for (
size_t i = 0; i < newLabels.size(); ++i)
820 labels.push_back(newLabels[i]);
826 template<
typename MatrixType>
829 const int newFieldDim = newField.rows();
830 const int newPointCount = newField.cols();
831 const int pointCount =
features.cols();
833 if (newField.rows() == 0)
841 if(fieldDim == newFieldDim)
844 if(pointCount == newPointCount)
847 data.block(row, 0, fieldDim, pointCount) = newField;
851 stringstream errorMsg;
852 errorMsg <<
"The field " << name <<
" cannot be added because the number of points is not the same. Old point count: " << pointCount <<
"new: " << newPointCount;
858 stringstream errorMsg;
859 errorMsg <<
"The field " << name <<
" already exists but could not be added because the dimension is not the same. Old dim: " << fieldDim <<
" new: " << newFieldDim;
865 if(pointCount == newPointCount || pointCount == 0)
867 const int oldFieldDim(data.rows());
868 const int totalDim = oldFieldDim + newFieldDim;
869 data.conservativeResize(totalDim, newPointCount);
870 data.bottomRows(newFieldDim) = newField;
871 labels.push_back(
Label(name, newFieldDim));
875 stringstream errorMsg;
876 errorMsg <<
"The field " << name <<
" cannot be added because the number of points is not the same. Old point count: " << pointCount <<
" new: " << newPointCount;
883 template<
typename MatrixType>
889 const unsigned keepAfterId = deleteId + span;
890 const unsigned lastId = data.rows() - 1;
891 const unsigned sizeKeep = data.rows() - keepAfterId;
892 const unsigned nbPoints = data.cols();
896 if(keepAfterId <= lastId)
898 data.block(deleteId, 0, sizeKeep, nbPoints) = data.block(keepAfterId, 0, sizeKeep, nbPoints);
902 data.conservativeResize(data.rows()-span, nbPoints);
905 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
907 if (it->text == name)
920 template<
typename MatrixType>
924 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
926 if (it->text == name)
930 if (viewRow >=
int(it->span))
932 (boost::format(
"Requesting row %1% of field %2% that only has %3% rows") % viewRow % name % it->span).str()
934 return data.block(row + viewRow, 0, 1, data.cols());
937 return data.block(row, 0, it->span, data.cols());
947 template<
typename MatrixType>
951 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
953 if (it->text == name)
957 if (viewRow >=
int(it->span))
959 (boost::format(
"Requesting row %1% of field %2% that only has %3% rows") % viewRow % name % it->span).str()
961 return data.block(row + viewRow, 0, 1, data.cols());
964 return data.block(row, 0, it->span, data.cols());
975 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
977 if (it->text == name)
979 if (dim == 0 || it->span == dim)
993 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
995 if (it->text == name)
1003 template<
typename T>
1007 for(BOOST_AUTO(it, labels.begin()); it != labels.end(); ++it)
1009 if (it->text == name)
1021 template<
typename T>
1024 a.features.swap(b.features);
1025 swap(a.featureLabels, b.featureLabels);
1026 a.descriptors.swap(b.descriptors);
1027 swap(a.descriptorLabels, b.descriptorLabels);
1028 a.times.swap(b.times);
1029 swap(a.timeLabels, b.timeLabels);
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.
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.