49 #include <assimp/scene.h> 50 #include <assimp/Importer.hpp> 51 #include <assimp/postprocess.h> 53 #include <Eigen/Geometry> 55 #include <boost/math/constants/constants.hpp> 64 struct LocalVertexType
66 LocalVertexType() :
x(0.0),
y(0.0),
z(0.0)
70 LocalVertexType(
const Eigen::Vector3d& v) :
x(v.x()),
y(v.y()),
z(v.z())
79 struct ltLocalVertexValue
81 bool operator()(
const LocalVertexType& p1,
const LocalVertexType& p2)
const 98 struct ltLocalVertexIndex
100 bool operator()(
const LocalVertexType& p1,
const LocalVertexType& p2)
const 102 return p1.index < p2.index;
110 unsigned int nt = triangles.size() / 3;
111 Mesh* mesh =
new Mesh(vertices.size(), nt);
112 for (
unsigned int i = 0; i < vertices.size(); ++i)
114 mesh->
vertices[3 * i] = vertices[i].x();
115 mesh->
vertices[3 * i + 1] = vertices[i].y();
116 mesh->
vertices[3 * i + 2] = vertices[i].z();
119 std::copy(triangles.begin(), triangles.end(), mesh->
triangles);
128 if (source.size() < 3)
131 if (source.size() % 3 != 0)
133 "constructed triangles will not make sense.");
135 std::set<detail::LocalVertexType, detail::ltLocalVertexValue> vertices;
136 std::vector<unsigned int> triangles;
138 unsigned int n = source.size() / 3;
139 for (
unsigned int i = 0; i < n; ++i)
142 unsigned int i3 = i * 3;
143 detail::LocalVertexType vt1(source[i3]);
144 std::set<detail::LocalVertexType, detail::ltLocalVertexValue>::iterator p1 = vertices.find(vt1);
145 if (p1 == vertices.end())
147 vt1.index = vertices.size();
148 vertices.insert(vt1);
151 vt1.index = p1->index;
152 triangles.push_back(vt1.index);
154 detail::LocalVertexType vt2(source[++i3]);
155 std::set<detail::LocalVertexType, detail::ltLocalVertexValue>::iterator p2 = vertices.find(vt2);
156 if (p2 == vertices.end())
158 vt2.index = vertices.size();
159 vertices.insert(vt2);
162 vt2.index = p2->index;
163 triangles.push_back(vt2.index);
165 detail::LocalVertexType vt3(source[++i3]);
166 std::set<detail::LocalVertexType, detail::ltLocalVertexValue>::iterator p3 = vertices.find(vt3);
167 if (p3 == vertices.end())
169 vt3.index = vertices.size();
170 vertices.insert(vt3);
173 vt3.index = p3->index;
175 triangles.push_back(vt3.index);
179 std::vector<detail::LocalVertexType> vt;
180 vt.insert(vt.end(), vertices.begin(), vertices.end());
181 std::sort(vt.begin(), vt.end(), detail::ltLocalVertexIndex());
184 unsigned int nt = triangles.size() / 3;
186 Mesh* mesh =
new Mesh(vt.size(), nt);
187 for (
unsigned int i = 0; i < vt.size(); ++i)
189 unsigned int i3 = i * 3;
195 std::copy(triangles.begin(), triangles.end(), mesh->
triangles);
204 static const Eigen::Vector3d one(1.0, 1.0, 1.0);
210 static const Eigen::Vector3d one(1.0, 1.0, 1.0);
215 const std::string& assimp_hint)
217 if (!buffer || size < 1)
225 std::size_t pos = assimp_hint.find_last_of(
".");
226 if (pos != std::string::npos)
228 hint = assimp_hint.substr(pos + 1);
229 std::transform(hint.begin(), hint.end(), hint.begin(), ::tolower);
235 Assimp::Importer importer;
239 importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, aiComponent_NORMALS | aiComponent_TANGENTS_AND_BITANGENTS |
240 aiComponent_COLORS | aiComponent_TEXCOORDS |
241 aiComponent_BONEWEIGHTS | aiComponent_ANIMATIONS |
242 aiComponent_TEXTURES | aiComponent_LIGHTS |
243 aiComponent_CAMERAS | aiComponent_MATERIALS);
246 const aiScene* scene = importer.ReadFileFromMemory(reinterpret_cast<const void*>(buffer), size,
247 aiProcess_Triangulate | aiProcess_JoinIdenticalVertices |
248 aiProcess_SortByPType | aiProcess_RemoveComponent,
258 scene->mRootNode->mTransformation = aiMatrix4x4();
262 importer.ApplyPostProcessing(aiProcess_OptimizeMeshes | aiProcess_OptimizeGraph);
273 res = retriever.
get(resource);
291 CONSOLE_BRIDGE_logWarn(
"This could be because of a resource filename that is too long for the Assimp library, a " 292 "known bug. As a workaround shorten the filename/path.");
299 void extractMeshData(
const aiScene* scene,
const aiNode* node,
const aiMatrix4x4& parent_transform,
301 std::vector<unsigned int>& triangles)
303 aiMatrix4x4 transform = parent_transform;
304 transform *= node->mTransformation;
305 for (
unsigned int j = 0; j < node->mNumMeshes; ++j)
307 const aiMesh* a = scene->mMeshes[node->mMeshes[j]];
308 unsigned int offset = vertices.size();
309 for (
unsigned int i = 0; i < a->mNumVertices; ++i)
311 aiVector3D v = transform * a->mVertices[i];
312 vertices.push_back(Eigen::Vector3d(v.x * scale.x(), v.y * scale.y(), v.z * scale.z()));
314 for (
unsigned int i = 0; i < a->mNumFaces; ++i)
315 if (a->mFaces[i].mNumIndices == 3)
317 triangles.push_back(offset + a->mFaces[i].mIndices[0]);
318 triangles.push_back(offset + a->mFaces[i].mIndices[1]);
319 triangles.push_back(offset + a->mFaces[i].mIndices[2]);
323 for (
unsigned int n = 0; n < node->mNumChildren; ++n)
324 extractMeshData(scene, node->mChildren[n], transform, scale, vertices, triangles);
330 static const Eigen::Vector3d one(1.0, 1.0, 1.0);
336 if (!scene->HasMeshes())
342 std::vector<unsigned int> triangles;
343 extractMeshData(scene, scene->mRootNode, aiMatrix4x4(), scale, vertices, triangles);
344 if (vertices.empty())
349 if (triangles.empty())
375 double x = box.
size[0] / 2.0;
376 double y = box.
size[1] / 2.0;
377 double z = box.
size[2] / 2.0;
413 static const unsigned int tri[] = { 0, 1, 2, 2, 3, 0, 4, 3, 2, 2, 6, 4, 7, 6, 2, 2, 1, 7,
414 3, 4, 5, 5, 0, 3, 0, 5, 7, 7, 1, 0, 7, 5, 4, 4, 6, 7 };
415 memcpy(result->
triangles, tri,
sizeof(
unsigned int) * 36);
425 std::vector<unsigned int> triangles;
427 const double r = sphere.
radius;
428 const double pi = boost::math::constants::pi<double>();
429 const unsigned int seg = std::max<unsigned int>(6, 0.5 + 2.0 * pi * r / 0.01);
432 const unsigned int ring = std::max<unsigned int>(6, 2.0 * r / 0.01);
437 phid = pi * 2.0 / seg;
440 double theta, thetad;
441 thetad = pi / (ring + 1);
444 for (
unsigned int i = 0; i < ring; ++i)
446 double theta_ = theta + thetad * (i + 1);
447 for (
unsigned int j = 0; j < seg; ++j)
448 vertices.push_back(Eigen::Vector3d(r * sin(theta_) * cos(phi + j * phid), r * sin(theta_) * sin(phi + j * phid),
451 vertices.push_back(Eigen::Vector3d(0.0, 0.0, r));
452 vertices.push_back(Eigen::Vector3d(0.0, 0.0, -r));
454 for (
unsigned int i = 0; i < ring - 1; ++i)
456 for (
unsigned int j = 0; j < seg; ++j)
458 unsigned int a, b, c,
d;
460 b = (j == seg - 1) ? (i * seg) : (i * seg + j + 1);
461 c = (i + 1) * seg + j;
462 d = (j == seg - 1) ? ((i + 1) * seg) : ((i + 1) * seg + j + 1);
463 triangles.push_back(a);
464 triangles.push_back(c);
465 triangles.push_back(b);
466 triangles.push_back(b);
467 triangles.push_back(c);
468 triangles.push_back(d);
472 for (
unsigned int j = 0; j < seg; ++j)
476 b = (j == seg - 1) ? 0 : (j + 1);
477 triangles.push_back(ring * seg);
478 triangles.push_back(a);
479 triangles.push_back(b);
481 a = (ring - 1) * seg + j;
482 b = (j == seg - 1) ? (ring - 1) * seg : ((ring - 1) * seg + j + 1);
483 triangles.push_back(a);
484 triangles.push_back(ring * seg + 1);
485 triangles.push_back(b);
494 std::vector<unsigned int> triangles;
497 static unsigned int tot_for_unit_cylinder = 100;
500 double h = cylinder.
length;
502 const double pi = boost::math::constants::pi<double>();
503 unsigned int tot = std::max<unsigned int>(6, ceil(tot_for_unit_cylinder * r));
504 double phid = pi * 2 / tot;
506 double circle_edge = phid * r;
507 unsigned int h_num = ceil(std::abs(h) / circle_edge);
510 double hd = h / h_num;
512 for (
unsigned int i = 0; i < tot; ++i)
513 vertices.push_back(Eigen::Vector3d(r * cos(phi + phid * i), r * sin(phi + phid * i), h / 2));
515 for (
unsigned int i = 0; i < h_num - 1; ++i)
516 for (
unsigned int j = 0; j < tot; ++j)
517 vertices.push_back(Eigen::Vector3d(r * cos(phi + phid * j), r * sin(phi + phid * j), h / 2 - (i + 1) * hd));
519 for (
unsigned int i = 0; i < tot; ++i)
520 vertices.push_back(Eigen::Vector3d(r * cos(phi + phid * i), r * sin(phi + phid * i), -h / 2));
522 vertices.push_back(Eigen::Vector3d(0, 0, h / 2));
523 vertices.push_back(Eigen::Vector3d(0, 0, -h / 2));
525 for (
unsigned int i = 0; i < tot; ++i)
527 triangles.push_back((h_num + 1) * tot);
528 triangles.push_back(i);
529 triangles.push_back((i == tot - 1) ? 0 : (i + 1));
532 for (
unsigned int i = 0; i < tot; ++i)
534 triangles.push_back((h_num + 1) * tot + 1);
535 triangles.push_back(h_num * tot + ((i == tot - 1) ? 0 : (i + 1)));
536 triangles.push_back(h_num * tot + i);
539 for (
unsigned int i = 0; i < h_num; ++i)
541 for (
unsigned int j = 0; j < tot; ++j)
545 b = (j == tot - 1) ? 0 : (j + 1);
547 d = (j == tot - 1) ? tot : (j + 1 + tot);
550 triangles.push_back(start + b);
551 triangles.push_back(start + a);
552 triangles.push_back(start + c);
553 triangles.push_back(start + b);
554 triangles.push_back(start + c);
555 triangles.push_back(start + d);
565 std::vector<unsigned int> triangles;
568 static unsigned int tot_for_unit_cone = 100;
573 const double pi = boost::math::constants::pi<double>();
574 unsigned int tot = tot_for_unit_cone * r;
575 double phid = pi * 2 / tot;
577 double circle_edge = phid * r;
578 unsigned int h_num = ceil(h / circle_edge);
581 double hd = h / h_num;
583 for (
unsigned int i = 0; i < h_num - 1; ++i)
585 double h_i = h / 2 - (i + 1) * hd;
586 double rh = r * (0.5 - h_i / h);
587 for (
unsigned int j = 0; j < tot; ++j)
588 vertices.push_back(Eigen::Vector3d(rh * cos(phi + phid * j), rh * sin(phi + phid * j), h_i));
591 for (
unsigned int i = 0; i < tot; ++i)
592 vertices.push_back(Eigen::Vector3d(r * cos(phi + phid * i), r * sin(phi + phid * i), -h / 2));
594 vertices.push_back(Eigen::Vector3d(0, 0, h / 2));
595 vertices.push_back(Eigen::Vector3d(0, 0, -h / 2));
597 for (
unsigned int i = 0; i < tot; ++i)
599 triangles.push_back(h_num * tot);
600 triangles.push_back(i);
601 triangles.push_back((i == tot - 1) ? 0 : (i + 1));
604 for (
unsigned int i = 0; i < tot; ++i)
606 triangles.push_back(h_num * tot + 1);
607 triangles.push_back((h_num - 1) * tot + ((i == tot - 1) ? 0 : (i + 1)));
608 triangles.push_back((h_num - 1) * tot + i);
611 for (
unsigned int i = 0; i < h_num - 1; ++i)
612 for (
unsigned int j = 0; j < tot; ++j)
616 b = (j == tot - 1) ? 0 : (j + 1);
618 d = (j == tot - 1) ? tot : (j + 1 + tot);
621 triangles.push_back(start + b);
622 triangles.push_back(start + a);
623 triangles.push_back(start + c);
624 triangles.push_back(start + b);
625 triangles.push_back(start + c);
626 triangles.push_back(start + d);
633 inline void writeFloatToSTL(
char*& ptr,
float data)
635 memcpy(ptr, &data,
sizeof(
float));
636 ptr +=
sizeof(float);
638 inline void writeFloatToSTL(
char*& ptr,
double datad)
641 memcpy(ptr, &data,
sizeof(
float));
642 ptr +=
sizeof(float);
649 memset(&buffer[0], 0, 80);
650 char* ptr = &buffer[80];
652 memcpy(ptr, &nt,
sizeof(uint32_t));
653 ptr +=
sizeof(uint32_t);
656 unsigned int i3 = i * 3;
666 memset(ptr, 0,
sizeof(
float) * 3);
667 ptr +=
sizeof(float) * 3;
671 writeFloatToSTL(ptr, mesh->
vertices[index]);
672 writeFloatToSTL(ptr, mesh->
vertices[index + 1]);
673 writeFloatToSTL(ptr, mesh->
vertices[index + 2]);
675 writeFloatToSTL(ptr, mesh->
vertices[index]);
676 writeFloatToSTL(ptr, mesh->
vertices[index + 1]);
677 writeFloatToSTL(ptr, mesh->
vertices[index + 2]);
679 writeFloatToSTL(ptr, mesh->
vertices[index]);
680 writeFloatToSTL(ptr, mesh->
vertices[index + 1]);
681 writeFloatToSTL(ptr, mesh->
vertices[index + 2]);
#define CONSOLE_BRIDGE_logWarn(fmt,...)
Definition of various shapes. No properties such as position are included. These are simply the descr...
double radius
The radius of the cylinder.
Definition of a cylinder Length is along z axis. Origin is at center of mass.
std::vector< Eigen::Vector3d, Eigen::aligned_allocator< Eigen::Vector3d > > vector_Vector3d
double length
The length (height) of the cone.
double size[3]
x, y, z dimensions of the box (axis-aligned)
ShapeType type
The type of the shape.
double radius
The radius of the cone.
double length
The length of the cylinder.
unsigned int * triangles
The vertex indices for each triangle triangle k has vertices at index (3k, 3k+1, 3k+2) = (v1...
Definition of a cone Tip is on positive z axis. Center of base is on negative z axis. Origin is halway between tip and center of base.
Mesh * createMeshFromVertices(const EigenSTL::vector_Vector3d &vertices, const std::vector< unsigned int > &triangles)
Load a mesh from a set of vertices.
A basic definition of a shape. Shapes are considered centered at origin.
boost::shared_array< uint8_t > data
unsigned int triangle_count
The number of triangles formed with the vertices.
double * vertices
The position for each vertex vertex k has values at index (3k, 3k+1, 3k+2) = (x,y,z)
double * triangle_normals
The normal to each triangle; unit vector represented as (x,y,z); If missing from the mesh...
void computeVertexNormals()
Compute vertex normals by averaging from adjacent triangle normals.
const std::string & shapeStringName(const Shape *shape)
Get the string name of the shape.
MemoryResource get(const std::string &url)
void computeTriangleNormals()
Compute the normals of each triangle from its vertices via cross product.
#define CONSOLE_BRIDGE_logError(fmt,...)
Mesh * createMeshFromResource(const std::string &resource)
Load a mesh from a resource that contains a mesh that can be loaded by assimp.
void writeSTLBinary(const Mesh *mesh, std::vector< char > &buffer)
Write the mesh to a buffer in STL format.
Definition of a triangle mesh By convention the "center" of the shape is at the origin. For a mesh this implies that the AABB of the mesh is centered at the origin. Some methods may not work with arbitrary meshes whose AABB is not centered at the origin.
Definition of a box Aligned with the XYZ axes.
Mesh * createMeshFromBinary(const char *buffer, std::size_t size, const std::string &assimp_hint=std::string())
Load a mesh from a binary stream that contains a mesh that can be loaded by assimp.
Mesh * createMeshFromAsset(const aiScene *scene, const Eigen::Vector3d &scale, const std::string &assimp_hint=std::string())
Load a mesh from an assimp datastructure.
double radius
The radius of the sphere.
Mesh * createMeshFromShape(const Shape *shape)
Construct a mesh from a primitive shape that is NOT already a mesh. This call allocates a new object...