7 #include "imstkAssimpMeshIO.h" 8 #include "imstkLineMesh.h" 9 #include "imstkLogger.h" 10 #include "imstkMeshIO.h" 11 #include "imstkSurfaceMesh.h" 12 #include "imstkVecDataArray.h" 14 #include <assimp/Importer.hpp> 15 #include <assimp/mesh.h> 16 #include <assimp/postprocess.h> 17 #include <assimp/scene.h> 21 std::shared_ptr<PointSet>
23 const std::string& filePath,
28 case MeshFileType::OBJ:
29 case MeshFileType::DAE:
30 case MeshFileType::FBX:
31 case MeshFileType::_3DS:
35 LOG(WARNING) <<
"Error: file type not supported for input " << filePath;
41 std::shared_ptr<PointSet>
45 Assimp::Importer importer;
49 CHECK(scene !=
nullptr && scene->HasMeshes()) <<
"Error: could not read with Assimp reader for input " << filePath;
52 aiMesh* importedMesh = scene->mMeshes[0];
53 if (scene->mNumMeshes > 1)
55 LOG(WARNING) <<
"Warning: file " << filePath <<
" contains more than one mesh. Using the first, dropping the rest.";
61 LOG(WARNING) <<
"Error: Invalid mesh. Input: " << filePath;
67 std::shared_ptr<PointSet>
71 auto numVertices = importedMesh->mNumVertices;
72 auto numFaces = importedMesh->mNumFaces;
76 LOG(WARNING) <<
"Error: mesh has no vertices.";
81 std::shared_ptr<VecDataArray<double, 3>> verticesPtr = std::make_shared<VecDataArray<double, 3>>(numVertices);
84 for (
unsigned int i = 0; i < numVertices; i++)
86 auto positionX = importedMesh->mVertices[i].x;
87 auto positionY = importedMesh->mVertices[i].y;
88 auto positionZ = importedMesh->mVertices[i].z;
89 vertices[i] = Vec3d(positionX, positionY, positionZ);
97 bool hasGreaterThanTriangle =
false;
98 for (
unsigned int i = 0; i < numFaces; i++)
100 aiFace cell = importedMesh->mFaces[i];
101 numTris +=
static_cast<int>(cell.mNumIndices == 3);
102 numLines +=
static_cast<int>(cell.mNumIndices == 2);
103 if (cell.mNumIndices > 3)
105 hasGreaterThanTriangle =
true;
110 if (hasGreaterThanTriangle)
112 LOG(WARNING) <<
"assimp reader found file with unsupported index counts. Dropping those cells.";
123 if (numTris == 0 && numLines > 0)
125 auto cellsPtr = std::make_shared<VecDataArray<int, 2>>(numLines);
129 for (
unsigned int i = 0; i < numFaces; i++)
131 aiFace triangle = importedMesh->mFaces[i];
132 unsigned int* indices = triangle.mIndices;
133 if (triangle.mNumIndices == 2)
135 cells[j++] = Vec2i(indices[0], indices[1]);
138 auto lineMesh = std::make_shared<LineMesh>();
139 lineMesh->initialize(verticesPtr, cellsPtr);
145 auto cellsPtr = std::make_shared<VecDataArray<int, 3>>(numTris);
149 for (
unsigned int i = 0; i < numFaces; i++)
151 aiFace triangle = importedMesh->mFaces[i];
152 unsigned int* indices = triangle.mIndices;
153 if (triangle.mNumIndices == 3)
155 cells[j++] = Vec3i(indices[0], indices[1], indices[2]);
160 std::shared_ptr<VecDataArray<double, 3>> normalsPtr = std::make_shared<VecDataArray<double, 3>>(numVertices);
162 std::shared_ptr<VecDataArray<float, 3>> tangentsPtr = std::make_shared<VecDataArray<float, 3>>(numVertices);
164 std::shared_ptr<VecDataArray<double, 3>> bitangentsPtr = std::make_shared<VecDataArray<double, 3>>(numVertices);
167 if (importedMesh->HasNormals())
169 for (
unsigned int i = 0; i < numVertices; i++)
171 auto normalX = importedMesh->mNormals[i].x;
172 auto normalY = importedMesh->mNormals[i].y;
173 auto normalZ = importedMesh->mNormals[i].z;
174 normals[i] = Vec3d(normalX, normalY, normalZ);
178 auto surfMesh = std::make_shared<SurfaceMesh>();
179 surfMesh->initialize(verticesPtr, cellsPtr, normalsPtr,
false);
180 surfMesh->setVertexNormals(
"normals", normalsPtr);
182 if (importedMesh->HasTangentsAndBitangents() && importedMesh->HasTextureCoords(0))
184 for (
unsigned int i = 0; i < numVertices; i++)
186 auto tangentX = importedMesh->mTangents[i].x;
187 auto tangentY = importedMesh->mTangents[i].y;
188 auto tangentZ = importedMesh->mTangents[i].z;
189 tangents[i] = Vec3f(tangentX, tangentY, tangentZ);
191 auto bitangentX = importedMesh->mBitangents[i].x;
192 auto bitangentY = importedMesh->mBitangents[i].y;
193 auto bitangentZ = importedMesh->mBitangents[i].z;
194 bitangents[i] = Vec3d(bitangentX, bitangentY, bitangentZ);
196 surfMesh->setVertexTangents(
"tangents", tangentsPtr);
200 if (importedMesh->HasTextureCoords(0))
202 std::shared_ptr<VecDataArray<float, 2>> UVs = std::make_shared<VecDataArray<float, 2>>(numVertices);
205 auto texcoords = importedMesh->mTextureCoords[0];
206 for (
unsigned int i = 0; i < numVertices; i++)
208 UVData[i][0] = texcoords[i].x;
209 UVData[i][1] = texcoords[i].y;
211 surfMesh->setVertexTCoords(
"tCoords", UVs);
220 unsigned int postProcessSteps =
221 aiPostProcessSteps::aiProcess_GenSmoothNormals |
222 aiPostProcessSteps::aiProcess_CalcTangentSpace |
223 aiPostProcessSteps::aiProcess_JoinIdenticalVertices |
224 aiPostProcessSteps::aiProcess_Triangulate |
225 aiPostProcessSteps::aiProcess_ImproveCacheLocality;
227 return postProcessSteps;
static std::shared_ptr< PointSet > read(const std::string &filePath, MeshFileType type)
Ensures file can be read and reads it if possible.
MeshFileType
Enumeration the mesh file type.
static unsigned int getDefaultPostProcessSteps()
Helper function for getting default post processing flags.
static std::shared_ptr< PointSet > convertAssimpMesh(aiMesh *importedMesh)
Convert from Assimp mesh to iMSTK SurfaceMesh. May convert to LineMesh if no triangles & only lines a...
static std::shared_ptr< PointSet > readMeshData(const std::string &filePath)
Reads mesh data and returns mesh. May read a LineMesh if no triangles & only lines are present...