59 return (this->text == that.
text) && (this->span == that.
span);
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 return (features.rows() - 1);
174 return features.rows();
181 return descriptorLabels.size();
188 return descriptors.rows();
203 bool isEqual =
false;
204 if((features.rows() == that.
features.rows()) &&
205 (features.cols() == that.
features.cols()) &&
208 (times.rows() == that.
times.rows()) &&
209 (times.cols() == that.
times.cols()))
211 isEqual = (features == that.
features) &&
215 (times == that.
times) &&
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);
241 this->features.rightCols(nbPoints2) = dp.
features;
245 assertDescriptorConsistency();
248 concatenateLabelledMatrix(&timeLabels, ×, dp.
timeLabels, dp.
times);
249 assertTimesConsistency();
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)
300 this->allocateFields(newLabels, filledLabels, newData);
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);
330 if (descriptors.cols() > 0)
331 descriptors.conservativeResize(Eigen::NoChange, pointCount);
333 if (times.cols() > 0)
334 times.conservativeResize(Eigen::NoChange, pointCount);
341 const int nbPoints(features.cols());
343 Matrix(features.rows(), nbPoints),
347 assertDescriptorConsistency();
348 if (descriptors.cols() > 0)
354 assertTimesConsistency();
355 if (times.cols() > 0)
369 Matrix(features.rows(), pointCount),
373 assertDescriptorConsistency();
374 if (descriptors.cols() > 0)
380 assertTimesConsistency();
381 if (times.cols() > 0)
394 features.col(thisCol) = that.
features.col(thatCol);
396 if (descriptors.cols() > 0)
397 descriptors.col(thisCol) = that.
descriptors.col(thatCol);
399 if (times.cols() > 0)
400 times.col(thisCol) = that.
times.col(thatCol);
407 features.col(iCol).swap(features.col(jCol));
408 if (descriptors.cols() > 0)
409 descriptors.col(iCol).swap(descriptors.col(jCol));
410 if (times.cols() > 0)
411 times.col(iCol).swap(times.col(jCol));
423 allocateField(name, dim, featureLabels, features);
430 allocateFields(newLabels, featureLabels, features);
437 removeFeature(
"pad");
438 addField<Matrix>(name, newFeature, featureLabels, features);
439 addField<Matrix>(
"pad", Matrix::Ones(1, features.cols()), featureLabels, features);
446 removeField(name, featureLabels, features);
453 return Matrix(getFeatureViewByName(name));
460 return getConstViewByName(name, featureLabels, features);
467 return getViewByName(name, featureLabels, features);
474 return getConstViewByName(name, featureLabels, features,
int(row));
481 return getViewByName(name, featureLabels, features,
int(row));
488 return fieldExists(name, 0, featureLabels);
495 return fieldExists(name, dim, featureLabels);
502 return getFieldDimension(name, featureLabels);
509 return getFieldStartingRow(name, featureLabels);
520 allocateField(name, dim, descriptorLabels, descriptors);
527 allocateFields(newLabels, descriptorLabels, descriptors);
534 addField(name, newDescriptor, descriptorLabels, descriptors);
541 removeField(name, descriptorLabels, descriptors);
549 return Matrix(getDescriptorViewByName(name));
556 return getConstViewByName(name, descriptorLabels, descriptors);
563 return getViewByName(name, descriptorLabels, descriptors);
570 return getConstViewByName(name, descriptorLabels, descriptors,
int(row));
577 return getViewByName(name, descriptorLabels, descriptors,
int(row));
584 return fieldExists(name, 0, descriptorLabels);
591 return fieldExists(name, dim, descriptorLabels);
598 return getFieldDimension(name, descriptorLabels);
605 return getFieldStartingRow(name, descriptorLabels);
612 assertConsistency(
"descriptors", descriptors.rows(), descriptors.cols(), descriptorLabels);
623 allocateField(name, dim, timeLabels, times);
630 allocateFields(newLabels, timeLabels, times);
638 addField(name, newTime, timeLabels, times);
645 removeField(name, timeLabels, times);
660 return getConstViewByName(name, timeLabels, times);
667 return getViewByName(name, timeLabels, times);
674 return getConstViewByName(name, timeLabels, times,
int(row));
681 return getViewByName(name, timeLabels, times,
int(row));
689 return fieldExists(name, 0, timeLabels);
696 return fieldExists(name, dim, timeLabels);
703 return getFieldDimension(name, timeLabels);
710 return getFieldStartingRow(name, timeLabels);
717 assertConsistency(
"times", times.rows(), times.cols(), timeLabels);
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()
737 if (dataCols != features.cols())
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>
762 if (fieldExists(name, 0, labels))
764 const unsigned descDim(getFieldDimension(name, labels));
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)
837 if (fieldExists(name, 0, labels))
839 const int fieldDim = getFieldDimension(name, labels);
841 if(fieldDim == newFieldDim)
844 if(pointCount == newPointCount)
846 const int row = getFieldStartingRow(name, labels);
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>
887 const unsigned deleteId = getFieldStartingRow(name, labels);
888 const unsigned span = getFieldDimension(name, labels);
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);