12#include <corecrt_math_defines.h>
14#include <robin_hood.h>
17#define _USE_MATH_DEFINES
26 const size_t n = vertices.size();
30 VectorsToBuffers(vertices);
74 const vector<array<T, 3>>& vertices,
75 vector<int>& mapped_indexes,
76 vector<T>& mapped_vertices
79 robin_hood::unordered_map <array<T, 3>,
int> index_map;
82 int vertsize = vertices.size();
85 for (
int i = 0; i < vertsize; i += 3) {
89 for (
int k = 0; k < 3; k++)
92 const auto& vert = vertices[i + k];
96 if (index_map.count(vert) > 0)
97 current_id = index_map[vert];
101 index_map[vert] = next_id;
102 current_id = next_id;
105 mapped_vertices.push_back(vert[0]);
106 mapped_vertices.push_back(vert[1]);
107 mapped_vertices.push_back(vert[2]);
115 mapped_indexes.push_back(ids[0]);
116 mapped_indexes.push_back(ids[1]);
117 mapped_indexes.push_back(ids[2]);
121 template <
typename T>
125 vector<int> mapped_indexes; vector<T> mapped_vertices;
129 if (!(mapped_indexes.size() % 3 == 0))
133 verts.resize(3, mapped_vertices.size() / 3);
134 indices.resize(3, mapped_indexes.size() / 3);
135 std::move(mapped_vertices.begin(), mapped_vertices.end(), verts.data());
136 std::move(mapped_indexes.begin(), mapped_indexes.end(), indices.data());
139 template <
typename T>
141 const vector<T>& in_vertices,
142 const vector<int>& in_indexes,
148 if (in_vertices.size() % 3 != 0 || in_indexes.size() % 3 != 0)
152 verts.resize(3, in_vertices.size() / 3);
153 indices.resize(3, in_indexes.size() / 3);
154 std::move(in_vertices.begin(), in_vertices.end(), verts.data());
155 std::move(in_indexes.begin(), in_indexes.end(), indices.data());
161 template <
typename T>
166 verts.resize(3, (
static_cast<size_t>(verts.cols()) + in_vertices.size()));
168 for (
int i = 0; i < in_vertices.size(); i++) {
169 auto& vertex = in_vertices[i];
170 verts(0, i) = vertex[0];
171 verts(1, i) = vertex[1];
172 verts(2, i) = vertex[2];
174 if (verts.hasNaN())
throw std::exception(
"Creation of mesh info failed");
177 template <
typename T>
180 template <
typename T>
183 template <
typename T>
186 Eigen::AngleAxis<T> yrot(0.5f *
static_cast<T
>(M_PI), Eigen::Vector3<T>::UnitX());
187 Eigen::Quaternion<T> quat;
190 verts = yrot.toRotationMatrix() * verts;
192 if (!verts.allFinite())
throw std::exception(
"Verts has NAN");
195 template <
typename T>
198 Eigen::AngleAxis<T> yrot(-0.5f *
static_cast<T
>(M_PI), Eigen::Vector3<T>::UnitX());
199 Eigen::Quaternion<T> quat;
202 Eigen::Matrix3<T> rotation_matrix = yrot.toRotationMatrix();
203 assert(!rotation_matrix.hasNaN());
204 verts = (rotation_matrix * verts);
205 assert(!verts.hasNaN());
208 template <
typename T>
212 T radian_ratio =
static_cast<T
>(M_PI) / 180.00f;
213 rx *= radian_ratio; ry *= radian_ratio; rz *= radian_ratio;
217 Eigen::AngleAxis<T> rollAngle(rz, Eigen::Vector3<T>::UnitZ());
218 Eigen::AngleAxis<T> yawAngle(ry, Eigen::Vector3<T>::UnitY());
219 Eigen::AngleAxis<T> pitchAngle(rx, Eigen::Vector3<T>::UnitX());
224 Eigen::Quaternion<T> q = (rollAngle * yawAngle * pitchAngle);
226 Eigen::Matrix3<T> rotation_matrix = q.toRotationMatrix();
230 assert(rotation_matrix.allFinite());
233 verts = (rotation_matrix * verts);
236 assert(verts.allFinite());
240 template <
typename T>
243 template <
typename T>
247 vector<T> out_array(verts.size());
250 std::copy(verts.data(), verts.data() + verts.size(), out_array.begin());
255 template <
typename T>
258 vector<int> out_array(indices.size());
259 std::copy(indices.data(), indices.data() + indices.size(), out_array.begin());
263 template <
typename T>
267 int tri_count = NumTris();
268 vector<array<T, 3>>out_array(tri_count * 3);
271 for (
int i = 0; i < tri_count; i++)
273 const int offset = i * 3;
274 out_array[offset] = (*this)[indices(0, i)];
275 out_array[offset + 1] = (*this)[indices(1, i)];
276 out_array[offset + 2] = (*this)[indices(2, i)];
281 template <
typename T>
284 template <
typename T>
288 if (i < 0 || i > NumVerts())
throw std::exception(
"Out of range on index");
291 array<T, 3> out_array;
292 out_array[0] = verts(0, i);
293 out_array[1] = verts(1, i);
294 out_array[2] = verts(2, i);
305 template <
typename T>
306 T
arrayDist(
const array<T, 3> from,
const array<T, 3>& to) {
307 return sqrtf(powf(from[0] - to[0], 2) + powf(from[1] - to[1], 2) + powf(from[2] - to[2], 2));
309 template <
typename T>
313 if (NumVerts() != M2.
NumVerts())
return false;
315 for (
int i = 0; i < NumVerts(); i++) {
316 auto this_array = (*this)[i];
317 auto that_array = M2[i];
319 if (!(
arrayDist(this_array, that_array) < 0.001))
325 template <
typename T>
329 ret_array.
size = indices.size();
330 ret_array.
data =
const_cast<int*
>(indices.data());
335 template <
typename T>
339 ret_array.
size = verts.size();
340 ret_array.
data =
const_cast<T*
>(verts.data());
Contains definitions for the Exceptions namespace.
Contains definitions for the MeshInfo class.
Manipulate and load geometry from disk.
T arrayDist(const array< T, 3 > from, const array< T, 3 > &to)
Calculate the distance between from and to.
void IndexRawVertices(const vector< array< T, 3 > > &vertices, vector< int > &mapped_indexes, vector< T > &mapped_vertices)
Index an array of vertices.
The OBJ file was not valid.
A simple type to hold the size and data pointer of an array.
int size
Number of elements in data
A collection of vertices and indices representing geometry.
void AddVerts(const std::vector< std::array< numeric_type, 3 > > &verts)
Add more vertices to this mesh.
int GetMeshID() const
Get the ID of this mesh.
bool operator==(const MeshInfo &M2) const
Compare the vertices of two MeshInfo objects.
void PerformRotation(numeric_type rx, numeric_type ry, numeric_type rz)
Rotate this mesh by x, y, z rotations in degrees (pitch, yaw, roll).
std::array< numeric_type, 3 > operator[](int i) const
Get vertex at a specific index in the mesh.
void SetMeshID(int new_id)
Change the ID of this mesh.
std::vector< std::array< numeric_type, 3 > > GetUnindexedVertices() const
Retrieve an unindexed array of this mesh's vertices.
void SetVert(int index, numeric_type x, numeric_type y, numeric_type z)
Change the position of the vertex at index.
void ConvertToOBJCoordinates()
Convert a mesh from Z-Up to Y-Up.
int NumTris() const
Calculate the total number of triangles in this mesh.
int NumVerts() const
Determine how many vertices are in this mesh.
MeshInfo()
Construct an empty instance of MeshInfo.
void VectorsToBuffers(const std::vector< std::array< numeric_type, 3 > > &vertices)
Index vertices then insert them into verts and indices.
const array_and_size< int > GetIndexPointer() const
Get a pointer to the index array of this mesh.
const array_and_size< numeric_type > GetVertexPointer() const
Get a pointer to the vertex array of this mesh.
void ConvertToRhinoCoordinates()
Convert a mesh from Y-Up to Z-Up.
std::vector< numeric_type > GetIndexedVertices() const
A copy of every vertex in this array.
std::vector< int > getRawIndices() const
Retrieve a copy of this mesh's index buffer as a 1D array.