Commit f859365b authored by Nicholas Milef's avatar Nicholas Milef Committed by Alexis Girault

ENH: Added Assimp support to improve mesh reading

Co-Authored-By: Alexis Girault's avatarAlexis Girault <alexis.girault@kitware.com>
parent bf875be2
......@@ -5,6 +5,7 @@ include(imstkAddLibrary)
imstk_add_library( Geometry
DEPENDS
Core
Assimp
VegaFEM::volumetricMesh
${VTK_LIBRARIES}
)
......
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& Imaging in Medicine, Rensselaer Polytechnic Institute.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
#include "imstkAssimpMeshIO.h"
#include "g3log/g3log.hpp"
namespace imstk
{
std::shared_ptr<SurfaceMesh>
AssimpMeshIO::read(const std::string& filePath, MeshFileType type)
{
switch (type)
{
case MeshFileType::OBJ :
case MeshFileType::DAE :
case MeshFileType::FBX :
case MeshFileType::_3DS :
return AssimpMeshIO::readMeshData(filePath);
break;
default :
LOG(WARNING) << "AssimpMeshIO::read error: file type not supported";
return nullptr;
break;
}
}
std::shared_ptr<SurfaceMesh>
AssimpMeshIO::readMeshData(const std::string& filePath)
{
// Importer mesh(es) and apply some clean-up operations
Assimp::Importer importer;
auto scene = importer.ReadFile(filePath,
aiPostProcessSteps::aiProcess_GenSmoothNormals |
aiPostProcessSteps::aiProcess_CalcTangentSpace |
aiPostProcessSteps::aiProcess_JoinIdenticalVertices |
aiPostProcessSteps::aiProcess_Triangulate);
// Check if there is actually a mesh or if the file can be read
if (!scene || !scene->HasMeshes())
{
LOG(WARNING) << "AssimpMeshIO::readMeshData error: could not read with reader.";
return nullptr;
}
// Get first mesh
auto importedMesh = scene->mMeshes[0];
// Build SurfaceMesh
auto mesh = std::make_shared<SurfaceMesh>();
// Get mesh information
auto numVertices = importedMesh->mNumVertices;
auto numTriangles = importedMesh->mNumFaces;
if (numVertices == 0)
{
LOG(WARNING) << "AssimpMeshIO::readMeshData error: mesh has no vertices.";
return nullptr;
}
// Vertex positions
StdVectorOfVec3d positions(numVertices);
for (unsigned int i = 0; i < numVertices; i++)
{
auto positionX = importedMesh->mVertices[i].x;
auto positionY = importedMesh->mVertices[i].y;
auto positionZ = importedMesh->mVertices[i].z;
positions[i] = Vec3d(positionX, positionY, positionZ);
}
// Triangles
std::vector<SurfaceMesh::TriangleArray> triangles(numTriangles);
for (unsigned int i = 0; i < numTriangles; i++)
{
auto triangle = importedMesh->mFaces[i];
auto indices = triangle.mIndices;
triangles[i][0] = indices[0];
triangles[i][1] = indices[1];
triangles[i][2] = indices[2];
}
mesh->initialize(positions, triangles, false);
// Vertex normals, tangents, and bitangents
StdVectorOfVec3d normals(numVertices);
StdVectorOfVec3d tangents(numVertices);
StdVectorOfVec3d bitangents(numVertices);
if (importedMesh->HasNormals())
{
for (unsigned int i = 0; i < numVertices; i++)
{
auto normalX = importedMesh->mNormals[i].x;
auto normalY = importedMesh->mNormals[i].y;
auto normalZ = importedMesh->mNormals[i].z;
normals[i] = Vec3d(normalX, normalY, normalZ);
}
}
if (importedMesh->HasTangentsAndBitangents())
{
for (unsigned int i = 0; i < numVertices; i++)
{
auto tangentX = importedMesh->mTangents[i].x;
auto tangentY = importedMesh->mTangents[i].y;
auto tangentZ = importedMesh->mTangents[i].z;
tangents[i] = Vec3d(tangentX, tangentY, tangentZ);
auto bitangentX = importedMesh->mBitangents[i].x;
auto bitangentY = importedMesh->mBitangents[i].y;
auto bitangentZ = importedMesh->mBitangents[i].z;
bitangents[i] = Vec3d(bitangentX, bitangentY, bitangentZ);
}
}
mesh->setVertexNormals(normals);
mesh->setVertexTangents(tangents);
mesh->setVertexBitangents(bitangents);
// UV coordinates normals
StdVectorOfVectorf UVs(numVertices);
if (importedMesh->HasTextureCoords(0))
{
auto texcoords = importedMesh->mTextureCoords[0];
for (unsigned int i = 0; i < numVertices; i++)
{
Vectorf UV(2);
UV[0] = texcoords[i].x;
UV[1] = texcoords[i].y;
UVs[i] = UV;
}
}
mesh->setDefaultTCoords("tCoords");
mesh->setPointDataArray("tCoords",UVs);
return mesh;
}
}
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& Imaging in Medicine, Rensselaer Polytechnic Institute.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
#ifndef imstkAssimpMeshIO_h
#define imstkAssimpMeshIO_h
#include "imstkSurfaceMesh.h"
#include "imstkMeshIO.h"
#include "assimp/Importer.hpp"
#include "assimp/mesh.h"
#include "assimp/scene.h"
#include "assimp/postprocess.h"
namespace imstk
{
///
/// \class AssimpMeshIO
///
/// \brief Assimp reader for surface meshes
///
class AssimpMeshIO
{
public:
///
/// \brief Ensures file can be read and reads it if possible
/// \param filePath path to file
/// \param type mesh file type
///
static std::shared_ptr<SurfaceMesh> read(const std::string& filePath, MeshFileType type);
protected:
///
/// \brief Reads mesh data and returns mesh
/// \param filePath
///
static std::shared_ptr<SurfaceMesh> readMeshData(const std::string& filePath);
};
}
#endif
......@@ -23,6 +23,7 @@
#include "imstkMeshIO.h"
#include "imstkVTKMeshIO.h"
#include "imstkAssimpMeshIO.h"
#include "imstkVegaMeshIO.h"
#include "imstkMSHMeshIO.h"
......@@ -48,9 +49,14 @@ MeshIO::read(const std::string& filePath)
case MeshFileType::VTP :
case MeshFileType::STL :
case MeshFileType::PLY :
case MeshFileType::OBJ :
return VTKMeshIO::read(filePath, meshType);
break;
case MeshFileType::OBJ :
case MeshFileType::DAE :
case MeshFileType::FBX :
case MeshFileType::_3DS :
return AssimpMeshIO::read(filePath, meshType);
break;
case MeshFileType::VEG :
return VegaMeshIO::read(filePath, meshType);
break;
......@@ -106,6 +112,18 @@ MeshIO::getFileType(const std::string& filePath)
{
meshType = MeshFileType::PLY;
}
else if (extString == "dae" || extString == "DAE")
{
meshType = MeshFileType::DAE;
}
else if (extString == "fbx" || extString == "FBX")
{
meshType = MeshFileType::FBX;
}
else if (extString == "3ds" || extString == "3DS")
{
meshType = MeshFileType::_3DS;
}
else if (extString == "veg" || extString == "VEG")
{
meshType = MeshFileType::VEG;
......
......@@ -45,6 +45,9 @@ enum MeshFileType
STL,
PLY,
OBJ,
DAE,
FBX,
_3DS,
VEG,
MSH
};
......
#-----------------------------------------------------------------------------
# Add External Project
#-----------------------------------------------------------------------------
include(imstkAddExternalProject)
imstk_add_external_project( Assimp
GIT_REPOSITORY https://github.com/assimp/assimp.git
GIT_TAG v3.3.1
INSTALL_COMMAND ${SKIP_STEP_COMMAND}
CMAKE_ARGS
-DASSIMP_BUILD_ASSIMP_TOOLS:BOOL=OFF
-DASSIMP_NO_EXPORT:BOOL=ON
-DLIBRARY_SUFFIX:STRING=
RELATIVE_INCLUDE_PATH "include"
#DEPENDENCIES ""
#VERBOSE
)
#-----------------------------------------------------------------------------
# Find path
#-----------------------------------------------------------------------------
find_path(Assimp_INCLUDE_DIRS
NAMES
assimp/Importer.hpp
)
mark_as_advanced(Assimp_INCLUDE_DIRS)
#-----------------------------------------------------------------------------
# Find library
#-----------------------------------------------------------------------------
find_library(Assimp_LIBRARIES
NAMES
libassimp
assimp
libassimpd
assimpd
)
mark_as_advanced(Assimp_LIBRARIES)
#-----------------------------------------------------------------------------
# Find package
#-----------------------------------------------------------------------------
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Assimp
REQUIRED_VARS
Assimp_INCLUDE_DIRS
Assimp_LIBRARIES)
#-----------------------------------------------------------------------------
# If missing target, create it
#-----------------------------------------------------------------------------
if(Assimp_FOUND AND NOT TARGET Assimp)
add_library(Assimp INTERFACE IMPORTED)
set_target_properties(Assimp PROPERTIES
INTERFACE_LINK_LIBRARIES "${Assimp_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${Assimp_INCLUDE_DIRS}"
)
endif()
......@@ -89,6 +89,7 @@ if(${PROJECT_NAME}_SUPERBUILD)
imstk_define_dependency(FTD2XX) #for LibNiFalcon
endif()
imstk_define_dependency(Assimp)
imstk_define_dependency(g3log)
imstk_define_dependency(Eigen)
imstk_define_dependency(SCCD)
......@@ -136,6 +137,10 @@ endif()
find_program(Uncrustify_EXECUTABLE Uncrustify)
include(SetupUncrustifyConfig)
# Assimp
find_package( Assimp REQUIRED )
include_directories( ${Assimp_INCLUDE_DIRS} )
# g3log
find_package( g3log REQUIRED )
include_directories( ${g3log_INCLUDE_DIR} )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment