ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
SimpleMesh.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 "SimpleMesh.h"
9 
10 // local
11 #include "GenericIndexedCloud.h"
12 
13 // System
14 #include <cassert>
15 
16 using namespace cloudViewer;
17 
19  bool linkVerticesWithMesh)
21  globalIterator(0),
22  theVertices(_theVertices),
23  verticesLinked(linkVerticesWithMesh) {}
24 
26  if (theVertices && verticesLinked) {
27  delete theVertices;
28  theVertices = nullptr;
29  }
30 }
31 
33  SimpleTriangle tri;
34  std::size_t count = m_triIndexes.size();
35  for (VerticesIndexes& ti : m_triIndexes) {
36  theVertices->getPoint(ti.i1, tri.A);
37  theVertices->getPoint(ti.i2, tri.B);
38  theVertices->getPoint(ti.i3, tri.C);
39  action(tri);
40  }
41 }
42 
44 
46  return _getTriangle(globalIterator++);
47 }
48 
49 GenericTriangle* SimpleMesh::_getTriangle(unsigned triangleIndex) {
50  assert(triangleIndex < m_triIndexes.size());
51 
52  const VerticesIndexes& ti = m_triIndexes[triangleIndex];
56 
57  return &dummyTriangle; // temporary!
58 }
59 
60 void SimpleMesh::getTriangleVertices(unsigned triangleIndex,
61  CCVector3& A,
62  CCVector3& B,
63  CCVector3& C) const {
64  assert(triangleIndex < m_triIndexes.size());
65 
66  const VerticesIndexes& ti = m_triIndexes[triangleIndex];
67  theVertices->getPoint(ti.i1, A);
68  theVertices->getPoint(ti.i2, B);
69  theVertices->getPoint(ti.i3, C);
70 }
71 
73  double A[3],
74  double B[3],
75  double C[3]) const {
76  assert(triangleIndex < m_triIndexes.size());
77 
78  const VerticesIndexes& ti = m_triIndexes[triangleIndex];
79  theVertices->getPoint(ti.i1, A);
80  theVertices->getPoint(ti.i2, B);
81  theVertices->getPoint(ti.i3, C);
82 }
83 
86  // if (!m_bbox.isValid())
87  //{
88  // m_bbox.clear();
89  // for (const VerticesIndexes& ti : m_triIndexes)
90  // {
91  // m_bbox.add(*theVertices->getPoint(ti.i1));
92  // m_bbox.add(*theVertices->getPoint(ti.i2));
93  // m_bbox.add(*theVertices->getPoint(ti.i3));
94  // }
95  // }
96 
97  // bbMin = m_bbox.minCorner();
98  // bbMax = m_bbox.maxCorner();
99 
100  return theVertices->getBoundingBox(bbMin, bbMax);
101 }
102 
103 void SimpleMesh::addTriangle(unsigned i1, unsigned i2, unsigned i3) {
104  m_triIndexes.push_back(VerticesIndexes(i1, i2, i3));
105 
106  m_bbox.setValidity(false);
107 }
108 
109 bool SimpleMesh::reserve(unsigned n) {
110  try {
111  m_triIndexes.reserve(n);
112  } catch (const std::bad_alloc&) {
113  return false;
114  }
115  return true;
116 }
117 
118 bool SimpleMesh::resize(unsigned n) {
119  try {
120  m_triIndexes.resize(n);
121  } catch (const std::bad_alloc&) {
122  return false;
123  }
124  return true;
125 }
126 
129 }
130 
131 bool SimpleMesh::interpolateNormals(unsigned triIndex,
132  const CCVector3& P,
133  CCVector3& N) {
134  if (static_cast<size_t>(triIndex) >= m_triIndexes.size()) {
135  // index out of range
136  assert(false);
137  return false;
138  }
139 
140  const VerticesIndexes& tri = m_triIndexes[triIndex];
141 
142  // intepolation weights
143  CCVector3d weights;
144  {
145  CCVector3 A, B, C;
146  theVertices->getPoint(tri.i1, A);
147  theVertices->getPoint(tri.i2, B);
148  theVertices->getPoint(tri.i3, C);
149 
150  // barcyentric intepolation weights
151  weights.x = sqrt(((P - B).cross(C - B)).norm2d()) /*/2*/;
152  weights.y = sqrt(((P - C).cross(A - C)).norm2d()) /*/2*/;
153  weights.z = sqrt(((P - A).cross(B - A)).norm2d()) /*/2*/;
154 
155  // normalize weights
156  double sum = weights.x + weights.y + weights.z;
157  weights /= sum;
158  }
159 
160  // interpolated normal
161  CCVector3d Nd(0, 0, 0);
162  {
163  const CCVector3* N1 = theVertices->getNormal(tri.i1);
164  Nd += N1->toDouble() * weights.u[0];
165 
166  const CCVector3* N2 = theVertices->getNormal(tri.i2);
167  Nd += N2->toDouble() * weights.u[1];
168 
169  const CCVector3* N3 = theVertices->getNormal(tri.i3);
170  Nd += N3->toDouble() * weights.u[2];
171 
172  Nd.normalize();
173  }
174 
175  N = Nd.toPC();
176 
177  return true;
178 }
179 
181  return &(m_triIndexes[triangleIndex]);
182 }
183 
186 }
int count
Type y
Definition: CVGeom.h:137
Type u[3]
Definition: CVGeom.h:139
Type x
Definition: CVGeom.h:137
Type z
Definition: CVGeom.h:137
void normalize()
Sets vector norm to unity.
Definition: CVGeom.h:428
Vector3Tpl< PointCoordinateType > toPC() const
Definition: CVGeom.h:263
Vector3Tpl< double > toDouble() const
Cast operator to a double vector (explicit call version)
Definition: CVGeom.h:255
void setValidity(bool state)
Sets bonding box validity.
Definition: BoundingBox.h:200
virtual void getBoundingBox(CCVector3 &bbMin, CCVector3 &bbMax)=0
Returns the cloud bounding box.
A generic 3D point cloud with index-based point access.
virtual const CCVector3 * getPoint(unsigned index) const =0
Returns the ith point.
virtual bool normalsAvailable() const
Returns whether normals are available.
virtual const CCVector3 * getNormal(unsigned index) const
If per-point normals are available, returns the one at a specific index.
A generic mesh with index-based vertex access.
std::function< void(GenericTriangle &)> genericTriangleAction
Generic function to apply to a triangle (used by foreach)
Definition: GenericMesh.h:53
A generic triangle interface.
virtual bool resize(unsigned n)
Resizes the mesh database.
Definition: SimpleMesh.cpp:118
unsigned globalIterator
Iterator on the list of triangles.
Definition: SimpleMesh.h:107
void forEach(genericTriangleAction action) override
Fast iteration mechanism.
Definition: SimpleMesh.cpp:32
~SimpleMesh() override
SimpleMesh destructor.
Definition: SimpleMesh.cpp:25
SimpleTriangle dummyTriangle
Dump triangle structure to transmit temporary data.
Definition: SimpleMesh.h:109
GenericTriangle * _getNextTriangle() override
Returns the next triangle (relatively to the global iterator position)
Definition: SimpleMesh.cpp:45
bool normalsAvailable() const override
Returns whether normals are available.
Definition: SimpleMesh.cpp:127
BoundingBox m_bbox
Bounding-box.
Definition: SimpleMesh.h:118
virtual void addTriangle(unsigned i1, unsigned i2, unsigned i3)
Adds a triangle to the mesh.
Definition: SimpleMesh.cpp:103
VerticesIndexes * getNextTriangleVertIndexes() override
Definition: SimpleMesh.cpp:184
VerticesIndexes * getTriangleVertIndexes(unsigned triangleIndex) override
Returns the indexes of the vertices of a given triangle.
Definition: SimpleMesh.cpp:180
GenericIndexedCloud * theVertices
The associated point cloud (vertices)
Definition: SimpleMesh.h:112
SimpleMesh(GenericIndexedCloud *_theVertices, bool linkVerticesWithMesh=false)
SimpleMesh Constructor.
Definition: SimpleMesh.cpp:18
void getTriangleVertices(unsigned triangleIndex, CCVector3 &A, CCVector3 &B, CCVector3 &C) const override
Returns the vertices of a given triangle.
Definition: SimpleMesh.cpp:60
void getBoundingBox(CCVector3 &bbMin, CCVector3 &bbMax) override
Returns the mesh bounding-box.
Definition: SimpleMesh.cpp:84
virtual bool reserve(unsigned n)
Reserves the memory to store the triangles (as 3 indexes each)
Definition: SimpleMesh.cpp:109
void placeIteratorAtBeginning() override
Places the mesh iterator at the beginning.
Definition: SimpleMesh.cpp:43
GenericTriangle * _getTriangle(unsigned triangleIndex) override
Returns the ith triangle.
Definition: SimpleMesh.cpp:49
bool interpolateNormals(unsigned triIndex, const CCVector3 &P, CCVector3 &N) override
Interpolates normal(s) inside a given triangle.
Definition: SimpleMesh.cpp:131
TriangleIndexesContainer m_triIndexes
The triangles indexes.
Definition: SimpleMesh.h:104
A simple triangle class.
__host__ __device__ float3 cross(float3 a, float3 b)
Definition: cutil_math.h:1295
Generic file read and write utility for python interface.
Triangle described by the indexes of its 3 vertices.