ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ecvSubMesh.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "ecvSubMesh.h"
9 
10 // Local
11 #include "ecvGenericPointCloud.h"
12 #include "ecvMesh.h"
13 
14 // Qt
15 #include <QString>
16 
17 // cloudViewer
19 
20 // system
21 #include <cassert>
22 #include <cstring>
23 
25  : ccGenericMesh("Sub-mesh"),
26  m_associatedMesh(nullptr),
27  m_globalIterator(0) {
29  parentMesh); // must be called so as to set the right dependency!
30 
31  showColors(parentMesh ? parentMesh->colorsShown() : true);
32  showNormals(parentMesh ? parentMesh->normalsShown() : true);
33  showSF(parentMesh ? parentMesh->sfShown() : true);
34 }
35 
37  bool unlinkPreviousOne /*=true*/) {
38  if (m_associatedMesh == mesh) return;
39 
40  if (m_associatedMesh && unlinkPreviousOne)
42 
43  m_associatedMesh = mesh;
44 
45  if (m_associatedMesh)
47 }
48 
50  if (obj == m_associatedMesh) m_bBox.setValidity(false);
51 }
52 
54  if (!m_associatedMesh) return;
55 
56  for (unsigned int index : m_triIndexes) {
59  action(*tri);
60  }
61 }
62 
65 }
66 
68 {
72  : nullptr;
73 }
74 
79  : nullptr;
80 }
81 
82 bool ccSubMesh::interpolateNormals(unsigned triIndex,
83  const CCVector3& P,
84  CCVector3& N) {
85  if (m_associatedMesh && triIndex < size())
87  P, N);
88 
89  // shouldn't happen
90  assert(false);
91  return false;
92 }
93 
94 bool ccSubMesh::interpolateNormalsBC(unsigned triIndex,
95  const CCVector3d& w,
96  CCVector3& N) {
97  if (m_associatedMesh && triIndex < size())
99  getTriGlobalIndex(triIndex), w, N);
100 
101  // shouldn't happen
102  assert(false);
103  return false;
104 }
105 
106 bool ccSubMesh::interpolateColors(unsigned triIndex,
107  const CCVector3& P,
108  ecvColor::Rgb& rgb) {
109  if (m_associatedMesh && triIndex < size())
111  P, rgb);
112 
113  // shouldn't happen
114  assert(false);
115  return false;
116 }
117 
118 bool ccSubMesh::getColorFromMaterial(unsigned triIndex,
119  const CCVector3& P,
121  bool interpolateColorIfNoTexture) {
122  if (m_associatedMesh && triIndex < size())
124  getTriGlobalIndex(triIndex), P, rgb,
125  interpolateColorIfNoTexture);
126 
127  // shouldn't happen
128  assert(false);
129  return false;
130 }
131 
133  unsigned char vertIndex,
135  bool returnColorIfNoTexture) {
136  if (m_associatedMesh && triIndex < size())
138  getTriGlobalIndex(triIndex), vertIndex, rgb,
139  returnColorIfNoTexture);
140 
141  // shouldn't happen
142  assert(false);
143  return false;
144 }
145 
147  unsigned triIndex) // temporary object
148 {
149  if (m_associatedMesh && triIndex < size())
151 
152  // shouldn't happen
153  assert(false);
154  return nullptr;
155 }
156 
157 void ccSubMesh::getTriangleVertices(unsigned triIndex,
158  CCVector3& A,
159  CCVector3& B,
160  CCVector3& C) const {
161  if (m_associatedMesh && triIndex < size()) {
163  C);
164  } else {
165  // shouldn't happen
166  assert(false);
167  }
168 }
169 
170 void ccSubMesh::getTriangleVertices(unsigned triangleIndex,
171  double A[3],
172  double B[3],
173  double C[3]) const {
174  if (m_associatedMesh && triangleIndex < size()) {
176  A, B, C);
177  } else {
178  // shouldn't happen
179  assert(false);
180  }
181 }
182 
184  unsigned triIndex) {
185  if (m_associatedMesh && triIndex < size())
187  getTriGlobalIndex(triIndex));
188 
189  // shouldn't happen
190  assert(false);
191  return nullptr;
192 }
193 
195  IndexMap* indexMap /*=0*/) {
197  assert(vertices && m_associatedMesh);
198  if (!vertices || !m_associatedMesh) {
199  return nullptr;
200  }
201 
202  const ccGenericPointCloud::VisibilityTableType& verticesVisibility =
203  vertices->getTheVisibilityArray();
204  if (verticesVisibility.size() < vertices->size()) {
205  CVLog::Error(QString("[Sub-mesh %1] Internal error: vertex visibility "
206  "table not instantiated!")
207  .arg(getName()));
208  return nullptr;
209  }
210 
211  // we count the number of remaining faces
212  size_t triNum = m_triIndexes.size();
213  size_t visibleFaces = 0;
214  {
215  for (unsigned globalIndex : m_triIndexes) {
216  const cloudViewer::VerticesIndexes* tsi =
218  // triangle is visible?
219  if (verticesVisibility[tsi->i1] == POINT_VISIBLE &&
220  verticesVisibility[tsi->i2] == POINT_VISIBLE &&
221  verticesVisibility[tsi->i3] == POINT_VISIBLE) {
222  ++visibleFaces;
223  }
224  }
225  }
226 
227  // nothing to do
228  if (visibleFaces == 0) {
229  if (indexMap) // we still have to translate global indexes!
230  {
231  for (unsigned& globalIndex : m_triIndexes) {
232  globalIndex = indexMap->at(globalIndex);
233  }
234  }
235  return nullptr;
236  }
237 
238  ccSubMesh* newSubMesh = new ccSubMesh(m_associatedMesh);
239  if (!newSubMesh->reserve(size())) {
240  CVLog::Error(
241  "[ccSubMesh::createNewSubMeshFromSelection] Not enough "
242  "memory!");
243  return nullptr;
244  }
245 
246  // create sub-mesh
247  {
248  unsigned lastTri = 0;
249  for (size_t i = 0; i < triNum; ++i) {
250  unsigned globalIndex = m_triIndexes[i];
251  const cloudViewer::VerticesIndexes* tsi =
253 
254  if (indexMap) // translate global index?
255  globalIndex = indexMap->at(globalIndex);
256 
257  // triangle is visible?
258  if (verticesVisibility[tsi->i1] == POINT_VISIBLE &&
259  verticesVisibility[tsi->i2] == POINT_VISIBLE &&
260  verticesVisibility[tsi->i3] == POINT_VISIBLE) {
261  newSubMesh->addTriangleIndex(globalIndex);
262  } else if (removeSelectedFaces) // triangle is not visible? It
263  // stays in the original mesh!
264  {
265  // we replace the current triangle by the 'last' valid one
266  assert(lastTri <= i);
267  m_triIndexes[lastTri++] = globalIndex;
268  }
269  }
270 
271  // resize original mesh
272  if (removeSelectedFaces && lastTri < triNum) {
273  resize(lastTri);
274  m_bBox.setValidity(false);
276  }
277  }
278 
279  if (newSubMesh->size()) {
280  newSubMesh->setName(getName() + QString(".part"));
281  newSubMesh->resize(newSubMesh->size());
282  // newSubMesh->setDisplay(getDisplay());
283  newSubMesh->showColors(colorsShown());
284  newSubMesh->showNormals(normalsShown());
285  newSubMesh->showMaterials(materialsShown());
286  newSubMesh->showSF(sfShown());
287  newSubMesh->enableStippling(stipplingEnabled());
288  newSubMesh->showWired(isShownAsWire());
289  } else {
290  assert(false);
291  delete newSubMesh;
292  newSubMesh = nullptr;
293  }
294 
295  return newSubMesh;
296 }
297 
299  bool removeSelectedTriangles,
300  const std::vector<int>& selectedTriangleIndexes,
301  IndexMap* newRemainingTriangleIndexes /*=nullptr*/) {
302  if (!m_associatedMesh) {
303  assert(false);
304  return nullptr;
305  }
306  if (selectedTriangleIndexes.size() < m_associatedMesh->size()) {
307  CVLog::Error(QString("[Sub-mesh %1] Internal error: input triangle "
308  "indexes vector size is invalid")
309  .arg(getName()));
310  return nullptr;
311  }
312 
313  // we count the number of selected triangles
314  size_t selectedTriangleCount = 0;
315  {
316  for (unsigned globalIndex : m_triIndexes) {
317  // triangle is selected?
318  if (selectedTriangleIndexes[globalIndex] >= 0) {
319  ++selectedTriangleCount;
320  }
321  }
322  }
323 
324  // nothing to do
325  if (selectedTriangleCount == 0) {
326  if (newRemainingTriangleIndexes) // we still have to translate global
327  // indexes!
328  {
329  for (unsigned& globalIndex : m_triIndexes) {
330  globalIndex = newRemainingTriangleIndexes->at(globalIndex);
331  }
332  }
333  return nullptr;
334  }
335 
336  ccSubMesh* newSubMesh = new ccSubMesh(m_associatedMesh);
337  if (!newSubMesh->reserve(size())) {
338  CVLog::Error(
339  "[ccSubMesh::createNewSubMeshFromSelection] Not enough "
340  "memory!");
341  return nullptr;
342  }
343 
344  // create sub-mesh
345  {
346  size_t triCount = m_triIndexes.size();
347 
348  unsigned lastTriIndex = 0;
349  for (size_t i = 0; i < triCount; ++i) {
350  unsigned globalIndex = m_triIndexes[i];
351  const cloudViewer::VerticesIndexes* tsi =
353 
354  // triangle is selected?
355  if (selectedTriangleIndexes[globalIndex] >= 0) {
356  newSubMesh->addTriangleIndex(static_cast<unsigned>(
357  selectedTriangleIndexes[globalIndex]));
358  } else if (removeSelectedTriangles) // triangle is not selected? It
359  // stays in the original mesh!
360  {
361  // we replace the 'last' valid triangle by this one
362  assert(lastTriIndex <= i);
363  m_triIndexes[lastTriIndex++] =
364  newRemainingTriangleIndexes
365  ? newRemainingTriangleIndexes->at(globalIndex)
366  : globalIndex;
367  }
368  }
369 
370  // resize original mesh
371  if (removeSelectedTriangles && lastTriIndex < triCount) {
372  resize(lastTriIndex); // can't fail, always smaller
373  m_bBox.setValidity(false);
375  }
376  }
377 
378  if (newSubMesh->size() != 0) {
379  newSubMesh->setName(getName() + QString(".part"));
380  newSubMesh->resize(newSubMesh->size());
381  newSubMesh->showColors(colorsShown());
382  newSubMesh->showNormals(normalsShown());
383  newSubMesh->showMaterials(materialsShown());
384  newSubMesh->showSF(sfShown());
385  newSubMesh->enableStippling(stipplingEnabled());
386  newSubMesh->showWired(isShownAsWire());
387  } else {
388  assert(false);
389  delete newSubMesh;
390  newSubMesh = nullptr;
391  }
392 
393  return newSubMesh;
394 }
395 
397  return (ccHObject::normalsShown() || triNormsShown());
398 }
399 
400 #define CC_SUB_MESH_TRANSIENT_CONST_TEST(method) \
401  bool ccSubMesh::method() const { \
402  return m_associatedMesh ? m_associatedMesh->method() : false; \
403  }
404 
408 CC_SUB_MESH_TRANSIENT_CONST_TEST(hasDisplayedScalarField);
412 
414  return m_associatedMesh ? m_associatedMesh->getMaterialSet() : nullptr;
415 }
416 
417 int ccSubMesh::getTriangleMtlIndex(unsigned triIndex) const {
419  getTriGlobalIndex(triIndex))
420  : -1;
421 }
422 
425  : nullptr;
426 }
427 
428 void ccSubMesh::getTexCoordinates(unsigned index, TexCoords2D*& tx) const {
429  if (m_associatedMesh) {
431  }
432 }
433 
435  TexCoords2D*& tx1,
436  TexCoords2D*& tx2,
437  TexCoords2D*& tx3) const {
438  if (m_associatedMesh && triIndex < size()) {
440  tx1, tx2, tx3);
441  } else {
442  // shouldn't happen
443  tx1 = tx2 = tx3 = nullptr;
444  assert(false);
445  }
446 }
447 
450  : false;
451 }
452 
454  int& i1,
455  int& i2,
456  int& i3) const {
457  if (m_associatedMesh && triangleIndex < size()) {
459  getTriGlobalIndex(triangleIndex), i1, i2, i3);
460  } else {
461  i1 = i2 = i3 = -1;
462  }
463 }
464 
465 void ccSubMesh::getTriangleNormalIndexes(unsigned triIndex,
466  int& i1,
467  int& i2,
468  int& i3) const {
469  if (m_associatedMesh && triIndex < size()) {
471  i1, i2, i3);
472  } else {
473  i1 = i2 = i3 = -1;
474  }
475 }
476 
477 bool ccSubMesh::getTriangleNormals(unsigned triIndex,
478  CCVector3& Na,
479  CCVector3& Nb,
480  CCVector3& Nc) const {
481  return (m_associatedMesh && triIndex < size()
483  getTriGlobalIndex(triIndex), Na, Nb, Nc)
484  : false);
485 }
486 
488  return m_associatedMesh ? m_associatedMesh->getTriNormsTable() : nullptr;
489 }
490 
491 void ccSubMesh::clear(bool releaseMemory) {
492  if (releaseMemory)
493  m_triIndexes.resize(0);
494  else
495  m_triIndexes.clear();
496  m_bBox.setValidity(false);
497 }
498 
499 bool ccSubMesh::addTriangleIndex(unsigned globalIndex) {
500  try {
501  m_triIndexes.emplace_back(globalIndex);
502  } catch (const std::bad_alloc&) {
503  // not engough memory
504  return false;
505  }
506 
507  m_bBox.setValidity(false);
508 
509  return true;
510 }
511 
512 bool ccSubMesh::addTriangleIndex(unsigned firstIndex, unsigned lastIndex) {
513  if (firstIndex >= lastIndex) {
514  assert(false);
515  return false;
516  }
517 
518  unsigned range = lastIndex - firstIndex; // lastIndex is excluded
519 
520  try {
521  m_triIndexes.reserve(m_triIndexes.size() + range);
522  } catch (const std::bad_alloc&) {
523  // not engough memory
524  return false;
525  }
526 
527  for (unsigned i = firstIndex; i < lastIndex; ++i) {
528  m_triIndexes.emplace_back(i);
529  }
530 
531  m_bBox.setValidity(false);
532 
533  return true;
534 }
535 
536 void ccSubMesh::setTriangleIndex(unsigned localIndex, unsigned globalIndex) {
537  assert(localIndex < size());
538  m_triIndexes[localIndex] = globalIndex;
539  m_bBox.setValidity(false);
540 }
541 
542 bool ccSubMesh::reserve(size_t n) {
543  try {
544  m_triIndexes.reserve(n);
545  } catch (const std::bad_alloc&) {
546  // not engough memory
547  return false;
548  }
549  return true;
550 }
551 
552 bool ccSubMesh::resize(size_t n) {
553  try {
554  m_triIndexes.resize(n);
555  } catch (const std::bad_alloc&) {
556  // not engough memory
557  return false;
558  }
559  return true;
560 }
561 
562 unsigned ccSubMesh::capacity() const {
563  return static_cast<unsigned>(m_triIndexes.capacity());
564 }
565 
567  m_bBox.clear();
568 
569  if (m_associatedMesh) {
570  for (unsigned globalIndex : m_triIndexes) {
572  m_associatedMesh->_getTriangle(globalIndex);
573  m_bBox.add(*tri->_getA());
574  m_bBox.add(*tri->_getB());
575  m_bBox.add(*tri->_getC());
576  }
577  }
578 
580 }
581 
582 ccBBox ccSubMesh::getOwnBB(bool withGLFeatures /*=false*/) {
583  // force BB refresh if necessary
584  if (!m_bBox.isValid() && size() != 0) {
585  refreshBB();
586  }
587 
588  return m_bBox;
589 }
590 
592  // force BB refresh if necessary
593  if (!m_bBox.isValid() && size() != 0) {
594  refreshBB();
595  }
596 
597  bbMin = m_bBox.minCorner();
598  bbMax = m_bBox.maxCorner();
599 }
600 
601 bool ccSubMesh::toFile_MeOnly(QFile& out, short dataVersion) const {
602  assert(out.isOpen() && (out.openMode() & QIODevice::WriteOnly));
603  if (dataVersion < 29) {
604  assert(false);
605  return false;
606  }
607 
608  if (!ccGenericMesh::toFile_MeOnly(out, dataVersion)) return false;
609 
610  // we can't save the associated mesh here (as it may already be saved)
611  // so instead we save it's unique ID (dataVersion>=29)
612  // WARNING: the mesh must be saved in the same BIN file! (responsibility of
613  // the caller)
614  uint32_t meshUniqueID =
616  ? static_cast<uint32_t>(m_associatedMesh->getUniqueID())
617  : 0);
618  if (out.write((const char*)&meshUniqueID, 4) < 0) return WriteError();
619 
620  // references (dataVersion>=29)
621  if (!ccSerializationHelper::GenericArrayToFile<unsigned, 1, unsigned>(
622  m_triIndexes, out))
623  return WriteError();
624 
625  return true;
626 }
627 
629  short minVersion =
630  std::max(static_cast<short>(29),
632  return std::max(minVersion, ccGenericMesh::minimumFileVersion_MeOnly());
633 }
634 
636  short dataVersion,
637  int flags,
638  LoadedIDMap& oldToNewIDMap) {
639  if (!ccGenericMesh::fromFile_MeOnly(in, dataVersion, flags, oldToNewIDMap))
640  return false;
641 
642  // as the associated mesh can't be saved directly
643  // we only store its unique ID (dataVersion>=29) --> we hope we will find it
644  // at loading time (i.e. this is the responsibility of the caller to make
645  // sure that all dependencies are saved together)
646  uint32_t meshUniqueID = 0;
647  if (in.read((char*)&meshUniqueID, 4) < 0) return ReadError();
648  //[DIRTY] WARNING: temporarily, we set the mesh unique ID in the
649  //'m_associatedMesh' pointer!!!
650  *(uint32_t*)(&m_associatedMesh) = meshUniqueID;
651 
652  // references (dataVersion>=29)
653  if (!ccSerializationHelper::GenericArrayFromFile<unsigned, 1, unsigned>(
654  m_triIndexes, in, dataVersion, "triangle indexes"))
655  return ReadError();
656 
657  return true;
658 }
constexpr unsigned char POINT_VISIBLE
Definition: CVConst.h:92
static bool Error(const char *format,...)
Display an error dialog with formatted message.
Definition: CVLog.cpp:143
Array of compressed 3D normals (single index)
Array of 2D texture coordinates.
Bounding box structure.
Definition: ecvBBox.h:25
virtual bool colorsShown() const
Returns whether colors are shown or not.
virtual bool sfShown() const
Returns whether active scalar field is visible.
virtual bool normalsShown() const
Returns whether normals are shown or not.
virtual void showColors(bool state)
Sets colors visibility.
virtual void showSF(bool state)
Sets active scalarfield visibility.
Generic mesh interface.
virtual bool materialsShown() const
Sets whether textures/material should be displayed or not.
void showNormals(bool state) override
Sets normals visibility.
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.
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.
A 3D cloud interface with associated features (color, normals, octree, etc.)
virtual VisibilityTableType & getTheVisibilityArray()
Returns associated visibility array.
std::vector< unsigned char > VisibilityTableType
Array of "visibility" information for each point.
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
virtual void notifyGeometryUpdate()
Definition: ecvHObject.cpp:104
void removeDependencyWith(ccHObject *otherObject)
Removes any dependency flags with a given object.
Definition: ecvHObject.cpp:497
void addDependency(ccHObject *otherObject, int flags, bool additive=true)
Adds a new dependence (additive or not)
Definition: ecvHObject.cpp:455
@ DP_NOTIFY_OTHER_ON_UPDATE
Definition: ecvHObject.h:261
Mesh (triangle) material.
Triangular mesh.
Definition: ecvMesh.h:35
bool interpolateNormalsBC(unsigned triIndex, const CCVector3d &w, CCVector3 &N) override
Interpolates normal(s) inside a given triangle.
Definition: ecvMesh.cpp:4105
void getTriangleTexCoordinatesIndexes(unsigned triangleIndex, int &i1, int &i2, int &i3) const override
Returns the triplet of tex coords indexes for a given triangle.
Definition: ecvMesh.cpp:3691
const ccMaterialSet * getMaterialSet() const override
Definition: ecvMesh.h:412
TextureCoordsContainer * getTexCoordinatesTable() const override
Returns per-triangle texture coordinates array.
Definition: ecvMesh.h:476
NormsIndexesTableType * getTriNormsTable() const override
Returns per-triangle normals shared array.
Definition: ecvMesh.h:344
void getTriangleNormalIndexes(unsigned triangleIndex, int &i1, int &i2, int &i3) const override
Returns a triplet of normal indexes for a given triangle (if any)
Definition: ecvMesh.cpp:3353
bool getTriangleNormals(unsigned triangleIndex, CCVector3 &Na, CCVector3 &Nb, CCVector3 &Nc) const override
Returns a given triangle normal.
Definition: ecvMesh.cpp:3367
bool normalsShown() const override
Returns whether normals are shown or not.
Definition: ecvMesh.cpp:388
virtual unsigned size() const override
Returns the number of triangles.
Definition: ecvMesh.cpp:2143
void getTriangleTexCoordinates(unsigned triIndex, TexCoords2D *&tx1, TexCoords2D *&tx2, TexCoords2D *&tx3) const override
Returns per-triangle texture coordinates (pointer to)
Definition: ecvMesh.cpp:3620
bool getColorFromMaterial(unsigned triIndex, const CCVector3 &P, ecvColor::Rgb &C, bool interpolateColorIfNoTexture) override
Definition: ecvMesh.cpp:4228
ccGenericPointCloud * getAssociatedCloud() const override
Returns the vertices cloud.
Definition: ecvMesh.h:143
virtual void getTriangleVertices(unsigned triangleIndex, CCVector3 &A, CCVector3 &B, CCVector3 &C) const override
Returns the vertices of a given triangle.
Definition: ecvMesh.cpp:2187
bool hasPerTriangleTexCoordIndexes() const override
Returns whether this mesh as per-triangle triplets of tex coords indexes.
Definition: ecvMesh.h:484
bool interpolateNormals(unsigned triIndex, const CCVector3 &P, CCVector3 &N) override
Interpolates normal(s) inside a given triangle.
Definition: ecvMesh.cpp:4050
void getTexCoordinates(unsigned index, TexCoords2D *&tx) const override
Definition: ecvMesh.cpp:3653
bool getVertexColorFromMaterial(unsigned triIndex, unsigned char vertIndex, ecvColor::Rgb &C, bool returnColorIfNoTexture) override
Definition: ecvMesh.cpp:4154
int getTriangleMtlIndex(unsigned triangleIndex) const override
Returns a given triangle material indexes.
Definition: ecvMesh.cpp:3761
cloudViewer::GenericTriangle * _getTriangle(unsigned triangleIndex) override
Returns the ith triangle.
Definition: ecvMesh.cpp:2173
cloudViewer::VerticesIndexes * getTriangleVertIndexes(unsigned triangleIndex) override
Returns the indexes of the vertices of a given triangle.
Definition: ecvMesh.cpp:2599
bool interpolateColors(unsigned triIndex, const CCVector3 &P, ecvColor::Rgb &C) override
Interpolates RGB colors inside a given triangle.
Definition: ecvMesh.cpp:4120
virtual QString getName() const
Returns object name.
Definition: ecvObject.h:72
virtual unsigned getUniqueID() const
Returns object unique ID.
Definition: ecvObject.h:86
virtual void setName(const QString &name)
Sets object name.
Definition: ecvObject.h:75
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 short GenericArrayToFileMinVersion()
Returns the minimum file version to save/load a 'generic array'.
A sub-mesh.
Definition: ecvSubMesh.h:19
void setAssociatedMesh(ccMesh *mesh, bool unlinkPreviousOne=true)
Sets the associated mesh.
Definition: ecvSubMesh.cpp:36
void forEach(genericTriangleAction action) override
Fast iteration mechanism.
Definition: ecvSubMesh.cpp:53
void getTriangleTexCoordinatesIndexes(unsigned triangleIndex, int &i1, int &i2, int &i3) const override
Returns the triplet of tex coords indexes for a given triangle.
Definition: ecvSubMesh.cpp:453
bool toFile_MeOnly(QFile &out, short dataVersion) const override
Save own object data.
Definition: ecvSubMesh.cpp:601
NormsIndexesTableType * getTriNormsTable() const override
Returns per-triangle normals shared array.
Definition: ecvSubMesh.cpp:487
cloudViewer::VerticesIndexes * getNextTriangleVertIndexes() override
Definition: ecvSubMesh.cpp:75
const ccMaterialSet * getMaterialSet() const override
Definition: ecvSubMesh.cpp:413
bool getTriangleNormals(unsigned triangleIndex, CCVector3 &Na, CCVector3 &Nb, CCVector3 &Nc) const override
Returns a given triangle normal.
Definition: ecvSubMesh.cpp:477
bool getColorFromMaterial(unsigned triIndex, const CCVector3 &P, ecvColor::Rgb &rgb, bool interpolateColorIfNoTexture) override
Definition: ecvSubMesh.cpp:118
ccSubMesh(ccMesh *parentMesh)
Default constructor.
Definition: ecvSubMesh.cpp:24
bool getVertexColorFromMaterial(unsigned triIndex, unsigned char vertIndex, ecvColor::Rgb &rgb, bool returnColorIfNoTexture) override
Definition: ecvSubMesh.cpp:132
void getTriangleNormalIndexes(unsigned triangleIndex, int &i1, int &i2, int &i3) const override
Returns a triplet of normal indexes for a given triangle (if any)
Definition: ecvSubMesh.cpp:465
bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads own object data.
Definition: ecvSubMesh.cpp:635
void clear(bool releaseMemory)
Clears the mesh.
Definition: ecvSubMesh.cpp:491
void getBoundingBox(CCVector3 &bbMin, CCVector3 &bbMax) override
Returns the mesh bounding-box.
Definition: ecvSubMesh.cpp:591
cloudViewer::GenericTriangle * _getTriangle(unsigned index) override
Returns the ith triangle.
Definition: ecvSubMesh.cpp:146
bool hasPerTriangleTexCoordIndexes() const override
Returns whether this mesh as per-triangle triplets of tex coords indexes.
Definition: ecvSubMesh.cpp:448
std::vector< unsigned int > IndexMap
Indexes map for createNewSubMeshFromSelection.
Definition: ecvSubMesh.h:175
ccBBox m_bBox
Bounding-box.
Definition: ecvSubMesh.h:229
void refreshBB() override
Forces bounding-box update.
Definition: ecvSubMesh.cpp:566
bool interpolateNormalsBC(unsigned triIndex, const CCVector3d &w, CCVector3 &N) override
Interpolates normal(s) inside a given triangle.
Definition: ecvSubMesh.cpp:94
bool normalsShown() const override
Returns whether normals are shown or not.
Definition: ecvSubMesh.cpp:396
TextureCoordsContainer * getTexCoordinatesTable() const override
Returns per-triangle texture coordinates array.
Definition: ecvSubMesh.cpp:423
unsigned getTriGlobalIndex(unsigned localIndex) const
Definition: ecvSubMesh.h:116
virtual void getTriangleVertices(unsigned triangleIndex, CCVector3 &A, CCVector3 &B, CCVector3 &C) const override
Returns the vertices of a given triangle.
Definition: ecvSubMesh.cpp:157
ccSubMesh * createNewSubMeshFromSelection(bool removeSelectedTriangles, const std::vector< int > &selectedTriangleIndexes, IndexMap *newRemainingTriangleIndexes=nullptr)
Creates a new sub mesh with the visible vertices only.
Definition: ecvSubMesh.cpp:298
ccBBox getOwnBB(bool withGLFeatures=false) override
Returns the entity's own bounding-box.
Definition: ecvSubMesh.cpp:582
ccGenericPointCloud * getAssociatedCloud() const override
Returns the vertices cloud.
Definition: ecvSubMesh.cpp:63
cloudViewer::GenericTriangle * _getNextTriangle() override
Returns the next triangle (relatively to the global iterator position)
Definition: ecvSubMesh.cpp:67
unsigned size() const override
Returns the number of triangles.
Definition: ecvSubMesh.h:85
bool interpolateColors(unsigned triIndex, const CCVector3 &P, ecvColor::Rgb &rgb) override
Interpolates RGB colors inside a given triangle.
Definition: ecvSubMesh.cpp:106
int getTriangleMtlIndex(unsigned triangleIndex) const override
Returns a given triangle material indexes.
Definition: ecvSubMesh.cpp:417
void onUpdateOf(ccHObject *obj) override
This method is called when another object (geometry) is updated.
Definition: ecvSubMesh.cpp:49
ReferencesContainer m_triIndexes
Indexes of (some of) the associated mesh triangles.
Definition: ecvSubMesh.h:223
ccMesh * m_associatedMesh
Associated mesh.
Definition: ecvSubMesh.h:217
void getTexCoordinates(unsigned index, TexCoords2D *&tx) const override
Definition: ecvSubMesh.cpp:428
void getTriangleTexCoordinates(unsigned triIndex, TexCoords2D *&tx1, TexCoords2D *&tx2, TexCoords2D *&tx3) const override
Returns per-triangle texture coordinates (pointer to)
Definition: ecvSubMesh.cpp:434
short minimumFileVersion_MeOnly() const override
Definition: ecvSubMesh.cpp:628
bool resize(size_t n)
Presets the size of the vector used to store triangle references.
Definition: ecvSubMesh.cpp:552
bool interpolateNormals(unsigned triIndex, const CCVector3 &P, CCVector3 &N) override
Interpolates normal(s) inside a given triangle.
Definition: ecvSubMesh.cpp:82
bool reserve(size_t n)
Reserves some memory for hosting the triangle references.
Definition: ecvSubMesh.cpp:542
void setTriangleIndex(unsigned localIndex, unsigned globalIndex)
Sets global index for a given element.
Definition: ecvSubMesh.cpp:536
unsigned m_globalIterator
Iterator on the triangles references container.
Definition: ecvSubMesh.h:226
bool addTriangleIndex(unsigned globalIndex)
Triangle global index insertion mechanism.
Definition: ecvSubMesh.cpp:499
unsigned capacity() const override
Returns max capacity.
Definition: ecvSubMesh.cpp:562
cloudViewer::VerticesIndexes * getTriangleVertIndexes(unsigned triangleIndex) override
Returns the indexes of the vertices of a given triangle.
Definition: ecvSubMesh.cpp:183
const Vector3Tpl< T > & maxCorner() const
Returns max corner (const)
Definition: BoundingBox.h:156
void setValidity(bool state)
Sets bonding box validity.
Definition: BoundingBox.h:200
void clear()
Resets the bounding box.
Definition: BoundingBox.h:125
const Vector3Tpl< T > & minCorner() const
Returns min corner (const)
Definition: BoundingBox.h:154
bool isValid() const
Returns whether bounding box is valid or not.
Definition: BoundingBox.h:203
void add(const Vector3Tpl< T > &P)
'Enlarges' the bounding box with a point
Definition: BoundingBox.h:131
virtual unsigned size() const =0
Returns the number of points.
std::function< void(GenericTriangle &)> genericTriangleAction
Generic function to apply to a triangle (used by foreach)
Definition: GenericMesh.h:53
A generic triangle interface.
virtual const CCVector3 * _getA() const =0
Returns the first vertex (A)
virtual const CCVector3 * _getC() const =0
Returns the third vertex (C)
virtual const CCVector3 * _getB() const =0
Returns the second vertex (B)
RGB color structure.
Definition: ecvColorTypes.h:49
#define CC_SUB_MESH_TRANSIENT_CONST_TEST(method)
Definition: ecvSubMesh.cpp:400
normal_z rgb
2D texture coordinates
Triangle described by the indexes of its 3 vertices.