114 const Labels& 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)
160 return features.cols();
167 const size_t nbRows = features.rows();
168 return (nbRows == 0) ? 0 : (nbRows - 1);
175 return features.rows();
182 return descriptorLabels.size();
189 return descriptors.rows();
204 bool isEqual =
false;
205 if((features.rows() == that.
features.rows()) &&
206 (features.cols() == that.
features.cols()) &&
209 (times.rows() == that.
times.rows()) &&
210 (times.cols() == that.
times.cols()))
212 isEqual = (features == that.
features) &&
216 (times == that.
times) &&
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);
242 this->features.rightCols(nbPoints2) = dp.
features;
246 assertDescriptorConsistency();
249 concatenateLabelledMatrix(&timeLabels, ×, dp.
timeLabels, dp.
times);
250 assertTimesConsistency();
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)
301 this->allocateFields(newLabels, filledLabels, newData);
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);
331 if (descriptors.cols() > 0)
332 descriptors.conservativeResize(Eigen::NoChange, pointCount);
334 if (times.cols() > 0)
335 times.conservativeResize(Eigen::NoChange, pointCount);
342 const int nbPoints(features.cols());
344 Matrix(features.rows(), nbPoints),
348 assertDescriptorConsistency();
349 if (descriptors.cols() > 0)
355 assertTimesConsistency();
356 if (times.cols() > 0)
370 Matrix(features.rows(), pointCount),
374 assertDescriptorConsistency();
375 if (descriptors.cols() > 0)
381 assertTimesConsistency();
382 if (times.cols() > 0)
395 features.col(thisCol) = that.
features.col(thatCol);
397 if (descriptors.cols() > 0)
398 descriptors.col(thisCol) = that.
descriptors.col(thatCol);
400 if (times.cols() > 0)
401 times.col(thisCol) = that.
times.col(thatCol);
408 features.col(iCol).swap(features.col(jCol));
409 if (descriptors.cols() > 0)
410 descriptors.col(iCol).swap(descriptors.col(jCol));
411 if (times.cols() > 0)
412 times.col(iCol).swap(times.col(jCol));
424 allocateField(
name,
dim, featureLabels, features);
431 allocateFields(newLabels, featureLabels, features);
438 removeFeature(
"pad");
439 addField<Matrix>(
name, newFeature, featureLabels, features);
440 addField<Matrix>(
"pad", Matrix::Ones(1, features.cols()), featureLabels, features);
447 removeField(
name, featureLabels, features);
461 return getConstViewByName(
name, featureLabels, features);
468 return getViewByName(
name, featureLabels, features);
475 return getConstViewByName(
name, featureLabels, features,
int(row));
482 return getViewByName(
name, featureLabels, features,
int(row));
489 return fieldExists(
name, 0, featureLabels);
496 return fieldExists(
name,
dim, featureLabels);
503 return getFieldDimension(
name, featureLabels);
510 return getFieldStartingRow(
name, featureLabels);
521 allocateField(
name,
dim, descriptorLabels, descriptors);
528 allocateFields(newLabels, descriptorLabels, descriptors);
535 addField(
name, newDescriptor, descriptorLabels, descriptors);
542 removeField(
name, descriptorLabels, descriptors);
557 return getConstViewByName(
name, descriptorLabels, descriptors);
564 return getViewByName(
name, descriptorLabels, descriptors);
571 return getConstViewByName(
name, descriptorLabels, descriptors,
int(row));
578 return getViewByName(
name, descriptorLabels, descriptors,
int(row));
585 return fieldExists(
name, 0, descriptorLabels);
592 return fieldExists(
name,
dim, descriptorLabels);
599 return getFieldDimension(
name, descriptorLabels);
606 return getFieldStartingRow(
name, descriptorLabels);
613 assertConsistency(
"descriptors", descriptors.rows(), descriptors.cols(), descriptorLabels);
624 allocateField(
name,
dim, timeLabels, times);
631 allocateFields(newLabels, timeLabels, times);
639 addField(
name, newTime, timeLabels, times);
646 removeField(
name, timeLabels, times);
661 return getConstViewByName(
name, timeLabels, times);
668 return getViewByName(
name, timeLabels, times);
675 return getConstViewByName(
name, timeLabels, times,
int(row));
682 return getViewByName(
name, timeLabels, times,
int(row));
690 return fieldExists(
name, 0, timeLabels);
697 return fieldExists(
name,
dim, timeLabels);
704 return getFieldDimension(
name, timeLabels);
711 return getFieldStartingRow(
name, timeLabels);
718 assertConsistency(
"times", times.rows(), times.cols(), timeLabels);
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()
738 if (dataCols != features.cols())
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>
763 if (fieldExists(
name, 0, labels))
765 const unsigned descDim(getFieldDimension(
name, labels));
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);
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)
838 if (fieldExists(
name, 0, labels))
840 const int fieldDim = getFieldDimension(
name, labels);
842 if(fieldDim == newFieldDim)
845 if(pointCount == newPointCount)
847 const int row = getFieldStartingRow(
name, labels);
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>
888 const unsigned deleteId = getFieldStartingRow(
name, labels);
889 const unsigned span = getFieldDimension(
name, labels);
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>