44 m_associatedCloud(nullptr),
45 m_triNormals(nullptr),
48 m_triVertIndexes(nullptr),
50 m_triMtlIndexes(nullptr),
51 m_texCoordIndexes(nullptr),
52 m_triNormalIndexes(nullptr) {
71 const std::vector<Eigen::Vector3i>& triangles)
79 if (cloud->
resize(
static_cast<unsigned>(vertices.size()))) {
89 m_associatedCloud(nullptr),
90 m_triNormals(nullptr),
93 m_triVertIndexes(nullptr),
95 m_triMtlIndexes(nullptr),
96 m_texCoordIndexes(nullptr),
97 m_triNormalIndexes(nullptr) {
103 unsigned triNum = giMesh->
size();
107 for (
unsigned i = 0; i < triNum; ++i) {
151 this->
merge(&mesh,
false);
156 if (!this->
merge(&mesh,
false)) {
166 return (
ccMesh(*
this) += mesh);
179 bool ccMesh::CreateInternalCloud() {
185 "Already has associated vertices cloud!");
192 "Creating associated vertices cloud failed!");
251 "[ccMesh::computePerVertexNormals] Vertex set is not a "
256 unsigned triCount =
size();
264 "[ccMesh::computePerVertexNormals] Not enough vertices! (<3)");
272 std::vector<CCVector3> theNorms;
275 }
catch (
const std::bad_alloc&) {
276 CVLog::Warning(
"[ccMesh::computePerVertexNormals] Not enough memory!");
281 bool normalsWereAllocated = cloud->
hasNormals();
283 ->resizeTheNormsTable())
293 for (
unsigned i = 0; i < triCount; ++i) {
296 assert(tsi->
i1 < vertCount && tsi->
i2 < vertCount &&
297 tsi->
i3 < vertCount);
307 theNorms[tsi->
i1] += N;
308 theNorms[tsi->
i2] += N;
309 theNorms[tsi->
i3] += N;
315 for (
unsigned i = 0; i < vertCount; i++) {
326 if (!normalsWereAllocated) cloud->
showNormals(
true);
332 unsigned triCount =
size();
334 CVLog::Warning(
"[ccMesh::computePerTriangleNormals] Empty mesh!");
346 "[ccMesh::computePerTriangleNormals] Not enough memory!");
352 for (
unsigned i = 0; i < triCount; ++i) {
363 normIndexes->emplace_back(nIndex);
372 "[ccMesh::computePerTriangleNormals] Not enough memory!");
378 for (
int i = 0; i < static_cast<int>(triCount); ++i)
399 ScalarType* meanSF =
new ScalarType[nPts];
406 unsigned*
count =
new unsigned[nPts];
415 for (
unsigned i = 0; i < nPts; ++i) {
422 unsigned nTri =
size();
425 for (
unsigned i = 0; i < nTri; ++i) {
445 for (
unsigned i = 0; i < nPts; ++i) meanSF[i] /=
count[i];
451 for (
unsigned i = 0; i < nPts; ++i)
456 for (
unsigned i = 0; i < nPts; ++i) {
471 bool autoReleaseOldTable ) {
493 bool autoReleaseOldMaterialSet ) {
531 bool recoded =
false;
547 newNorms->emplace_back(newNormIndex);
554 for (
unsigned i=0; i<numTriNormals; i++)
584 void** additionalParameters,
586 std::vector<int>* equivalentIndexes =
587 static_cast<std::vector<int>*
>(additionalParameters[0]);
596 nNSS.prepare(c_defaultSearchRadius,
607 nNSS.pointsInNeighbourhood.resize(n);
615 cloudViewer::DgmOctree::NeighboursSet::iterator it =
616 nNSS.pointsInNeighbourhood.begin();
617 for (
unsigned i = 0; i < n; ++i, ++it) {
621 nNSS.alreadyVisitedNeighbourhoodSize = 1;
625 for (
unsigned i = 0; i < n; ++i) {
627 if (equivalentIndexes->at(thisIndex) < 0)
636 nNSS, c_defaultSearchRadius,
false);
640 for (
unsigned j = 0; j < k; ++j) {
642 const unsigned& otherIndex =
643 nNSS.pointsInNeighbourhood[j].pointIndex;
644 if (
static_cast<int>(otherIndex) != thisIndex)
645 equivalentIndexes->at(otherIndex) = thisIndex;
650 equivalentIndexes->at(thisIndex) = thisIndex;
662 QWidget* parentWidget ) {
669 unsigned faceCount =
size();
670 if (vertCount == 0 || faceCount == 0) {
672 "[ccMesh::mergeDuplicatedVertices] No triangle or no vertex");
677 std::vector<int> equivalentIndexes;
678 const int razValue = -1;
679 equivalentIndexes.resize(vertCount, razValue);
683 QScopedPointer<ecvProgressDialog> pDlg(
nullptr);
696 void* additionalParameters[] = {
697 static_cast<void*
>(&equivalentIndexes)};
700 pDlg.data(),
"Tag duplicated vertices");
704 "[MergeDuplicatedVertices] Duplicated vertices removal "
705 "algorithm failed?!");
710 unsigned remainingCount = 0;
711 for (
unsigned i = 0; i < vertCount; ++i) {
712 int eqIndex = equivalentIndexes[i];
713 assert(eqIndex >= 0);
714 if (eqIndex ==
static_cast<int>(i))
718 int newIndex =
static_cast<int>(vertCount + remainingCount);
719 equivalentIndexes[i] = newIndex;
725 if (!newVerticesRef.
reserve(remainingCount)) {
732 for (
unsigned i = 0; i < vertCount; ++i) {
733 int eqIndex = equivalentIndexes[i];
734 if (eqIndex >=
static_cast<int>(vertCount))
737 equivalentIndexes[i] =
738 equivalentIndexes[eqIndex];
758 unsigned newFaceCount = 0;
759 for (
unsigned i = 0; i < faceCount; ++i) {
761 tri->
i1 =
static_cast<unsigned>(equivalentIndexes[tri->
i1]) -
763 tri->
i2 =
static_cast<unsigned>(equivalentIndexes[tri->
i2]) -
765 tri->
i3 =
static_cast<unsigned>(equivalentIndexes[tri->
i3]) -
770 if (tri->
i1 != tri->
i2 && tri->
i1 != tri->
i3 &&
771 tri->
i2 != tri->
i3) {
777 if (newFaceCount == 0) {
779 "[MergeDuplicatedVertices] After vertex fusion, all "
780 "triangles would collapse! We'll keep the non-fused "
783 newVertices =
nullptr;
803 "[MergeDuplicatedVertices] Remaining vertices after "
804 "auto-removal of duplicate ones: %i",
807 "[MergeDuplicatedVertices] Remaining faces after auto-removal "
808 "of duplicate ones: %i",
811 }
catch (
const std::bad_alloc&) {
813 "[MergeDuplicatedVertices] Not enough memory: could not remove "
814 "duplicated vertices!");
823 return Eigen::Vector3d(0.0, 0.0, 0.0);
831 return Eigen::Vector3d(0.0, 0.0, 0.0);
839 return Eigen::Vector3d(0.0, 0.0, 0.0);
878 cloud->
Scale(s, center);
883 const Eigen::Vector3d& center) {
899 const std::vector<size_t>& indices,
bool cleanup)
const {
902 "[SelectByIndices] This mesh contains triangle uvs that are "
903 "not handled in this function");
907 assert(baseVertices);
909 auto output = std::make_shared<ccMesh>(baseVertices);
910 output->reserve(indices.size());
916 for (
const auto& sel_vidx : indices) {
919 "[SelectByIndex] indices contains index {} out of range. "
924 if (new_vert_ind[sel_vidx] >= 0) {
927 new_vert_ind[sel_vidx] = int(output->getVerticeSize());
930 static_cast<unsigned>(sel_vidx))));
931 if (has_vertex_normals) {
936 static_cast<unsigned>(sel_vidx)));
938 if (has_vertex_colors) {
943 static_cast<unsigned>(sel_vidx)));
947 for (
size_t tidx = 0; tidx <
size(); ++tidx) {
950 int nvidx0 = new_vert_ind[triangle(0)];
951 int nvidx1 = new_vert_ind[triangle(1)];
952 int nvidx2 = new_vert_ind[triangle(2)];
953 if (nvidx0 >= 0 && nvidx1 >= 0 && nvidx2 >= 0) {
955 if (has_triangle_normals) {
964 output->RemoveDuplicatedVertices();
965 output->RemoveDuplicatedTriangles();
966 output->RemoveUnreferencedVertices();
967 output->RemoveDegenerateTriangles();
971 output->shrinkToFit();
981 output->addChild(baseVertices);
984 "Triangle mesh sampled from {:d} vertices and {:d} triangles to "
985 "{:d} vertices and {:d} triangles.",
987 (
int)output->size());
995 "[ccMesh::Crop] ccBBox either has zeros "
996 "size, or has wrong bounds.");
997 return std::make_shared<ccMesh>(
nullptr);
1005 "[ccMesh::Crop] ecvOrientedBBox either has zeros "
1006 "size, or has wrong bounds.");
1007 return std::make_shared<ccMesh>(
nullptr);
1021 unsigned faceCount =
size();
1022 if (!vertCount || !faceCount)
return false;
1024 std::vector<CCVector3> verticesDisplacement;
1026 verticesDisplacement.resize(vertCount);
1027 }
catch (
const std::bad_alloc&) {
1033 std::vector<unsigned> edgesCount;
1035 edgesCount.resize(vertCount, 0);
1036 }
catch (
const std::bad_alloc&) {
1042 for (
unsigned j = 0; j < faceCount; j++) {
1044 edgesCount[tri->
i1] += 2;
1045 edgesCount[tri->
i2] += 2;
1046 edgesCount[tri->
i3] += 2;
1054 QObject::tr(
"Iterations: %1\nVertices: %2\nFaces: %3")
1058 progressCb->
start();
1062 for (
unsigned iter = 0; iter < nbIteration; iter++) {
1063 std::fill(verticesDisplacement.begin(), verticesDisplacement.end(),
1068 for (
unsigned j = 0; j < faceCount; j++) {
1080 verticesDisplacement[tri->
i1] += dAB + dAC;
1081 verticesDisplacement[tri->
i2] += dBC - dAB;
1082 verticesDisplacement[tri->
i3] -= dAC + dBC;
1091 for (
unsigned i = 0; i < vertCount; i++) {
1092 if (edgesCount[i]) {
1097 (*P) += verticesDisplacement[i] * (factor / edgesCount[i]);
1118 unsigned triNum =
size();
1122 std::vector<unsigned> usedVerts;
1130 usedVerts.resize(vertNum, 0);
1131 }
catch (
const std::bad_alloc&) {
1139 for (
unsigned i = 0; i < triNum; ++i) {
1142 usedVerts[tsi->
i1] = 1;
1143 usedVerts[tsi->
i2] = 1;
1144 usedVerts[tsi->
i3] = 1;
1149 unsigned realVertCount = 0;
1151 for (
unsigned i = 0; i < vertNum; ++i)
1152 usedVerts[i] = (usedVerts[i] == 1 ? realVertCount++ : vertNum);
1157 if (realVertCount == vertNum) {
1162 if (rc.
reserve(realVertCount)) {
1163 for (
unsigned i = 0; i < vertNum; ++i) {
1164 if (usedVerts[i] != vertNum)
1172 if (newVertices && newVertices->
size() < rc.
size()) {
1175 newVertices =
nullptr;
1190 if (!vertices)
delete newVertices;
1197 if (!usedVerts.empty())
1200 for (
unsigned i = 0; i < triNum; ++i) {
1204 usedVerts[tsi->
i3]);
1206 usedVerts.resize(0);
1209 for (
unsigned i = 0; i < triNum; ++i) {
1221 if (!clonedNormsTable) {
1225 if (clonedNormsTable)
1229 "[ccMesh::clone] Not enough memory: failed to "
1230 "clone per-triangle normals!");
1249 "[ccMesh::clone] Not enough memory: failed to clone "
1250 "per-triangle normal indexes!");
1259 if (!clonedMaterials) {
1263 if (clonedMaterials) {
1267 "[ccMesh::clone] Not enough memory: failed to "
1268 "clone materials set!");
1276 if (clonedMaterials) {
1285 "[ccMesh::clone] Not enough memory: failed to clone "
1286 "per-triangle materials!");
1295 if (!cloneTexCoords) {
1299 if (!cloneTexCoords) {
1301 "[ccMesh::clone] Not enough memory: failed to "
1302 "clone texture coordinates!");
1311 if (cloneTexCoords) {
1321 "[ccMesh::clone] Not enough memory: failed to clone "
1322 "per-triangle texture info!");
1348 int* warnings )
const {
1351 if (triangleIndices.empty()) {
1352 CVLog::Warning(
"[ccMesh::partialClone] Empty triangle selection");
1356 unsigned triNum =
size();
1359 for (
unsigned triIdx : triangleIndices) {
1360 if (triIdx >= triNum) {
1361 CVLog::Error(QString(
"[ccMesh::partialClone] Triangle index %1 out "
1370 std::set<unsigned> usedVerticesSet;
1371 for (
unsigned triIdx : triangleIndices) {
1374 usedVerticesSet.insert(tri->
i1);
1375 usedVerticesSet.insert(tri->
i2);
1376 usedVerticesSet.insert(tri->
i3);
1380 std::map<unsigned, unsigned> vertexIndexMap;
1381 unsigned newVertexIndex = 0;
1382 for (
unsigned oldIdx : usedVerticesSet) {
1383 vertexIndexMap[oldIdx] = newVertexIndex++;
1388 if (!refCloud.
reserve(
static_cast<unsigned>(usedVerticesSet.size()))) {
1390 "[ccMesh::partialClone] Not enough memory for vertex reference "
1395 for (
unsigned oldIdx : usedVerticesSet) {
1401 int cloneWarnings = 0;
1405 *warnings = cloneWarnings;
1412 CVLog::Error(
"[ccMesh::partialClone] Failed to clone vertices");
1418 if (!partialMesh->
reserve(
static_cast<unsigned>(triangleIndices.size()))) {
1422 "[ccMesh::partialClone] Not enough memory for mesh triangles");
1427 for (
unsigned oldTriIdx : triangleIndices) {
1431 vertexIndexMap[tri->
i2],
1432 vertexIndexMap[tri->
i3]);
1439 if (clonedNormsTable) {
1441 partialMesh->
addChild(clonedNormsTable);
1444 for (
unsigned oldTriIdx : triangleIndices) {
1451 "[ccMesh::partialClone] Failed to clone triangle "
1457 "[ccMesh::partialClone] Failed to reserve triangle normal "
1466 if (clonedMaterials) {
1468 partialMesh->
addChild(clonedMaterials);
1471 for (
unsigned oldTriIdx : triangleIndices) {
1477 "[ccMesh::partialClone] Failed to clone materials");
1482 "[ccMesh::partialClone] Failed to reserve triangle "
1483 "material indexes");
1491 if (clonedTexCoords) {
1495 for (
unsigned oldTriIdx : triangleIndices) {
1502 "[ccMesh::partialClone] Failed to clone texture "
1508 "[ccMesh::partialClone] Failed to reserve triangle texture "
1509 "coordinate indexes");
1515 partialMesh->
addChild(newVertices);
1530 CVLog::Print(QString(
"[ccMesh::partialClone] Created partial mesh: %1 "
1531 "triangles, %2 vertices")
1532 .arg(triangleIndices.size())
1533 .arg(usedVerticesSet.size()));
1541 if (!p1 || p1->
size() == 0 || !p2 || p2->
size() == 0) {
1548 CVLog::Warning(
"[ccMesh::TriangulateTwoPolylines] Not enough memory");
1555 for (
unsigned i = 0; i < p1->
size(); ++i)
1557 for (
unsigned j = 0; j < p2->
size(); ++j)
1560 assert(vertices->
size() != 0);
1567 if (projectionDir) {
1570 Y = projectionDir->
cross(
X);
1575 "[ccMesh::TriangulateTwoPolylines] Failed to fit a plane "
1576 "through both polylines");
1585 std::vector<CCVector2> points2D;
1586 std::vector<int> segments2D;
1588 points2D.reserve(p1->
size() + p2->
size());
1590 }
catch (
const std::bad_alloc&) {
1592 CVLog::Warning(
"[ccMesh::TriangulateTwoPolylines] Not enough memory");
1600 for (
size_t i = 0; i < 2; ++i) {
1602 unsigned vertCount = poly->
size();
1603 int vertIndex0 =
static_cast<int>(points2D.size());
1605 for (
unsigned v = 0; v < vertCount; ++v) {
1607 int vertIndex =
static_cast<int>(points2D.size());
1611 points2D.emplace_back(P2D);
1613 if (v + 1 < vertCount) {
1614 segments2D.emplace_back(vertIndex);
1615 segments2D.emplace_back(vertIndex + 1);
1616 }
else if (closed) {
1617 segments2D.emplace_back(vertIndex);
1618 segments2D.emplace_back(vertIndex0);
1622 assert(points2D.size() == p1->
size() + p2->
size());
1623 assert(segments2D.size() ==
1628 std::string errorStr;
1629 if (!delaunayMesh->
buildMesh(points2D, segments2D, errorStr)) {
1631 .arg(QString::fromStdString(errorStr)));
1632 delete delaunayMesh;
1642 std::vector<cloudViewer::PointProjectionTools::IndexedCCVector2>
1645 indexedPoints2D.resize(points2D.size());
1646 for (
size_t i = 0; i < points2D.size(); ++i) {
1647 indexedPoints2D[i] = points2D[i];
1648 indexedPoints2D[i].index =
static_cast<unsigned>(i);
1651 std::list<cloudViewer::PointProjectionTools::IndexedCCVector2*>
1654 indexedPoints2D, hullPoints)) {
1655 std::list<cloudViewer::PointProjectionTools::
1656 IndexedCCVector2*>::iterator A =
1658 for (; A != hullPoints.end(); ++A) {
1660 std::list<cloudViewer::PointProjectionTools::
1661 IndexedCCVector2*>::iterator B = A;
1663 if (B == hullPoints.end()) {
1664 B = hullPoints.begin();
1667 unsigned Aindex = (*A)->index;
1668 unsigned Bindex = (*B)->index;
1669 int Apoly = (Aindex < p1->
size() ? 0 : 1);
1670 int Bpoly = (Bindex < p1->
size() ? 0 : 1);
1672 if (Apoly == Bpoly) {
1674 if (abs(
static_cast<int>(Bindex) -
1675 static_cast<int>(Aindex)) > 1) {
1677 unsigned iStart = std::min(Aindex, Bindex);
1678 unsigned iStop = std::max(Aindex, Bindex);
1679 std::vector<CCVector2> contour;
1680 contour.reserve(iStop - iStart + 1);
1681 for (
unsigned j = iStart; j <= iStop; ++j) {
1682 contour.emplace_back(points2D[j]);
1692 "[ccMesh::TriangulateTwoPolylines] Failed to compute "
1693 "the convex hull (can't clean the mesh borders)");
1695 }
catch (
const std::bad_alloc&) {
1697 "[ccMesh::TriangulateTwoPolylines] Not enough memory to "
1698 "clean the mesh borders");
1703 if (mesh->
size() != delaunayMesh->
size()) {
1710 delete delaunayMesh;
1711 delaunayMesh =
nullptr;
1724 CVLog::Warning(
"[ccMesh::TriangulateTwoPolylines] Not enough memory");
1734 bool updateNormals ,
1736 unsigned char dim ) {
1737 if (!cloud || dim > 2) {
1738 CVLog::Warning(
"[ccMesh::Triangulate] Invalid input parameters!");
1741 if (cloud->
size() < 3) {
1742 CVLog::Warning(
"[ccMesh::Triangulate] Cloud has not enough points!");
1747 std::string errorStr;
1750 cloud,
type, maxEdgeLength, dim, errorStr);
1752 CVLog::Warning(QString(
"[ccMesh::Triangulate] Failed to construct "
1753 "Delaunay mesh (Triangle lib error: %1)")
1754 .arg(QString::fromStdString(errorStr)));
1763 dummyMesh =
nullptr;
1767 "[ccMesh::Triangulate] An error occurred while computing mesh! "
1768 "(not enough memory?)");
1776 if (!cloudHadNormals || updateNormals) {
1791 CVLog::Warning(
"[ccMesh::merge] Internal error: invalid input!");
1799 "[ccMesh::merge] Requires meshes with standard vertices!");
1808 const unsigned triNumBefore =
size();
1810 bool success =
false;
1812 for (
int iteration = 0; iteration < 1;
1816 unsigned vertIndexShift = 0;
1827 vertIndexShift = vertNumBefore;
1828 if (vertNumBefore == 0) {
1839 const unsigned triAdded = mesh->
size();
1840 bool otherMeshHasMaterials =
1842 bool otherMeshHasTexCoords =
1844 bool otherMeshHasTriangleNormals =
1847 if (!
reserve(triNumBefore + triAdded)) {
1863 for (
unsigned i = 0; i < triAdded; ++i) {
1867 vertIndexShift + tsi->
i3);
1875 if (otherMeshHasTriangleNormals) {
1876 size_t triIndexShift = 0;
1887 triNormalsCountBefore +
1899 triIndexShift = triNormalsCountBefore;
1905 triNumBefore + triAdded);
1915 : indexes.
u[0] +
static_cast<int>(
1919 : indexes.
u[1] +
static_cast<int>(
1933 triNumBefore + triAdded);
1936 Tuple3i defaultElement(-1, -1, -1);
1937 for (
unsigned i = 0; i < mesh->
size(); ++i)
1948 if (otherMeshHasMaterials) {
1949 std::vector<int> materialIndexMap;
1958 size_t otherMatSetSize = mesh->
m_materials->size();
1960 materialIndexMap.resize(otherMatSetSize, -1);
1961 }
catch (
const std::bad_alloc&) {
1966 for (
size_t m = 0; m != otherMatSetSize; ++m) {
1981 static_cast<int>(materialIndexMap.size()));
1983 (index < 0 ? -1 : materialIndexMap[index]);
1993 for (
unsigned i = 0; i < mesh->
size(); ++i)
2002 if (hasTexCoords || otherMeshHasTexCoords) {
2004 if (otherMeshHasTexCoords) {
2005 size_t texCoordIndexShift = 0;
2023 for (
unsigned i = 0; i < mesh->
m_texCoords->size();
2029 texCoordIndexShift = texCoordCountBefore;
2035 triNumBefore + triAdded);
2047 texCoordIndexShift),
2052 texCoordIndexShift),
2057 texCoordIndexShift));
2065 triNumBefore + triAdded);
2068 Tuple3i defaultElement(-1, -1, -1);
2083 if (createSubMesh) {
2085 const unsigned triNumAfter =
size();
2088 if (subMesh->
reserve(triNumAfter - triNumBefore)) {
2101 CVLog::Warning(QString(
"[Merge] Not enough memory to create the "
2102 "sub-mesh corresponding to mesh '%1'!")
2166 if (m_globalIterator < m_triVertIndexes->
size()) {
2174 unsigned triangleIndex)
2176 assert(triangleIndex < m_triVertIndexes->
size());
2191 assert(triangleIndex < m_triVertIndexes->
size());
2203 double C[3])
const {
2204 assert(triangleIndex < m_triVertIndexes->
size());
2215 return Eigen::Vector3d();
2253 return Eigen::Vector3d();
2268 return std::vector<Eigen::Vector3d>();
2297 return Eigen::Vector3d();
2313 return std::vector<Eigen::Vector3d>();
2347 "[ccMesh] m_associatedCloud must be set before use!");
2355 "[ccMesh] m_associatedCloud must be set before use!");
2370 return std::vector<Eigen::Vector3d>();
2381 static_cast<unsigned>(cloud->
size() + vertices.size()))) {
2393 for (
size_t i = 0; i <
count; ++i) {
2439 "[ccMesh::setTriangle] index out of range!");
2444 static_cast<unsigned>(triangle[1]),
2445 static_cast<unsigned>(triangle[2]));
2456 resize(triangles.size());
2457 for (
unsigned int i = 0; i <
size(); ++i) {
2465 return std::vector<Eigen::Vector3i>();
2468 std::vector<Eigen::Vector3i> triangles(
size());
2469 for (
size_t i = 0; i <
size(); ++i) {
2493 static const int s_defaultMtlIndex = -1;
2499 static const Tuple3i s_defaultTexCoords(-1, -1, -1);
2505 static const Tuple3i s_defaultNormIndexes(-1, -1, -1);
2516 "Must call CreateInternalCloud first!");
2522 if (!baseVertices->
resize(n)) {
2528 "[resizeTheNormsTable] Not have enough memory! ");
2533 "[resizeTheRGBTable] Not have enough memory! ");
2544 "Must call CreateInternalCloud first!");
2552 "[reserveThePointsTable] Not have enough memory! ");
2557 "[reserveTheNormsTable] Not have enough memory! ");
2562 "[reserveTheRGBTable] Not have enough memory! ");
2575 assert(std::max(index1, index2) <
size());
2584 if (index >=
size()) {
2586 "[ccMesh::removeTriangles] index out of range!");
2600 unsigned triangleIndex) {
2605 unsigned triangleIndex)
const {
2613 vertIndx(0) = tsi->
i1;
2614 vertIndx(1) = tsi->
i2;
2615 vertIndx(2) = tsi->
i3;
2619 if (m_globalIterator < m_triVertIndexes->
size()) {
2646 if (triNum == 0)
return;
2650 (triNum >
context.minLODTriangleCount &&
2652 unsigned decimStep =
2653 (lodEnabled ?
static_cast<unsigned>(
2654 ceil(
static_cast<double>(triNum * 3) /
2691 if (entityPickingMode) {
2698 showTriNormals =
false;
2699 applyMaterials =
false;
2700 showTextures =
false;
2703 bool greyForNanScalarValues =
true;
2714 if (greyForNanScalarValues && entityPickingMode) {
2742 context.visFiltering = visFiltering;
2748 bool removeSelectedTriangles,
2749 std::vector<int>* newIndexesOfRemainingTriangles ,
2750 bool withChildEntities ) {
2755 size_t triCount =
size();
2758 std::vector<int> triangleIndexMap;
2761 ccMesh* newMesh =
nullptr;
2769 false,
nullptr,
nullptr,
true, &rc);
2772 "[ccMesh::createNewMeshFromSelection] Failed to create "
2773 "segmented mesh vertices! (not enough memory)");
2778 }
else if (newVertices->
size() == 0) {
2780 "[ccMesh::createNewMeshFromSelection] No visible point in "
2785 assert(newVertices);
2798 this, &rc,
true,
nullptr, newVertices, 0,
2802 "[ccMesh::createNewMeshFromSelection] Process failed: not "
2807 newMesh =
new ccMesh(selection, newVertices);
2810 selection =
nullptr;
2814 newVertices =
nullptr;
2816 "[ccMesh::createNewMeshFromSelection] An error occurred: "
2817 "not enough memory?");
2830 bool addFeatures =
false;
2840 std::vector<int> newNormIndexes;
2846 newTriNormals->
link();
2849 }
catch (
const std::bad_alloc&) {
2851 "[ccMesh::createNewMeshFromSelection] Failed to "
2852 "create new normals subset! (not enough memory)");
2855 newTriNormals =
nullptr;
2860 std::vector<int> newTexIndexes;
2866 newTriTexIndexes->
link();
2869 }
catch (
const std::bad_alloc&) {
2871 "[ccMesh::createNewMeshFromSelection] Failed to "
2872 "create new texture indexes subset! (not enough "
2876 newTriTexIndexes =
nullptr;
2881 std::vector<int> newMatIndexes;
2887 QString(
".subset"));
2888 newMaterials->
link();
2891 }
catch (
const std::bad_alloc&) {
2893 "[ccMesh::createNewMeshFromSelection] Failed to "
2894 "create new material subset! (not enough memory)");
2897 newMaterials =
nullptr;
2898 if (newTriTexIndexes)
2904 newTriTexIndexes =
nullptr;
2905 newTexIndexes.resize(0);
2910 for (
size_t i = 0; i < triCount; ++i) {
2911 if (triangleIndexMap[i] >= 0)
2914 if (newTriNormals) {
2918 const Tuple3i& triNormIndexes =
2924 for (
unsigned j = 0; j < 3; ++j) {
2925 if (triNormIndexes.
u[j] >= 0 &&
2926 newNormIndexes[triNormIndexes.
u[j]] < 0) {
2927 if (newTriNormals->size() ==
2928 newTriNormals->capacity() &&
2930 newTriNormals->size() +
2935 "createNewMeshFromSelection] "
2936 "Failed to create new normals "
2937 "subset! (not enough memory)");
2940 newTriNormals =
nullptr;
2946 newNormIndexes[triNormIndexes.
u[j]] =
2955 newTriNormals->emplace_back(
2957 triNormIndexes.
u[j]));
2964 triNormIndexes.
u[0] < 0
2966 : newNormIndexes[triNormIndexes
2968 triNormIndexes.
u[1] < 0
2970 : newNormIndexes[triNormIndexes
2972 triNormIndexes.
u[2] < 0
2974 : newNormIndexes[triNormIndexes
2980 if (newTriTexIndexes) {
2984 const Tuple3i& triTexIndexes =
2991 for (
unsigned j = 0; j < 3; ++j) {
2992 if (triTexIndexes.
u[j] >= 0 &&
2993 newTexIndexes[triTexIndexes.
u[j]] < 0) {
2994 if (newTriTexIndexes->size() ==
2995 newTriTexIndexes->capacity() &&
2997 newTriTexIndexes->size() +
3001 "Failed to create new texture "
3002 "coordinates subset! (not enough "
3006 newTriTexIndexes =
nullptr;
3011 newTexIndexes[triTexIndexes.
u[j]] =
static_cast<
3017 newTriTexIndexes->emplace_back(
3019 triTexIndexes.
u[j]));
3023 if (newTriTexIndexes)
3026 triTexIndexes.
u[0] < 0
3028 : newTexIndexes[triTexIndexes.
u[0]],
3029 triTexIndexes.
u[1] < 0
3031 : newTexIndexes[triTexIndexes.
u[1]],
3032 triTexIndexes.
u[2] < 0
3034 : newTexIndexes[triTexIndexes
3049 if (triMatIndex >= 0 &&
3050 newMatIndexes[triMatIndex] < 0) {
3053 newMatIndexes[triMatIndex] =
static_cast<int>(
3054 newMaterials->size());
3058 newMaterials->emplace_back(
3060 }
catch (
const std::bad_alloc&) {
3062 "[ccMesh::createNewMeshFromSelection] "
3063 "Failed to create new materials "
3064 "subset! (not enough memory)");
3067 newMaterials =
nullptr;
3076 : newMatIndexes[triMatIndex]);
3082 if (newTriNormals) {
3083 newTriNormals->resize(
3084 newTriNormals->size());
3088 newTriNormals =
nullptr;
3091 if (newTriTexIndexes) {
3094 newTriTexIndexes =
nullptr;
3100 newMaterials =
nullptr;
3117 if (removeSelectedTriangles) {
3118 newRemainingTriangleIndexes.resize(
3119 triCount,
static_cast<unsigned>(triCount));
3121 unsigned newInvisibleIndex = 0;
3122 for (
size_t i = 0; i < triCount; ++i) {
3123 if (triangleIndexMap[i] <
3127 newRemainingTriangleIndexes[i] = newInvisibleIndex++;
3132 for (
size_t i = 0; i < subMeshes.size(); ++i) {
3135 removeSelectedTriangles, triangleIndexMap,
3136 removeSelectedTriangles ? &newRemainingTriangleIndexes
3148 newSubMesh =
nullptr;
3152 if (subMesh->
size() ==
3156 subMeshes[i] =
nullptr;
3160 }
catch (
const std::bad_alloc&) {
3167 for (
size_t i = 0; i < subMeshes.size(); ++i) {
3173 if (withChildEntities) {
3178 if (removeSelectedTriangles) {
3179 if (newIndexesOfRemainingTriangles) {
3180 if (newIndexesOfRemainingTriangles->empty()) {
3182 newIndexesOfRemainingTriangles->resize(triCount);
3183 }
catch (
const std::bad_alloc&) {
3185 "[ccMesh::createNewMeshFromSelection] Not enough "
3189 }
else if (newIndexesOfRemainingTriangles->size() != triCount) {
3191 "[ccMesh::createNewMeshFromSelection] Input 'new "
3192 "indexes of reamining triangles' vector has a wrong "
3197 assert(!newIndexesOfRemainingTriangles ||
3198 newIndexesOfRemainingTriangles->size() == triCount);
3206 for (
size_t i = 0; i < triCount; ++i) {
3207 if (triangleIndexMap[i] < 0)
3212 for (
unsigned j = 0; j < 3; ++j) {
3229 if (newIndexesOfRemainingTriangles) {
3230 newIndexesOfRemainingTriangles->at(i) =
3231 static_cast<int>(lastTri);
3234 }
else if (newIndexesOfRemainingTriangles) {
3235 newIndexesOfRemainingTriangles->at(i) = -1;
3243 std::vector<int> newIndexes;
3251 for (
int j = 0; j < 3; ++j) {
3252 int oldVertexIndex = tsi.
i[j];
3253 assert(oldVertexIndex < newIndexes.size());
3254 tsi.
i[j] = newIndexes[oldVertexIndex];
3260 "[ccMesh::createNewMeshFromSelection] Failed to remove "
3267 }
else if (newIndexesOfRemainingTriangles) {
3269 "[ccMesh::createNewMeshFromSelection] A 'new indexes of "
3270 "reamining triangles' vector was provided while no triangle "
3271 "shall be removed");
3374 if (indexes.
u[0] >= 0)
3379 if (indexes.
u[1] >= 0)
3384 if (indexes.
u[2] >= 0)
3399 double Nc[3])
const {
3403 if (indexes.
u[0] >= 0) {
3408 Na[0] =
static_cast<double>(n1[0]);
3409 Na[1] =
static_cast<double>(n1[1]);
3410 Na[2] =
static_cast<double>(n1[2]);
3416 if (indexes.
u[1] >= 0) {
3421 Nb[0] =
static_cast<double>(n2[0]);
3422 Nb[1] =
static_cast<double>(n2[1]);
3423 Nb[2] =
static_cast<double>(n2[2]);
3430 if (indexes.
u[2] >= 0) {
3435 Nc[0] =
static_cast<double>(n3[0]);
3436 Nc[1] =
static_cast<double>(n3[1]);
3437 Nc[2] =
static_cast<double>(n3[2]);
3450 Eigen::Vector3d& Na,
3451 Eigen::Vector3d& Nb,
3452 Eigen::Vector3d& Nc)
const {
3457 std::vector<Eigen::Vector3d> triangleNormals;
3458 triangleNormals.reserve(this->
size());
3459 for (
size_t i = 0; i < this->
size(); i++) {
3462 return triangleNormals;
3466 std::vector<CCVector3*> triNormals;
3467 for (
size_t i = 0; i < this->
size(); i++) {
3475 if (index >=
m_triNormals->size())
return Eigen::Vector3d(0.0, 0.0, 0.0);
3480 return Eigen::Vector3d(n1[0], n1[1], n1[2]);
3484 const Eigen::Vector3d& triangle_normal) {
3526 int normalIndex =
static_cast<int>(
m_triNormals->size() - 1);
3538 "[getTriangleNorms] has no triangle normals!");
3539 return std::vector<Eigen::Vector3d>();
3542 std::vector<Eigen::Vector3d> triangle_normals(
m_triNormals->size());
3547 return triangle_normals;
3551 const std::vector<Eigen::Vector3d>& triangle_normals) {
3552 bool success =
true;
3555 for (
size_t i = 0; i < triangle_normals.size(); ++i) {
3558 "[ccMesh::addTriangleNorms] add triangle normals "
3572 const std::vector<Eigen::Vector3d>& triangle_normals) {
3573 bool success =
true;
3575 for (
const auto&
normal : triangle_normals) {
3578 "[ccMesh::addTriangleNorms] add triangle normals "
3599 bool autoReleaseOldTable ) {
3629 if (txInd.
u[0] >=
static_cast<int>(texCoordsSize) ||
3630 txInd.
u[1] >=
static_cast<int>(texCoordsSize) ||
3631 txInd.
u[2] >=
static_cast<int>(texCoordsSize)) {
3633 "[ccMesh::getTriangleTexCoordinates] Triangle %u: texCoord "
3634 "indices [%d, %d, %d] out of range (size=%u)",
3635 triIndex, txInd.
u[0], txInd.
u[1], txInd.
u[2],
3639 tx1 = (txInd.
u[0] >= 0 && txInd.
u[0] <
static_cast<int>(texCoordsSize)
3642 tx2 = (txInd.
u[1] >= 0 && txInd.
u[1] <
static_cast<int>(texCoordsSize)
3645 tx3 = (txInd.
u[2] >= 0 && txInd.
u[2] <
static_cast<int>(texCoordsSize)
3649 tx1 = tx2 = tx3 =
nullptr;
3675 if (texCoordIndexes) texCoordIndexes->
release();
3720 bool autoReleaseOldTable ) {
3767 assert(out.isOpen() && (out.openMode() & QIODevice::WriteOnly));
3768 if (dataVersion < 29) {
3778 uint32_t vertUniqueID =
3782 if (out.write((
const char*)&vertUniqueID, 4) < 0)
return WriteError();
3790 uint32_t normArrayID =
3794 if (out.write((
const char*)&normArrayID, 4) < 0)
return WriteError();
3803 uint32_t texCoordArrayID =
3807 if (out.write((
const char*)&texCoordArrayID, 4) < 0)
3820 if (out.write((
const char*)&matSetID, 4) < 0)
return WriteError();
3826 "Internal error: mesh has no triangles array! (not enough "
3835 if (out.write((
const char*)&hasTriMtlIndexes,
sizeof(
bool)) < 0)
3837 if (hasTriMtlIndexes) {
3839 if (!ccSerializationHelper::GenericArrayToFile<int, 1, int>(
3846 if (out.write((
const char*)&hasTexCoordIndexes,
sizeof(
bool)) < 0)
3848 if (hasTexCoordIndexes) {
3850 if (!ccSerializationHelper::GenericArrayToFile<Tuple3i, 3, int>(
3856 bool hasTriNormalIndexes =
3858 if (out.write((
const char*)&hasTriNormalIndexes,
sizeof(
bool)) < 0)
3860 if (hasTriNormalIndexes) {
3862 if (!ccSerializationHelper::GenericArrayToFile<Tuple3i, 3, int>(
3872 std::max(
static_cast<short>(29),
3890 uint32_t vertUniqueID = 0;
3891 if (in.read((
char*)&vertUniqueID, 4) < 0)
return ReadError();
3903 uint32_t normArrayID = 0;
3904 if (in.read((
char*)&normArrayID, 4) < 0)
return ReadError();
3917 uint32_t texCoordArrayID = 0;
3918 if (in.read((
char*)&texCoordArrayID, 4) < 0)
return ReadError();
3931 uint32_t matSetID = 0;
3932 if (in.read((
char*)&matSetID, 4) < 0)
return ReadError();
3946 bool hasTriMtlIndexes =
false;
3947 if (in.read((
char*)&hasTriMtlIndexes,
sizeof(bool)) < 0)
return ReadError();
3948 if (hasTriMtlIndexes) {
3953 if (!ccSerializationHelper::GenericArrayFromFile<int, 1, int>(
3962 bool hasTexCoordIndexes =
false;
3963 if (in.read((
char*)&hasTexCoordIndexes,
sizeof(
bool)) < 0)
3965 if (hasTexCoordIndexes) {
3970 if (!ccSerializationHelper::GenericArrayFromFile<Tuple3i, 3, int>(
3972 "texture coordinates")) {
3980 if (dataVersion < 29) {
3988 bool hasTriNormalIndexes =
false;
3989 if (in.read((
char*)&hasTriNormalIndexes,
sizeof(
bool)) < 0)
3991 if (hasTriNormalIndexes) {
3997 if (!ccSerializationHelper::GenericArrayFromFile<Tuple3i, 3, int>(
4004 if (dataVersion < 29) {
4013 bool stippling =
false;
4014 if (in.read((
char*)&stippling,
sizeof(
bool)) < 0)
return ReadError();
4026 assert(triIndex < m_triVertIndexes->
size());
4041 weights.
x = sqrt(((P - *B).cross(*C - *B)).norm2d()) ;
4042 weights.
y = sqrt(((P - *C).cross(*A - *C)).norm2d()) ;
4043 weights.
z = sqrt(((P - *A).cross(*B - *A)).norm2d()) ;
4046 double sum = weights.
x + weights.
y + weights.
z;
4053 assert(triIndex <
size());
4068 const Tuple3i* triNormIndexes ) {
4071 if (!triNormIndexes || triNormIndexes->
u[0] >= 0) {
4075 triNormIndexes->
u[0]))
4080 if (!triNormIndexes || triNormIndexes->
u[1] >= 0) {
4084 triNormIndexes->
u[1]))
4089 if (!triNormIndexes || triNormIndexes->
u[2] >= 0) {
4093 triNormIndexes->
u[2]))
4108 assert(triIndex <
size());
4123 assert(triIndex <
size());
4145 floor(C1.
r * w.
u[0] + C2.
r * w.
u[1] + C3.
r * w.
u[2]));
4147 floor(C1.
g * w.
u[0] + C2.
g * w.
u[1] + C3.
g * w.
u[2]));
4149 floor(C1.
b * w.
u[0] + C2.
b * w.
u[1] + C3.
b * w.
u[2]));
4155 unsigned char vertIndex,
4157 bool returnColorIfNoTexture) {
4158 assert(triIndex <
size());
4160 assert(vertIndex < 3);
4161 if (vertIndex > 2) {
4163 "[ccMesh::getVertexColorFromMaterial] Internal error: invalid "
4173 assert(matIndex <
static_cast<int>(
m_materials->size()));
4180 bool foundMaterial =
false;
4181 if (matIndex >= 0) {
4183 if (material->hasTexture()) {
4187 (txInd.
u[vertIndex] >= 0
4193 float tx = std::modf(T->
tx, &temp);
4194 if (tx < 0) tx = 1.0f + tx;
4195 float ty = std::modf(T->
ty, &temp);
4196 if (ty < 0) ty = 1.0f + ty;
4199 const QImage texture = material->getTexture();
4201 std::min(
static_cast<int>(
floor(tx * texture.width())),
4202 texture.width() - 1);
4204 std::min(
static_cast<int>(
floor(ty * texture.height())),
4205 texture.height() - 1);
4207 QRgb pixel = texture.pixel(xPix, yPix);
4210 foundMaterial =
true;
4216 foundMaterial =
true;
4220 if (!foundMaterial && returnColorIfNoTexture &&
hasColors()) {
4222 foundMaterial =
true;
4225 return foundMaterial;
4231 bool interpolateColorIfNoTexture) {
4232 assert(triIndex <
size());
4239 assert(matIndex <
static_cast<int>(
m_materials->size()));
4244 if (interpolateColorIfNoTexture)
4251 if (!material->hasTexture()) {
4276 if (interpolateColorIfNoTexture)
4281 double x = (T1 ? T1->
tx * w.
u[0] : 0.0) + (T2 ? T2->
tx * w.
u[1] : 0.0) +
4282 (T3 ? T3->
tx * w.
u[2] : 0.0);
4283 double y = (T1 ? T1->
ty * w.
u[0] : 0.0) + (T2 ? T2->
ty * w.
u[1] : 0.0) +
4284 (T3 ? T3->
ty * w.
u[2] : 0.0);
4290 xFrac = std::modf(
x, &xInt);
4292 }
else if (
x < 0.0) {
4294 xFrac = std::modf(
x, &xInt);
4301 yFrac = std::modf(
y, &yInt);
4303 }
else if (
y < 0.0) {
4305 yFrac = std::modf(
y, &yInt);
4311 const QImage texture = material->getTexture();
4312 int xPix = std::min(
static_cast<int>(
floor(
x * texture.width())),
4313 texture.width() - 1);
4314 int yPix = std::min(
static_cast<int>(
floor(
y * texture.height())),
4315 texture.height() - 1);
4317 QRgb pixel = texture.pixel(xPix, yPix);
4332 static QMap<qint64, unsigned>
4337 if (edgeIndex1 > edgeIndex2)
std::swap(edgeIndex1, edgeIndex2);
4339 return (
static_cast<qint64
>(edgeIndex1) << 32) |
4340 static_cast<qint64
>(edgeIndex2);
4347 CVLog::Error(
"[ccMesh::pushSubdivide] Invalid input argument!");
4354 "[ccMesh::pushSubdivide] Vertices set must be a true point "
4372 CVLog::Error(
"[ccMesh::pushSubdivide] Not enough memory!");
4383 unsigned indexG1 = 0;
4386 QMap<qint64, unsigned>::const_iterator it =
4390 indexG1 = vertices->
size();
4404 indexA, indexB, indexC),
4411 indexG1 = it.value();
4414 unsigned indexG2 = 0;
4417 QMap<qint64, unsigned>::const_iterator it =
4421 indexG2 = vertices->
size();
4435 indexA, indexB, indexC),
4442 indexG2 = it.value();
4445 unsigned indexG3 = vertices->
size();
4448 QMap<qint64, unsigned>::const_iterator it =
4452 indexG3 = vertices->
size();
4466 indexA, indexB, indexC),
4473 indexG3 = it.value();
4490 CVLog::Error(
"[ccMesh::pushSubdivide] Not enough memory!");
4504 CVLog::Error(
"[ccMesh::subdivide] Invalid input argument!");
4509 unsigned triCount =
size();
4511 unsigned vertCount = (vertices ? vertices->
size() : 0);
4512 if (!vertices || vertCount * triCount == 0) {
4513 CVLog::Error(
"[ccMesh::subdivide] Invalid mesh: no face or no vertex!");
4521 if (!resultVertices) {
4522 CVLog::Error(
"[ccMesh::subdivide] Not enough memory!");
4527 resultMesh->
addChild(resultVertices);
4529 if (!resultMesh->
reserve(triCount)) {
4530 CVLog::Error(
"[ccMesh::subdivide] Not enough memory!");
4538 for (
unsigned i = 0; i < triCount; ++i) {
4543 CVLog::Error(
"[ccMesh::subdivide] Not enough memory!");
4549 CVLog::Error(
"[ccMesh::subdivide] An error occurred!");
4557 unsigned newTriCount = resultMesh->
size();
4558 for (
unsigned i = 0; i < newTriCount; ++i) {
4563 unsigned indexA = tri.
i1;
4564 unsigned indexB = tri.
i2;
4565 unsigned indexC = tri.
i3;
4570 QMap<qint64, unsigned>::const_iterator it =
4574 indexG1 = (int)it.value();
4578 QMap<qint64, unsigned>::const_iterator it =
4582 indexG2 = (
int)it.value();
4586 QMap<qint64, unsigned>::const_iterator it =
4590 indexG3 = (
int)it.value();
4594 unsigned brokenEdges = (indexG1 < 0 ? 0 : 1) +
4595 (indexG2 < 0 ? 0 : 1) +
4596 (indexG3 < 0 ? 0 : 1);
4598 if (brokenEdges == 1) {
4599 int indexG = indexG1;
4600 unsigned char i1 = 2;
4604 }
else if (indexG3 >= 0) {
4608 assert(indexG >= 0);
4611 unsigned indexes[3] = {indexA, indexB, indexC};
4614 tri.
i1 = indexes[i1];
4616 tri.
i3 = indexes[(i1 + 2) % 3];
4620 indexes[(i1 + 1) % 3], indexG)) {
4621 CVLog::Error(
"[ccMesh::subdivide] Not enough memory!");
4625 }
else if (brokenEdges == 2) {
4634 indexG2, indexG3) ||
4637 CVLog::Error(
"[ccMesh::subdivide] Not enough memory!");
4641 }
else if (indexG2 < 0)
4649 indexG3, indexG1) ||
4652 CVLog::Error(
"[ccMesh::subdivide] Not enough memory!");
4664 indexG1, indexG2) ||
4667 CVLog::Error(
"[ccMesh::subdivide] Not enough memory!");
4672 }
else if (brokenEdges ==
4687 CVLog::Error(
"[ccMesh::subdivide] Not enough memory!");
4694 CVLog::Error(
"[ccMesh::subdivide] An error occurred!");
4721 "[ccMesh::convertMaterialsToVertexColors] Mesh has no "
4728 "[ccMesh::convertMaterialsToVertexColors] Need a true point "
4729 "cloud as vertices!");
4736 "[ccMesh::convertMaterialsToVertexColors] Failed to resize "
4737 "vertices color table! (not enough memory?)");
4742 unsigned faceCount =
size();
4745 for (
unsigned i = 0; i < faceCount; ++i) {
4747 for (
unsigned char j = 0; j < 3; ++j) {
constexpr float ZERO_TOLERANCE_F
constexpr unsigned char POINT_HIDDEN
constexpr double ZERO_TOLERANCE_D
Tuple3Tpl< int > Tuple3i
Tuple of 3 int values.
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
float PointCoordinateType
Type of the coordinates of a (N-D) point.
virtual void link()
Increase counter.
virtual void release()
Decrease counter and deletes object when 0.
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 PrintVerbose(const char *format,...)
Prints out a verbose formatted message in console.
static bool Error(const char *format,...)
Display an error dialog with formatted message.
Array of RGB colors for each point.
Array of compressed 3D normals (single index)
NormsIndexesTableType * clone() override
Duplicates array (overloaded from ccArray::clone)
Array of 2D texture coordinates.
TextureCoordsContainer * clone() override
Duplicates array (overloaded from ccArray::clone)
void normalize()
Sets vector norm to unity.
Type dot(const Vector3Tpl &v) const
Dot product.
Vector3Tpl orthogonal() const
Returns a normalized vector which is orthogonal to this one.
Vector3Tpl< PointCoordinateType > toPC() const
Vector3Tpl cross(const Vector3Tpl &v) const
Cross product.
Vector3Tpl< double > toDouble() const
Cast operator to a double vector (explicit call version)
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
Shareable array that can be properly inserted in the DB tree.
Type & getValue(size_t index)
bool isAllocated() const
Returns whether some memory has been allocated or not.
bool resizeSafe(size_t count, bool initNewElements=false, const Type *valueForNewElements=nullptr)
Resizes memory (no exception thrown)
bool reserveSafe(size_t count)
Reserves memory (no exception thrown)
void setValue(size_t index, const Type &value)
void swap(size_t i1, size_t i2)
bool copy(Base &dest) const
Copies the content of this array in another one.
void clear(bool releaseMemory=false)
static ccBBox CreateFromPoints(const std::vector< CCVector3 > &points)
QSharedPointer< ccColorScale > Shared
Shared pointer type.
virtual bool colorsShown() const
Returns whether colors are shown or not.
virtual bool isVisible() const
Returns whether entity is visible or not.
virtual bool hasDisplayedScalarField() const
Returns whether an active scalar field is available or not.
virtual bool hasColors() const
Returns whether colors are enabled or not.
virtual void setVisible(bool state)
Sets entity visibility.
virtual bool sfShown() const
Returns whether active scalar field is visible.
virtual bool normalsShown() const
Returns whether normals are shown or not.
virtual bool hasNormals() const
Returns whether normals are enabled or not.
virtual bool isColorOverridden() const
virtual void showNormals(bool state)
Sets normals visibility.
virtual void showColors(bool state)
Sets colors visibility.
virtual void showSF(bool state)
Sets active scalarfield visibility.
virtual bool hasScalarFields() const
Returns whether one or more scalar fields are instantiated.
bool m_normalsDisplayed
Specifies whether normals should be displayed.
virtual void getDrawingParameters(glDrawParams ¶ms) const
Returns main OpenGL parameters for this entity.
ecvColor::Rgb m_tempColor
Temporary (unique) color.
static ccGLMatrixTpl< float > FromEigenMatrix(const Eigen::Matrix< double, 4, 4 > &mat)
void applyRotation(Vector3Tpl< float > &vec) const
Applies rotation only to a 3D vector (in place) - float version.
void shiftRotationCenter(const Vector3Tpl< T > &vec)
Shifts rotation center.
void setRotation(const float Rt[9])
Sets Rotation from a float array.
Float version of ccGLMatrixTpl.
virtual void showPoints(bool state)
virtual bool materialsShown() const
Sets whether textures/material should be displayed or not.
void showNormals(bool state) override
Sets normals visibility.
void importParametersFrom(const ccGenericMesh *mesh)
Imports the parameters from another mesh.
virtual void showWired(bool state)
Sets whether mesh should be displayed as a wire or with plain facets.
bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads own object data.
virtual bool triNormsShown() const
Returns whether per-triangle normals are shown or not.
virtual bool isShownAsWire() const
Returns whether the mesh is displayed as wired or with plain facets.
short minimumFileVersion_MeOnly() const override
void enableStippling(bool state)
Enables polygon stippling.
virtual void showMaterials(bool state)
Sets whether textures should be displayed or not.
virtual bool isShownAsPoints() const
Returns whether the mesh is displayed as wired or with plain facets.
void handleColorRamp(CC_DRAW_CONTEXT &context)
Handles the color ramp display.
bool toFile_MeOnly(QFile &out, short dataVersion) const override
Save own object data.
virtual bool stipplingEnabled() const
Returns whether polygon stippling is enabled or not.
virtual void showTriNorms(bool state)
Sets whether to show or not per-triangle normals.
A 3D cloud interface with associated features (color, normals, octree, etc.)
virtual const CCVector3 & getPointNormal(unsigned pointIndex) const =0
Returns normal corresponding to a given point.
virtual ccGenericPointCloud * createNewCloudFromVisibilitySelection(bool removeSelectedPoints=false, VisibilityTableType *visTable=nullptr, std::vector< int > *newIndexesOfRemainingPoints=nullptr, bool silent=false, cloudViewer::ReferenceCloud *selection=nullptr)=0
virtual const ecvColor::Rgb & getPointColor(unsigned pointIndex) const =0
Returns color corresponding to a given point.
virtual VisibilityTableType & getTheVisibilityArray()
Returns associated visibility array.
virtual ccGenericPointCloud * clone(ccGenericPointCloud *destCloud=nullptr, bool ignoreChildren=false)=0
Clones this entity.
std::vector< unsigned char > VisibilityTableType
Array of "visibility" information for each point.
virtual bool removeVisiblePoints(VisibilityTableType *visTable=nullptr, std::vector< int > *newIndexes=nullptr)=0
Removes all the 'visible' points (as defined by the visibility array)
virtual void unallocateVisibilityArray()
Erases the points visibility information.
static bool CloneChildren(const ccHObject *sourceEntity, ccHObject *destEntity, std::vector< int > *newPointOrTriangleIndex=nullptr, const ccHObject *sourceEntityProxy=nullptr, ccHObject *destEntityProxy=nullptr)
static ccPointCloud * ToPointCloud(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccPointCloud.
Hierarchical CLOUDVIEWER Object.
virtual void notifyGeometryUpdate()
static Eigen::Vector3d ComputeMinBound(const std::vector< Eigen::Vector3d > &points)
Compute min bound of a list points.
virtual const ccGLMatrix & getGLTransformationHistory() const
Returns the transformation 'history' matrix.
ccGLMatrix m_glTransHistory
Cumulative GL transformation.
int getChildIndex(const ccHObject *aChild) const
Returns child index.
static Eigen::Vector3d ComputeCenter(const std::vector< Eigen::Vector3d > &points)
Computer center of a list of points.
virtual void onUpdateOf(ccHObject *obj)
This method is called when another object (geometry) is updated.
void addDependency(ccHObject *otherObject, int flags, bool additive=true)
Adds a new dependence (additive or not)
unsigned getChildrenNumber() const
Returns the number of children.
virtual void applyGLTransformation(const ccGLMatrix &trans)
Applies a GL transformation to the entity.
@ DP_NOTIFY_OTHER_ON_DELETE
@ DP_NOTIFY_OTHER_ON_UPDATE
ccHObject * getParent() const
Returns parent object.
ccHObject * m_parent
Parent.
void removeChild(ccHObject *child)
unsigned filterChildren(Container &filteredChildren, bool recursive=false, CV_CLASS_ENUM filter=CV_TYPES::OBJECT, bool strict=false) const
Collects the children corresponding to a certain pattern.
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
virtual void onDeletionOf(const ccHObject *obj)
This method is called when another object is deleted.
std::vector< ccHObject * > Container
Standard instances container (for children, etc.)
static Eigen::Vector3d ComputeMaxBound(const std::vector< Eigen::Vector3d > &points)
Compute max bound of a list points.
Mesh (triangle) material.
int addMaterial(ccMaterial::CShared mat, bool allowDuplicateNames=false)
Adds a material.
ccMaterialSet * clone() const
Clones materials set.
QSharedPointer< const ccMaterial > CShared
Const + Shared type.
bool interpolateNormalsBC(unsigned triIndex, const CCVector3d &w, CCVector3 &N) override
Interpolates normal(s) inside a given triangle.
ccMesh * cloneMesh(ccGenericPointCloud *vertices=nullptr, ccMaterialSet *clonedMaterials=nullptr, NormsIndexesTableType *clonedNormsTable=nullptr, TextureCoordsContainer *cloneTexCoords=nullptr)
Clones this entity.
void getTriangleTexCoordinatesIndexes(unsigned triangleIndex, int &i1, int &i2, int &i3) const override
Returns the triplet of tex coords indexes for a given triangle.
cloudViewer::VerticesIndexes * getNextTriangleVertIndexes() override
virtual void showNormals_extended(bool p)
ccMaterialSet * m_materials
Materials.
const ccMaterialSet * getMaterialSet() const override
std::vector< Eigen::Vector3d > getTriangleNorms() const
std::vector< Eigen::Vector3d > getVertexColors() const
bool merge(const ccMesh *mesh, bool createSubMesh)
Merges another mesh into this one.
cloudViewer::GenericTriangle * _getNextTriangle() override
Returns the next triangle (relatively to the global iterator position)
void addEigenVertices(const std::vector< Eigen::Vector3d > &vertices)
void getTriangleNormalIndexes(unsigned triangleIndex, int &i1, int &i2, int &i3) const override
Returns a triplet of normal indexes for a given triangle (if any)
static ccMesh * Triangulate(ccGenericPointCloud *cloud, cloudViewer::TRIANGULATION_TYPES type, bool updateNormals=false, PointCoordinateType maxEdgeLength=0, unsigned char dim=2)
Creates a Delaunay 2.5D mesh from a point cloud.
virtual ecvOrientedBBox GetOrientedBoundingBox() const override
void drawMeOnly(CC_DRAW_CONTEXT &context) override
Enables (OpenGL) stipple mask.
bool hasMaterials() const override
bool hasDisplayedScalarField() const override
Returns whether an active scalar field is available or not.
void invertPerTriangleNormals()
Invert per-triangle normals.
virtual ccMesh & Scale(const double s, const Eigen::Vector3d ¢er) override
Apply scaling to the geometry coordinates. Given a scaling factor , and center , a given point is tr...
void applyGLTransformation(const ccGLMatrix &trans) override
Applies a GL transformation to the entity.
ccMesh & operator=(const ccMesh &mesh)
bool laplacianSmooth(unsigned nbIteration=100, PointCoordinateType factor=static_cast< PointCoordinateType >(0.01), ecvProgressDialog *progressCb=nullptr)
Laplacian smoothing.
virtual Eigen::Vector3d GetMaxBound() const override
Returns max bounds for geometry coordinates.
bool normalsShown() const override
Returns whether normals are shown or not.
ccMesh operator+(const ccMesh &mesh) const
bool reservePerTriangleMtlIndexes()
Reserves memory to store per-triangle material index.
void flipTriangles()
Flips the triangle.
void setTriangleMtlIndexesTable(triangleMaterialIndexesSet *matIndexesTable, bool autoReleaseOldTable=true)
Sets per-triangle material indexes array.
void setVertexNormal(size_t index, const Eigen::Vector3d &normal)
bool processScalarField(MESH_SCALAR_FIELD_PROCESS process)
ccMesh * subdivide(PointCoordinateType maxArea) const
ccGenericPointCloud * m_associatedCloud
associated cloud (vertices)
bool setTriangleNorm(size_t index, const Eigen::Vector3d &triangle_normal)
triangleMaterialIndexesSet * m_triMtlIndexes
Per-triangle material indexes.
void removePerTriangleNormalIndexes()
Removes any per-triangle triplets of normal indexes.
std::vector< int > triangle_material_ids_
List of material ids.
triangleTexCoordIndexesSet * m_texCoordIndexes
Mesh tex coords indexes (per-triangle)
bool convertMaterialsToVertexColors()
Converts materials to vertex colors.
short minimumFileVersion_MeOnly() const override
void addVertice(const Eigen::Vector3d &vertice)
bool toFile_MeOnly(QFile &out, short dataVersion) const override
Save own object data.
virtual unsigned size() const override
Returns the number of triangles.
void setTriangle(size_t index, const Eigen::Vector3i &triangle)
ccMesh(ccGenericPointCloud *vertices=nullptr)
Default ccMesh constructor.
void getTriangleTexCoordinates(unsigned triIndex, TexCoords2D *&tx1, TexCoords2D *&tx2, TexCoords2D *&tx3) const override
Returns per-triangle texture coordinates (pointer to)
void setTriNormsTable(NormsIndexesTableType *triNormsTable, bool autoReleaseOldTable=true)
Sets per-triangle normals array (may be shared)
std::vector< Eigen::Vector2d > triangle_uvs_
List of uv coordinates per triangle.
void transformTriNormals(const ccGLMatrix &trans)
Transforms the mesh per-triangle normals.
void swapTriangles(unsigned index1, unsigned index2)
Swaps two triangles.
Eigen::Vector3d getTriangleNorm(size_t index) const
ccBBox m_bBox
Bounding-box.
bool HasVertexNormals() const
bool hasColors() const override
Returns whether colors are enabled or not.
MESH_SCALAR_FIELD_PROCESS
Mesh scalar field processes.
bool getColorFromMaterial(unsigned triIndex, const CCVector3 &P, ecvColor::Rgb &C, bool interpolateColorIfNoTexture) override
const ccGLMatrix & getGLTransformationHistory() const override
Returns the transformation 'history' matrix.
bool pushSubdivide(unsigned indexA, unsigned indexB, unsigned indexC)
Used internally by 'subdivide'.
void setAssociatedCloud(ccGenericPointCloud *cloud)
Sets the associated vertices cloud (warning)
ccArray< Tuple3i, 3, int > triangleNormalsIndexesSet
Set of triplets of indexes referring to mesh normals.
std::vector< std::unordered_set< int > > adjacency_list_
void addTriangleMtlIndex(int mtlIndex)
Adds triangle material index for next triangle.
void setTriangleMtlIndex(unsigned triangleIndex, int mtlIndex)
Sets triangle material indexes.
unsigned m_globalIterator
Iterator on the list of triangles.
void clearTriNormals()
Removes per-triangle normals.
bool computePerTriangleNormals()
Computes per-triangle normals.
void setEigenVertices(const std::vector< Eigen::Vector3d > &vertices)
const std::vector< CCVector3 > & getVertices() const
void setMaterialSet(ccMaterialSet *materialSet, bool autoReleaseOldMaterialSet=true)
Sets associated material set (may be shared)
void setTriangles(const std::vector< Eigen::Vector3i > &triangles)
bool reserve(std::size_t n)
Reserves the memory to store the vertex indexes (3 per triangle)
ccGenericPointCloud * getAssociatedCloud() const override
Returns the vertices cloud.
void shiftTriangleIndexes(unsigned shift)
Shifts all triangles indexes.
void addVertexColors(const std::vector< Eigen::Vector3d > &colors)
std::shared_ptr< ccMesh > Crop(const ccBBox &bbox) const
void addVertexNormal(const Eigen::Vector3d &normal)
void addTriangleTexCoordIndexes(int i1, int i2, int i3)
Adds a triplet of tex coords indexes for next triangle.
NormsIndexesTableType * m_triNormals
Per-triangle normals.
triangleNormalsIndexesSet * m_triNormalIndexes
Mesh normals indexes (per-triangle)
static ccMesh * TriangulateTwoPolylines(ccPolyline *p1, ccPolyline *p2, CCVector3 *projectionDir=nullptr)
Creates a Delaunay 2.5D mesh from two polylines.
bool hasTextures() const override
Returns whether textures are available for this mesh.
ccMesh & operator+=(const ccMesh &mesh)
bool setTriangleNormalIndexes(size_t triangleIndex, CompressedNormType value)
void setVertexNormals(const std::vector< Eigen::Vector3d > &normals)
Eigen::Vector3d getVertice(size_t index) const
bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads own object data.
ccArray< Tuple3i, 3, int > triangleTexCoordIndexesSet
Set of triplets of indexes referring to mesh texture coordinates.
unsigned getUniqueIDForDisplay() const override
Returns object unqiue ID used for display.
void placeIteratorAtBeginning() override
Places the mesh iterator at the beginning.
void addTriangle(unsigned i1, unsigned i2, unsigned i3)
Adds a triangle to the mesh.
virtual ccBBox GetAxisAlignedBoundingBox() const override
Returns an axis-aligned bounding box of the geometry.
void removePerTriangleTexCoordIndexes()
Remove per-triangle tex coords indexes.
virtual void getTriangleVertices(unsigned triangleIndex, CCVector3 &A, CCVector3 &B, CCVector3 &C) const override
Returns the vertices of a given triangle.
bool reservePerTriangleNormalIndexes()
Reserves memory to store per-triangle triplets of normal indexes.
bool hasPerTriangleTexCoordIndexes() const override
Returns whether this mesh as per-triangle triplets of tex coords indexes.
void setTexCoordinatesTable(TextureCoordsContainer *texCoordsTable, bool autoReleaseOldTable=true)
Sets per-triangle texture coordinates array (may be shared)
bool interpolateNormals(unsigned triIndex, const CCVector3 &P, CCVector3 &N) override
Interpolates normal(s) inside a given triangle.
std::vector< Eigen::Vector3i > getTriangles() const
std::vector< Eigen::Vector3d > getEigenVertices() const
unsigned int getVerticeSize() const
void removeTriangles(size_t index)
TextureCoordsContainer * m_texCoords
Texture coordinates.
std::vector< CCVector3 > & getVerticesPtr()
bool resize(size_t n)
Resizes the array of vertex indexes (3 per triangle)
void setVertexColors(const std::vector< Eigen::Vector3d > &colors)
Eigen::Vector3d getVertexColor(size_t index) const
bool resizeAssociatedCloud(std::size_t n)
bool arePerTriangleNormalsEnabled() const
Returns whether per triangle normals are enabled.
cloudViewer::SimpleRefTriangle m_currentTriangle
Dump triangle structure to transmit temporary data.
std::vector< Eigen::Vector3d > getVertexNormals() const
ccArray< cloudViewer::VerticesIndexes, 3, unsigned > triangleIndexesContainer
Container of per-triangle vertices indexes (3)
void addTriangleNormalIndexes(int i1, int i2, int i3)
Adds a triplet of normal indexes for next triangle.
std::vector< Eigen::Vector3d > getTriangleNormals() const
void getTexCoordinates(unsigned index, TexCoords2D *&tx) const override
bool reserveAssociatedCloud(std::size_t n, bool init_color=false, bool init_normal=false)
bool reservePerTriangleTexCoordIndexes()
Reserves memory to store per-triangle triplets of tex coords indexes.
void setVertexColor(size_t index, const Eigen::Vector3d &color)
ccBBox getOwnBB(bool withGLFeatures=false) override
Returns the entity's own bounding-box.
bool getVertexColorFromMaterial(unsigned triIndex, unsigned char vertIndex, ecvColor::Rgb &C, bool returnColorIfNoTexture) override
bool hasNormals() const override
Returns whether normals are enabled or not.
bool computePerVertexNormals()
Computes per-vertex normals.
void refreshBB() override
Forces bounding-box update.
bool hasScalarFields() const override
Returns whether one or more scalar fields are instantiated.
ccMesh * createNewMeshFromSelection(bool removeSelectedTriangles, std::vector< int > *newIndexesOfRemainingTriangles=nullptr, bool withChildEntities=false)
Creates a new mesh with the selected vertices only.
void onDeletionOf(const ccHObject *obj) override
This method is called when another object is deleted.
void computeInterpolationWeights(unsigned triIndex, const CCVector3 &P, CCVector3d &weights) const override
Returns the (barycentric) interpolation weights for a given triangle.
~ccMesh() override
Default destructor.
std::shared_ptr< ccMesh > SelectByIndex(const std::vector< size_t > &indices, bool cleanup=true) const
void setTriangleTexCoordIndexes(unsigned triangleIndex, int i1, int i2, int i3)
Sets a triplet of tex coords indexes for a given triangle.
Eigen::Vector3i getTriangle(size_t index) const
virtual ccMesh & Translate(const Eigen::Vector3d &translation, bool relative=true) override
Apply translation to the geometry coordinates.
void removePerTriangleMtlIndexes()
Removes any per-triangle material indexes.
bool setTriangleNorms(const std::vector< Eigen::Vector3d > &triangle_normals)
void forEach(genericTriangleAction action) override
Fast iteration mechanism.
int getTriangleMtlIndex(unsigned triangleIndex) const override
Returns a given triangle material indexes.
void setVertice(size_t index, const Eigen::Vector3d &vertice)
bool HasTriangleNormals() const
virtual ccMesh & Rotate(const Eigen::Matrix3d &R, const Eigen::Vector3d ¢er) override
Apply rotation to the geometry coordinates and normals. Given a rotation matrix , and center ,...
std::vector< cloudViewer::geometry::Image > textures_
Textures of the image.
ccMesh * partialClone(const std::vector< unsigned > &triangleIndices, int *warnings=nullptr) const
Creates a new mesh from a selection of triangles (partial clone)
bool addTriangleNorm(const CCVector3 &N)
std::vector< CCVector3 * > getTriangleNormalsPtr() const
virtual Eigen::Vector3d GetMinBound() const override
Returns min bounds for geometry coordinates.
bool mergeDuplicatedVertices(unsigned char octreeLevel=DefaultMergeDulicateVerticesLevel, QWidget *parentWidget=nullptr)
Merges duplicated vertices.
void getBoundingBox(CCVector3 &bbMin, CCVector3 &bbMax) override
Returns the mesh bounding-box.
virtual Eigen::Vector3d GetCenter() const override
Returns the center of the geometry coordinates.
Eigen::Vector3d getVertexNormal(size_t index) const
cloudViewer::GenericTriangle * _getTriangle(unsigned triangleIndex) override
Returns the ith triangle.
void onUpdateOf(ccHObject *obj) override
This method is called when another object (geometry) is updated.
void addVertexNormals(const std::vector< Eigen::Vector3d > &normals)
void shrinkToFit()
Removes unused capacity.
std::vector< std::pair< std::string, Material > > materials_
void addVertexColor(const Eigen::Vector3d &color)
virtual ccMesh & Transform(const Eigen::Matrix4d &transformation) override
Apply transformation (4x4 matrix) to the geometry coordinates.
bool addTriangleNorms(const std::vector< Eigen::Vector3d > &triangle_normals)
unsigned capacity() const override
Returns max capacity.
ccArray< int, 1, int > triangleMaterialIndexesSet
Container of per-triangle material descriptors.
bool hasPerTriangleMtlIndexes() const
Returns whether this mesh as per-triangle material index.
void invertNormals()
Inverts normals (if any)
bool hasTriangleUvs() const
bool computeNormals(bool perVertex)
Computes normals.
ColorsTableType * getVertexColorsPtr()
bool hasTriNormals() const override
Returns whether the mesh has per-triangle normals.
cloudViewer::VerticesIndexes * getTriangleVertIndexes(unsigned triangleIndex) override
Returns the indexes of the vertices of a given triangle.
triangleIndexesContainer * m_triVertIndexes
Triangles' vertices indexes (3 per triangle)
bool interpolateColors(unsigned triIndex, const CCVector3 &P, ecvColor::Rgb &C) override
Interpolates RGB colors inside a given triangle.
static void InvertNormal(CompressedNormType &code)
Inverts a (compressed) normal.
const CCVector3 & getNormal(unsigned normIndex) const
Returns the precomputed normal corresponding to a given compressed index.
static const CCVector3 & GetNormal(unsigned normIndex)
Static access to ccNormalVectors::getNormal.
static unsigned GetNumberOfVectors()
Returns the number of compressed normal vectors.
static ccNormalVectors * GetUniqueInstance()
Returns unique instance.
static CompressedNormType GetNormIndex(const PointCoordinateType N[])
Returns the compressed index corresponding to a normal vector.
virtual void setLocked(bool state)
Sets the "enabled" property.
virtual QString getName() const
Returns object name.
virtual unsigned getUniqueID() const
Returns object unique ID.
bool isA(CV_CLASS_ENUM type) const
virtual void setName(const QString &name)
Sets object name.
virtual void setEnabled(bool state)
Sets the "enabled" property.
virtual bool isEnabled() const
Returns whether the object is enabled or not.
bool isKindOf(CV_CLASS_ENUM type) const
QString m_name
Object name.
QSharedPointer< ccOctree > Shared
Shared pointer.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void addEigenNorm(const Eigen::Vector3d &N)
std::vector< Eigen::Vector3d > getEigenNormals() const
ColorsTableType * rgbColors() const
Returns pointer on RGB colors table.
bool resizeTheNormsTable()
Resizes the compressed normals array.
void addEigenColor(const Eigen::Vector3d &color)
void addEigenNorms(const std::vector< Eigen::Vector3d > &normals)
void setEigenColors(const std::vector< Eigen::Vector3d > &colors)
Eigen::Vector3d getEigenNormal(size_t index) const
void addNorm(const CCVector3 &N)
Pushes a normal vector on stack (shortcut)
ccScalarField * getCurrentDisplayedScalarField() const
Returns the currently displayed scalar (or 0 if none)
bool hasNormals() const override
Returns whether normals are enabled or not.
bool resizeTheRGBTable(bool fillWithWhite=false)
Resizes the RGB colors array.
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
virtual ccPointCloud & Translate(const Eigen::Vector3d &translation, bool relative=true) override
Apply translation to the geometry coordinates.
static ccPointCloud * From(const cloudViewer::GenericIndexedCloud *cloud, const ccGenericPointCloud *sourceCloud=nullptr)
Creates a new point cloud object from a GenericIndexedCloud.
void setEigenNormals(const std::vector< Eigen::Vector3d > &normals)
bool reserveTheNormsTable()
Reserves memory to store the compressed normals.
virtual ccPointCloud & Scale(const double s, const Eigen::Vector3d ¢er) override
Apply scaling to the geometry coordinates. Given a scaling factor , and center , a given point is tr...
bool reserveTheRGBTable()
Reserves memory to store the RGB colors.
void clear() override
Clears the entity from all its points and features.
virtual void applyRigidTransformation(const ccGLMatrix &trans) override
Applies a rigid transformation (rotation + translation)
bool hasColors() const override
Returns whether colors are enabled or not.
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.
void setPointNormal(size_t pointIndex, const CCVector3 &N)
Sets a particular point normal (shortcut)
Eigen::Vector3d getEigenColor(size_t index) const
void addEigenColors(const std::vector< Eigen::Vector3d > &colors)
void shrinkToFit()
Removes unused capacity.
void addRGBColor(const ecvColor::Rgb &C)
Pushes an RGB color on stack.
bool reserveThePointsTable(unsigned _numberOfPoints)
Reserves memory to store the points coordinates.
std::vector< Eigen::Vector3d > getEigenColors() const
void invertNormals()
Inverts normals (if any)
unsigned segmentCount() const
Returns the number of segments.
bool areNaNValuesShownInGrey() const
Returns whether NaN values are displayed in gray or hidden.
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.
static short GenericArrayToFileMinVersion()
Returns the minimum file version to save/load a 'generic array'.
virtual void setGlobalShift(double x, double y, double z)
Sets shift applied to original coordinates (information storage only)
virtual const CCVector3d & getGlobalShift() const
Returns the shift applied to original coordinates.
virtual void setGlobalScale(double scale)
virtual double getGlobalScale() const
Returns the scale applied to original coordinates.
void setAssociatedMesh(ccMesh *mesh, bool unlinkPreviousOne=true)
Sets the associated mesh.
std::vector< unsigned int > IndexMap
Indexes map for createNewSubMeshFromSelection.
ccSubMesh * createNewSubMeshFromSelection(bool removeSelectedTriangles, const std::vector< int > &selectedTriangleIndexes, IndexMap *newRemainingTriangleIndexes=nullptr)
Creates a new sub mesh with the visible vertices only.
unsigned size() const override
Returns the number of triangles.
bool reserve(size_t n)
Reserves some memory for hosting the triangle references.
bool addTriangleIndex(unsigned globalIndex)
Triangle global index insertion mechanism.
std::vector< std::size_t > GetPointIndicesWithinBoundingBox(const std::vector< Eigen::Vector3d > &points) const
const Vector3Tpl< T > & maxCorner() const
Returns max corner (const)
void setValidity(bool state)
Sets bonding box validity.
void clear()
Resets the bounding box.
const Vector3Tpl< T > & minCorner() const
Returns min corner (const)
bool isValid() const
Returns whether bounding box is valid or not.
void add(const Vector3Tpl< T > &P)
'Enlarges' the bounding box with a point
A class to compute and handle a Delaunay 2D mesh on a subset of points.
virtual unsigned size() const override
Returns the number of triangles.
virtual bool removeOuterTriangles(const std::vector< CCVector2 > &vertices2D, const std::vector< CCVector2 > &polygon2D, bool removeOutside=true)
Removes the triangles falling outside of a given (2D) polygon.
virtual bool buildMesh(const std::vector< CCVector2 > &points2D, std::size_t pointCountToUse, std::string &outputErrorStr)
Build the Delaunay mesh on top a set of 2D points.
virtual void linkMeshWith(GenericIndexedCloud *aCloud, bool passOwnership=false)
Associate this mesh to a point cloud.
void getCellPos(CellCode code, unsigned char level, Tuple3i &cellPos, bool isCodeTruncated) const
int findNeighborsInASphereStartingFromCell(NearestNeighboursSearchStruct &nNSS, double radius, bool sortValues=true) const
Advanced form of the nearest neighbours search algorithm (in a sphere)
const PointCoordinateType & getCellSize(unsigned char level) const
Returns the octree cells length for a given level of subdivision.
void computeCellCenter(CellCode code, unsigned char level, CCVector3 ¢er, bool isCodeTruncated=false) const
unsigned executeFunctionForAllCellsAtLevel(unsigned char level, octreeCellFunc func, void **additionalParameters, bool multiThread=false, GenericProgressCallback *progressCb=nullptr, const char *functionTitle=nullptr, int maxThreadCount=0)
int build(GenericProgressCallback *progressCb=nullptr)
Builds the structure.
virtual unsigned size() const =0
Returns the number of points.
virtual ScalarType getPointScalarValue(unsigned pointIndex) const =0
Returns the ith point associated scalar value.
virtual bool hasPoints() const
virtual void setPointScalarValue(unsigned pointIndex, ScalarType value)=0
Sets the ith point associated scalar value.
virtual bool isScalarFieldEnabled() const =0
Returns true if the scalar field is enabled, false otherwise.
virtual const CCVector3 * getPointPersistentPtr(unsigned index)=0
Returns the ith point as a persistent pointer.
virtual const CCVector3 * getPoint(unsigned index) const =0
Returns the ith point.
A generic mesh with index-based vertex access.
virtual VerticesIndexes * getNextTriangleVertIndexes()=0
virtual unsigned size() const =0
Returns the number of triangles.
std::function< void(GenericTriangle &)> genericTriangleAction
Generic function to apply to a triangle (used by foreach)
virtual void placeIteratorAtBeginning()=0
Places the mesh iterator at the beginning.
virtual bool hasTriangles() const
A generic triangle interface.
const CCVector3 * getLSPlaneY()
Returns best interpolating plane (Least-square) 'Y' base vector.
const PointCoordinateType * getLSPlane()
Returns best interpolating plane equation (Least-square)
const CCVector3 * getGravityCenter()
Returns gravity center.
const CCVector3 * getLSPlaneX()
Returns best interpolating plane (Least-square) 'X' base vector.
bool oneStep()
Increments total progress value of a single unit.
std::vector< size_t > GetPointIndicesWithinBoundingBox(const std::vector< Eigen::Vector3d > &points) const
Return indices to points that are within the bounding box.
void setEigenPoints(const std::vector< Eigen::Vector3d > &points)
void addEigenPoint(const Eigen::Vector3d &point)
std::vector< CCVector3 > & getPoints()
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
unsigned size() const override
void setEigenPoint(size_t index, const Eigen::Vector3d &point)
std::vector< Eigen::Vector3d > getEigenPoints() const
unsigned capacity() const
Returns cloud capacity (i.e. reserved size)
Eigen::Vector3d getEigenPoint(size_t index) const
const CCVector3 * getPoint(unsigned index) const override
void addPoints(const std::vector< CCVector3 > &points)
bool isClosed() const
Returns whether the polyline is closed or not.
A very simple point cloud (no point duplication)
virtual bool addPointIndex(unsigned globalIndex)
Point global index insertion mechanism.
unsigned size() const override
Returns the number of points.
virtual unsigned getPointGlobalIndex(unsigned localIndex) const
const CCVector3 * getPointPersistentPtr(unsigned index) override
Returns the ith point as a persistent pointer.
virtual bool reserve(unsigned n)
Reserves some memory for hosting the point references.
const CCVector3 * getPoint(unsigned index) const override
Returns the ith point.
const CCVector3 * B
B vertex (ref)
const CCVector3 * C
C vertex (ref)
const CCVector3 * A
A vertex (ref)
virtual bool IsEmpty() const override
static ecvOrientedBBox CreateFromPoints(const std::vector< Eigen::Vector3d > &points)
Graphical progress indicator (thread-safe)
virtual void setInfo(const char *infoStr) override
Notifies some information about the ongoing process.
virtual void start() override
virtual void setMethodTitle(const char *methodTitle) override
Notifies the algorithm title.
unsigned int CompressedNormType
Compressed normals type.
unsigned char ColorCompType
Default color components type (R,G and B)
#define MACRO_Draw3D(context)
#define MACRO_LightIsEnabled(context)
#define MACRO_FastEntityPicking(context)
#define MACRO_EntityPicking(context)
#define MACRO_LODActivated(context)
static qint64 GenerateKey(unsigned edgeIndex1, unsigned edgeIndex2)
static bool TagDuplicatedVertices(const cloudViewer::DgmOctree::octreeCell &cell, void **additionalParameters, cloudViewer::NormalizedProgress *nProgress)
static const unsigned s_defaultSubdivideGrowRate
static QMap< qint64, unsigned > s_alreadyCreatedVertices
static CCVector3 s_blankNorm(0, 0, 0)
static PointCoordinateType s_maxSubdivideArea
MiniVec< float, N > floor(const MiniVec< float, N > &a)
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
TRIANGULATION_TYPES
Triangulation types.
bool LessThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
RgbTpl< ColorCompType > Rgb
3 components, default type
Rgb FromRgbafToRgb(const Rgbaf &color)
Conversion from Rgbaf.
constexpr ColorCompType MAX
Max value of a single color component (default type)
constexpr Rgb lightGrey(static_cast< ColorCompType >(MAX *0.8), static_cast< ColorCompType >(MAX *0.8), static_cast< ColorCompType >(MAX *0.8))
Rgb FromQRgb(QRgb qColor)
Conversion from QRgb.
Eigen::Matrix< Index, 3, 1 > Vector3i
void swap(cloudViewer::core::SmallVectorImpl< T > &LHS, cloudViewer::core::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
ReferenceCloud * points
Set of points lying inside this cell.
const DgmOctree * parentOctree
Octree to which the cell belongs.
unsigned char level
Cell level of subdivision.
CellCode truncatedCode
Truncated cell code.
Triangle described by the indexes of its 3 vertices.
Display parameters of a 3D entity.
bool showColors
Display colors.
bool showNorms
Display normals.
bool showSF
Display scalar field (prioritary on colors)