20 #include <QCoreApplication>
28 : m_app(app), m_cloud(nullptr) {
31 this->
setMetaData(
"class_name",
"GrainsAsEllipsoids");
68 const std::vector<std::vector<int>>& stacks,
70 : m_cloud(cloud), m_app(app), m_stacks(stacks) {
71 this->
setMetaData(
"class_name",
"GrainsAsEllipsoids");
81 std::cout <<
"[GrainsAsEllipsoids::GrainsAsEllipsoids] fit "
82 << stacks.size() <<
" ellipsoids" <<
std::endl;
90 for (
int idx = 0; idx <
m_stacks.size(); idx++) {
95 "[GrainsAsEllipsoids::GrainsAsEllipsoids] fit not possible "
97 QString::number(idx) +
" of size " +
100 float maxRadius =
m_radii[idx].maxCoeff();
104 center.
y + maxRadius,
105 center.
z + maxRadius));
107 center.
y - maxRadius,
108 center.
z - maxRadius));
115 int nPoints =
static_cast<int>(
m_stacks[el].size());
116 Eigen::MatrixX3d
points(nPoints, 3);
117 for (
int index = 0; index < nPoints; index++) {
124 Eigen::RowVector3d centroid =
points.colwise().mean();
125 m_center[el] << centroid.x(), centroid.y(), centroid.z();
140 for (
int k = 0; k < colorTable.size(); k++) {
151 QString cloudName =
"g3point_results";
154 for (
int idx = 0; idx <
m_center.size(); idx++) {
161 Eigen::Vector3f
point = center;
168 for (
unsigned int index = 0; index < cloud->
size(); index++) {
183 "[GrainsAsEllipsoids::exportResultsAsCloud] impossible to "
184 "allocate g3point_index scalar field");
188 int indexInResults = 0;
189 for (
int index = 0; index <
m_center.size(); index++) {
195 sf->
setValue(indexInResults, index);
204 if (sfIdxRadiusX == -1 || sfIdxRadiusY == -1 || sfIdxRadiusZ == -1) {
206 "[GrainsAsEllipsoids::exportResultsAsCloud] impossible to "
207 "allocate scalar fields to export the radii");
213 for (
unsigned int index = 0; index < cloud->
size(); index++) {
237 if (sfIdxR00 == -1 || sfIdxR01 == -1 || sfIdxR02 == -1 || sfIdxR10 == -1 ||
238 sfIdxR11 == -1 || sfIdxR12 == -1 || sfIdxR20 == -1 || sfIdxR21 == -1 ||
241 "[GrainsAsEllipsoids::exportResultsAsCloud] impossible to "
242 "allocate scalar fields to export the rotation");
254 for (
unsigned int index = 0; index < cloud->
size(); index++) {
293 std::vector<float>().swap(
vertices);
294 std::vector<float>().swap(
normals);
303 float sectorAngle, stackAngle;
306 stackAngle =
M_PI / 2 - i * stackStep;
307 xy = cosf(stackAngle);
308 z = sinf(stackAngle);
314 sectorAngle = j * sectorStep;
317 x = xy * cosf(sectorAngle);
318 y = xy * sinf(sectorAngle);
356 for (
int j = 0; j <
sectorCount; ++j, ++k1, ++k2) {
392 float maxRadius =
m_radii[index].maxCoeff();
396 center.
y + maxRadius,
397 center.
z + maxRadius));
399 center.
y - maxRadius,
400 center.
z - maxRadius));
405 "[GrainsAsEllipsoids::updateBBox] asking for the bounding of "
407 QString::number(index) +
" out of range");
412 const Eigen::Array3f& center,
413 const Eigen::Array3f&
radii,
414 const Eigen::Matrix3f& rotationMatrix,
415 Eigen::ArrayXd& parameters) {
425 float xrr = 1 /
radii(0);
426 float yrr = 1 /
radii(1);
427 float zrr = 1 /
radii(2);
429 float r11 = rotationMatrix.data()[0];
430 float r21 = rotationMatrix.data()[1];
431 float r31 = rotationMatrix.data()[2];
432 float r12 = rotationMatrix.data()[3];
433 float r22 = rotationMatrix.data()[4];
434 float r32 = rotationMatrix.data()[5];
435 float r13 = rotationMatrix.data()[6];
436 float r23 = rotationMatrix.data()[7];
437 float r33 = rotationMatrix.data()[8];
439 float xc = center(0);
440 float yc = center(1);
441 float zc = center(2);
445 parameters << pow(r11, 2) * pow(xrr, 2) + pow(r21, 2) * pow(yrr, 2) +
446 pow(r31, 2) * pow(zrr, 2),
447 pow(r12, 2) * pow(xrr, 2) + pow(r22, 2) * pow(yrr, 2) +
448 pow(r32, 2) * pow(zrr, 2),
449 pow(r13, 2) * pow(xrr, 2) + pow(r23, 2) * pow(yrr, 2) +
450 pow(r33, 2) * pow(zrr, 2),
451 2 * r11 * r12 * pow(xrr, 2) + 2 * r21 * r22 * pow(yrr, 2) +
452 2 * r31 * r32 * pow(zrr, 2),
453 2 * r11 * r13 * pow(xrr, 2) + 2 * r21 * r23 * pow(yrr, 2) +
454 2 * r31 * r33 * pow(zrr, 2),
455 2 * r12 * r13 * pow(xrr, 2) + 2 * r22 * r23 * pow(yrr, 2) +
456 2 * r32 * r33 * pow(zrr, 2),
457 (-2) * (pow(r11, 2) * xc * pow(xrr, 2) +
458 pow(r21, 2) * xc * pow(yrr, 2) +
459 pow(r31, 2) * xc * pow(zrr, 2) +
460 r11 * r12 * pow(xrr, 2) * yc +
461 r11 * r13 * pow(xrr, 2) * zc +
462 r21 * r22 * yc * pow(yrr, 2) +
463 r21 * r23 * pow(yrr, 2) * zc +
464 r31 * r32 * yc * pow(zrr, 2) +
465 r31 * r33 * zc * pow(zrr, 2)),
466 (-2) * (pow(r12, 2) * pow(xrr, 2) * yc +
467 pow(r22, 2) * yc * pow(yrr, 2) +
468 pow(r32, 2) * yc * pow(zrr, 2) +
469 r11 * r12 * xc * pow(xrr, 2) +
470 r21 * r22 * xc * pow(yrr, 2) +
471 r12 * r13 * pow(xrr, 2) * zc +
472 r31 * r32 * xc * pow(zrr, 2) +
473 r22 * r23 * pow(yrr, 2) * zc +
474 r32 * r33 * zc * pow(zrr, 2)),
475 (-2) * (pow(r13, 2) * pow(xrr, 2) * zc +
476 pow(r23, 2) * pow(yrr, 2) * zc +
477 pow(r33, 2) * zc * pow(zrr, 2) +
478 r11 * r13 * xc * pow(xrr, 2) +
479 r12 * r13 * pow(xrr, 2) * yc +
480 r21 * r23 * xc * pow(yrr, 2) +
481 r22 * r23 * yc * pow(yrr, 2) +
482 r31 * r33 * xc * pow(zrr, 2) +
483 r32 * r33 * yc * pow(zrr, 2)),
484 pow(r11, 2) * pow(xc, 2) * pow(xrr, 2) +
485 2 * r11 * r12 * xc * pow(xrr, 2) * yc +
486 2 * r11 * r13 * xc * pow(xrr, 2) * zc +
487 pow(r12, 2) * pow(xrr, 2) * pow(yc, 2) +
488 2 * r12 * r13 * pow(xrr, 2) * yc * zc +
489 pow(r13, 2) * pow(xrr, 2) * pow(zc, 2) +
490 pow(r21, 2) * pow(xc, 2) * pow(yrr, 2) +
491 2 * r21 * r22 * xc * yc * pow(yrr, 2) +
492 2 * r21 * r23 * xc * pow(yrr, 2) * zc +
493 pow(r22, 2) * pow(yc, 2) * pow(yrr, 2) +
494 2 * r22 * r23 * yc * pow(yrr, 2) * zc +
495 pow(r23, 2) * pow(yrr, 2) * pow(zc, 2) +
496 pow(r31, 2) * pow(xc, 2) * pow(zrr, 2) +
497 2 * r31 * r32 * xc * yc * pow(zrr, 2) +
498 2 * r31 * r33 * xc * zc * pow(zrr, 2) +
499 pow(r32, 2) * pow(yc, 2) * pow(zrr, 2) +
500 2 * r32 * r33 * yc * zc * pow(zrr, 2) +
501 pow(r33, 2) * pow(zc, 2) * pow(zrr, 2) - 1;
507 Eigen::Array3f& center,
508 Eigen::Array3f&
radii,
509 Eigen::Matrix3f& rotationMatrix) {
534 Eigen::ArrayXd p = parameters;
543 Eigen::MatrixXd q(4, 4);
545 q << p(0), p(3), p(4), p(6), p(3), p(1), p(5), p(7), p(4), p(5), p(2), p(8),
546 p(6), p(7), p(8), p(9);
548 center = q.block(0, 0, 3, 3)
549 .colPivHouseholderQr()
550 .solve(-p(Eigen::seq(6, 8)).matrix())
553 Eigen::MatrixXd t(4, 4);
554 t = Eigen::MatrixXd::Identity(4, 4);
559 Eigen::MatrixXd s(4, 4);
560 s = t * q * t.transpose();
563 Eigen::LLT<Eigen::MatrixXd> lltOfA(
564 (-s(3, 3) * s.block(0, 0, 3, 3).array()));
565 if (lltOfA.info() != Eigen::Success) {
569 Eigen::EigenSolver<Eigen::MatrixXd> eigensolver(s.block(0, 0, 3, 3));
570 if (eigensolver.info() != Eigen::Success) {
574 radii = (-s(3, 3) / eigensolver.eigenvalues().array().real())
578 eigensolver.eigenvectors().transpose().real().cast<
float>();
584 Eigen::ArrayXd& parameters) {
606 Eigen::MatrixXd d(xyz.rows(), 10);
608 d << xyz(Eigen::all, 0).pow(2).matrix(), xyz(Eigen::all, 1).pow(2).matrix(),
609 xyz(Eigen::all, 2).pow(2).matrix(),
610 (2 * xyz(Eigen::all, 1) * xyz(Eigen::all, 2)).matrix(),
611 (2 * xyz(Eigen::all, 0) * xyz(Eigen::all, 2)).matrix(),
612 (2 * xyz(Eigen::all, 0) * xyz(Eigen::all, 1)).matrix(),
613 (2 * xyz(Eigen::all, 0)).matrix(),
614 (2 * xyz(Eigen::all, 1)).matrix(),
615 (2 * xyz(Eigen::all, 2)).matrix(),
616 Eigen::MatrixXd::Ones(xyz.rows(), 1);
618 Eigen::MatrixXd s = d.transpose() * d;
624 c = Eigen::MatrixXd::Zero(10, 10);
625 c1 << 0, k, k, k, 0, k, k, k, 0;
626 c1 = c1.array() / 2 - 1;
627 c2 = -k * Eigen::Matrix3d::Identity();
628 c.block(0, 0, 3, 3) = c1;
629 c.block(3, 3, 3, 3) = c2;
631 Eigen::GeneralizedEigenSolver<Eigen::MatrixXd> eigensolver(s, c);
632 if (eigensolver.info() != Eigen::Success) {
636 Eigen::ArrayXd eigenValues(10);
637 Eigen::VectorXd eigenValuesAsAMatrix(10);
638 eigenValues = eigensolver.eigenvalues().real();
639 eigenValuesAsAMatrix = eigensolver.eigenvalues().real().matrix();
640 Xb condition = (eigenValues > 0) && (!eigenValues.isInf());
642 int flt = condition.count();
644 Eigen::ArrayXd finiteValues(flt);
645 finiteValues = Eigen::ArrayXd::Zero(flt);
646 int finiteValuesCounter = 0;
647 for (
int k = 0; k < eigenValues.size(); k++) {
649 finiteValues(finiteValuesCounter++) = eigenValues(k);
659 for (k = 0; k < 10; k++) {
660 if (eigenValues(k) == eigenValue) {
661 v = eigensolver.eigenvectors()(Eigen::all, k).real();
669 eigenValue = eigenValues.abs().minCoeff();
670 for (k = 0; k < 10; k++) {
671 if (
abs(eigenValues(k)) == eigenValue) {
672 v = eigensolver.eigenvectors()(Eigen::all, k).real();
679 eigenValue = finiteValues.abs().minCoeff();
680 for (k = 0; k < 10; k++) {
681 if (eigenValues(k) == eigenValue) {
682 v = eigensolver.eigenvectors()(Eigen::all, k).real();
689 parameters.resize(10);
691 parameters << v(0), v(1), v(2), 2 * v(5), 2 * v(4), 2 * v(3), 2 * v(6),
692 2 * v(7), 2 * v(8), v(9);
698 Eigen::Array3f& center,
699 Eigen::Array3f&
radii,
700 Eigen::Matrix3f& rotationMatrix,
710 for (
int index :
m_stacks[grainIndex]) {
715 Eigen::Map<const Eigen::MatrixX3f, Eigen::Unaligned, Eigen::Stride<1, 3>>
716 grainPoints(
static_cast<const float*
>(grainCloud->
getPoint(0)->
u),
717 grainCloud->
size(), 3);
723 Eigen::Vector3d scales(bb.
x, bb.
y, bb.
z);
724 double scale = 1 / scales.maxCoeff();
725 Eigen::RowVector3d means = grainPoints.cast<
double>().colwise().mean();
727 Eigen::ArrayXd p(10);
737 scale * (grainPoints.cast<
double>().rowwise() - means),
757 center = center / scale + Eigen::Array3f(means.cast<
float>());
762 std::sort(sortedRadii.begin(), sortedRadii.end());
763 Eigen::Array3f updatedRadii = {
764 sortedRadii[0], sortedRadii[1],
766 Eigen::Matrix3f updatedRotationMatrix;
767 for (
int k = 0; k < 3; k++) {
768 float radius = updatedRadii(k);
770 for (
int idx = 0; idx < 3; idx++) {
771 if (
radii[idx] == radius) {
776 updatedRotationMatrix(k, 0) = rotationMatrix(col, 0);
777 updatedRotationMatrix(k, 1) = rotationMatrix(col, 1);
778 updatedRotationMatrix(k, 2) = rotationMatrix(col, 2);
781 radii = updatedRadii;
782 rotationMatrix = updatedRotationMatrix;
796 "[GrainsAsEllipsoids::updateMeshAndLineSet] Empty data arrays, "
797 "cannot update mesh");
808 "[GrainsAsEllipsoids::updateMeshAndLineSet] Failed to "
809 "initialize sphere template");
815 bool hasContext =
false;
835 for (
int idx = 0; idx < static_cast<int>(
m_center.size()); idx++) {
845 for (
int i = 0; i < 3; i++) {
846 for (
int j = 0; j < 3; j++) {
856 "[GrainsAsEllipsoids::updateMeshAndLineSet] Rotation "
858 "contains NaN at index: " +
859 QString::number(idx));
867 "[GrainsAsEllipsoids::updateMeshAndLineSet] Invalid "
870 QString::number(idx));
876 Eigen::Array3f center =
m_center[idx];
879 std::vector<Eigen::Vector3d> ellipsoidVertices;
880 ellipsoidVertices.reserve(
vertices.size() / 3);
882 for (
size_t i = 0; i <
vertices.size(); i += 3) {
885 Eigen::Vector3f scaledVertex(sphereVertex.x() *
radii(0),
886 sphereVertex.y() *
radii(1),
887 sphereVertex.z() *
radii(2));
888 Eigen::Vector3f rotatedVertex = rotation * scaledVertex;
889 Eigen::Vector3d finalVertex(rotatedVertex.x() + center(0),
890 rotatedVertex.y() + center(1),
891 rotatedVertex.z() + center(2));
892 ellipsoidVertices.push_back(finalVertex);
899 static_cast<unsigned>(ellipsoidVertices.size()))) {
903 mesh->
setName(QString(
"Ellipsoid_%1_Mesh").arg(idx));
905 for (
size_t i = 0; i <
indices.size(); i += 3) {
907 static_cast<unsigned>(
indices[i]),
908 static_cast<unsigned>(
indices[i + 1]),
909 static_cast<unsigned>(
indices[i + 2]));
914 colorVec.
x, colorVec.
y, colorVec.
z,
918 QString(
"Ellipsoid_%1_Material").arg(idx)));
919 material->setDiffuse(materialColor);
920 material->setIllum(0);
923 QString(
"Ellipsoid_%1_MaterialSet").arg(idx));
941 if (!
lineIndices.empty() && !ellipsoidVertices.empty()) {
943 std::vector<Eigen::Vector2i> lines;
945 for (
size_t i = 0; i <
lineIndices.size(); i += 2) {
954 ellipsoidVertices, lines,
955 QString(
"Ellipsoid_%1_Lines")
961 Eigen::Vector3d lineColor(
color.x * 0.8,
color.y * 0.8,
971 const std::vector<int>& stack =
m_stacks[idx];
972 if (!stack.empty()) {
974 for (
int index : stack) {
980 pc->
setName(QString(
"Ellipsoid_%1_Points").arg(idx));
985 static_cast<unsigned char>(
987 static_cast<unsigned char>(
989 static_cast<unsigned char>(
991 for (
unsigned int i = 0; i < pc->
size(); i++) {
1008 for (
int idx = 0; idx < static_cast<int>(
m_center.size()); idx++) {
1014 m_meshes[idx]->setVisible(showMesh);
1015 m_meshes[idx]->setEnabled(showMesh);
1021 if (matSet && !matSet->empty()) {
1031 qSharedPointerConstCast<ccMaterial>(cMat);
1040 mat->setDiffuse(newColor);
1068 if (hasContext &&
m_app) {
1129 assert(out.isOpen() && (out.openMode() & QIODevice::WriteOnly));
1140 ::uint8_t componentCount =
static_cast<::uint8_t
>(N);
1141 if (out.write((
const char*)&componentCount, 1) < 0)
1145 ::uint32_t elementCount =
static_cast<::uint32_t
>(data.size());
1146 if (out.write((
const char*)&elementCount, 4) < 0)
1153 const char* _data = (
const char*)data.data();
1154 qint64 byteCount =
static_cast<qint64
>(elementCount);
1155 byteCount *=
sizeof(Eigen::Array3f);
1156 while (byteCount != 0) {
1157 static const qint64 s_maxByteSaveCount =
1159 qint64 saveCount =
std::min(byteCount, s_maxByteSaveCount);
1160 if (out.write(_data, saveCount) < 0)
1163 byteCount -= saveCount;
1171 ::uint8_t& componentCount,
1172 ::uint32_t& elementCount) {
1173 assert(in.isOpen() && (in.openMode() & QIODevice::ReadOnly));
1178 if (in.read((
char*)&componentCount, 1) < 0)
1182 if (in.read((
char*)&elementCount, 4) < 0)
1188 template <
typename T>
1190 std::ofstream file(
name.toLatin1());
1191 int elementSize = vector[0].size();
1192 for (
int i = 0; i < vector.size(); i++) {
1193 for (
int j = 0; j < elementSize; j++) {
1194 file << vector[i][j] <<
", ";
1202 std::vector<Eigen::Matrix3f> rotationMatrix) {
1203 std::ofstream file(
name.toLatin1());
1204 int elementSize = rotationMatrix[0].size();
1205 for (
int i = 0; i < rotationMatrix.size(); i++) {
1206 for (
int j = 0; j < elementSize; j++) {
1207 file << rotationMatrix[i](j) <<
", ";
1215 CVLog::Print(
"[G3Point] write GrainsAsEllipsoids object in .bin");
1236 if (!ccSerializationHelper::GenericArrayToFile<CCVector3f, 1, CCVector3f>(
1251 CVLog::Print(
"[G3Point] read GrainsAsEllipsoids object from .bin");
1258 m_center, in, dataVersion,
"G3Point m_center")) {
1265 m_radii, in, dataVersion,
"G3Point m_radii")) {
1273 "G3Point m_rotationMatrix")) {
1278 if (!ccSerializationHelper::GenericArrayFromFile<CCVector3f, 1, CCVector3f>(
1290 for (
int idx = 0; idx <
m_center.size(); idx++) {
1291 float maxRadius =
m_radii[idx].maxCoeff();
1300 center.
z + maxRadius));
1302 center.
z - maxRadius));
Vector3Tpl< float > CCVector3f
Float 3D Vector.
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
bool genericArrayToFile(const std::vector< Eigen::Array3f > &data, QFile &out)
bool readArrayHeader(QFile &in, short dataVersion, ::uint8_t &componentCount, ::uint32_t &elementCount)
bool rotationMatrixToFile(QString name, std::vector< Eigen::Matrix3f > rotationMatrix)
bool stdVectorToFile(QString name, std::vector< T > vector)
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
static bool Print(const char *format,...)
Prints out a formatted message in console.
static bool Error(const char *format,...)
Display an error dialog with formatted message.
bool fitEllipsoidToGrain(const int grainIndex, Eigen::Array3f ¢er, Eigen::Array3f &radii, Eigen::Matrix3f &rotationMatrix, const Method &method=DIRECT)
void updateBBoxOnlyOne(int index)
std::vector< Eigen::Array3f > m_center
std::vector< ccMesh * > m_meshes
std::vector< Eigen::Array3f > m_radii
bool implicitToExplicit(const Eigen::ArrayXd ¶meters, Eigen::Array3f ¢er, Eigen::Array3f &radii, Eigen::Matrix3f &rotationMatrix)
void showOnlyOne(bool state)
void updateMeshAndLineSet()
Update mesh and lineset representations for ellipsoids.
std::vector< ccPointCloud * > m_pointsClouds
std::vector< float > normals
std::vector< int > indices
void draw(CC_DRAW_CONTEXT &context) override
Draws entity and its children.
ecvMainAppInterface * m_app
std::vector< float > vertices
void clearGeneratedObjects()
bool toFile_MeOnly(QFile &out, short dataVersion) const override
Save own object data.
bool explicitToImplicit(const Eigen::Array3f ¢er, const Eigen::Array3f &radii, const Eigen::Matrix3f &rotationMatrix, Eigen::ArrayXd ¶meters)
std::vector< CCVector3f > m_grainColors
std::vector< float > texCoords
Eigen::Array< bool, Eigen::Dynamic, Eigen::Dynamic > Xb
void initSphereVertices()
bool directFit(const Eigen::ArrayX3d &xyz, Eigen::ArrayXd ¶meters)
std::set< int > m_fitNotOK
bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads own object data.
short minimumFileVersion_MeOnly() const override
GrainsAsEllipsoids(ecvMainAppInterface *app)
qCC_db
std::vector< cloudViewer::geometry::LineSet * > m_lineSets
bool exportResultsAsCloud()
std::vector< Eigen::Matrix3f > m_rotationMatrix
std::vector< std::vector< int > > m_stacks
ccBBox getOwnBB(bool withGLFeatures=false) override
Returns the entity's own bounding-box.
void setGrainColorsTable(const RGBAColorsTableType &colorTable)
std::vector< int > lineIndices
Array of RGBA colors for each point.
virtual bool isVisible() const
Returns whether entity is visible or not.
virtual void lockVisibility(bool state)
Locks/unlocks visibility.
virtual void setVisible(bool state)
Sets entity visibility.
virtual void showColors(bool state)
Sets colors visibility.
virtual void showMaterials(bool state)
Sets whether textures should be displayed or not.
void setPointSize(unsigned size=0)
Sets point size.
virtual bool toFile_MeOnly(QFile &out, short dataVersion) const
Save own object data.
void draw(CC_DRAW_CONTEXT &context) override
Draws entity and its children.
virtual short minimumFileVersion_MeOnly() const
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
virtual bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap)
Loads own object data.
ccHObject * getParent() const
Returns parent object.
virtual void redrawDisplay(bool forceRedraw=true, bool only2D=false)
Redraws associated display.
void removeChild(ccHObject *child)
Mesh (triangle) material.
int addMaterial(ccMaterial::CShared mat, bool allowDuplicateNames=false)
Adds a material.
Mesh (triangle) material.
QSharedPointer< const ccMaterial > CShared
Const + Shared type.
QSharedPointer< ccMaterial > Shared
Shared type.
void setMaterialSet(ccMaterialSet *materialSet, bool autoReleaseOldMaterialSet=true)
Sets associated material set (may be shared)
void addTriangle(unsigned i1, unsigned i2, unsigned i3)
Adds a triangle to the mesh.
virtual void setLocked(bool state)
Sets the "enabled" property.
void setMetaData(const QString &key, const QVariant &data)
Sets a meta-data element.
virtual void setName(const QString &name)
Sets object name.
virtual void setEnabled(bool state)
Sets the "enabled" property.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
int addScalarField(const char *uniqueName) override
Creates a new scalar field and registers it.
bool resizeTheRGBTable(bool fillWithWhite=false)
Resizes the RGB colors array.
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
bool resize(unsigned numberOfPoints) override
Resizes all the active features arrays.
void setPointColor(size_t pointIndex, const ecvColor::Rgb &col)
Sets a particular point color.
ccPointCloud * partialClone(const cloudViewer::ReferenceCloud *selection, int *warnings=nullptr, bool withChildEntities=true) const
Creates a new point cloud object from a ReferenceCloud (selection)
static bool CorruptError()
Sends a custom error message (corrupted file) and returns 'false'.
QMultiMap< unsigned, unsigned > LoadedIDMap
Map of loaded unique IDs (old ID --> new ID)
static bool ReadError()
Sends a custom error message (read error) and returns 'false'.
static bool WriteError()
Sends a custom error message (write error) and returns 'false'.
static bool GenericArrayFromFile(std::vector< Type > &data, QFile &in, short dataVersion, const QString &verboseDescription)
Helper: loads a vector structure from file.
static bool GenericArrayToFile(const std::vector< Type > &data, QFile &out)
Helper: saves a vector to file.
void setValidity(bool state)
Sets bonding box validity.
void clear()
Resets the bounding box.
void add(const Vector3Tpl< T > &P)
'Enlarges' the bounding box with a point
void setEigenPoints(const std::vector< Eigen::Vector3d > &points)
ScalarField * getScalarField(int index) const
Returns a pointer to a specific scalar field.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
void getBoundingBox(CCVector3 &bbMin, CCVector3 &bbMax) override
unsigned size() const override
const CCVector3 * getPoint(unsigned index) const override
A very simple point cloud (no point duplication)
virtual bool addPointIndex(unsigned globalIndex)
Point global index insertion mechanism.
A simple scalar field (to be associated to a point cloud)
virtual void computeMinAndMax()
Determines the min and max values.
void setValue(std::size_t index, ScalarType value)
LineSet define a sets of lines in 3D. A typical application is to display the point cloud corresponde...
LineSet & PaintUniformColor(const Eigen::Vector3d &color)
Assigns each line in the LineSet the same color.
Main application interface (for plugins)
virtual void putObjectBackIntoDBTree(ccHObject *obj, const ccHObjectContext &context)=0
Adds back object to DB tree.
virtual void addToDB(ccHObject *obj, bool updateZoom=false, bool autoExpandDBTree=true, bool checkDimensions=false, bool autoRedraw=true)=0
virtual ccHObjectContext removeObjectTemporarilyFromDBTree(ccHObject *obj)=0
Removes object temporarily from DB tree.
__host__ __device__ int2 abs(int2 v)
QTextStream & endl(QTextStream &stream)
constexpr ColorCompType MAX
Max value of a single color component (default type)
Eigen::Matrix< Index, 2, 1 > Vector2i
Backup "context" for an object.