diff --git a/IO/CMakeLists.txt b/IO/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..75392f8fe006488315d867a9a5db8efb7805ee73 --- /dev/null +++ b/IO/CMakeLists.txt @@ -0,0 +1,29 @@ + +simmedtk_add_library(IO + SOURCES + IOMesh.cpp + IOMeshAssimpDelegate.cpp + IOMeshVegaDelegate.cpp + IOMeshVTKDelegate.cpp + PUBLIC_HEADERS + Mesh.h + SurfaceMesh.h + VolumeMesh.h + VegaSceneObject.h + VegaSceneObjectDeformable.h + VegaSceneObjectWithRestPosition.h +) + +target_link_libraries(Mesh + PRIVATE + Core + Rendering + PUBLIC + Assimp::Assimp + VegaFEM::minivector + VegaFEM::volumetricMesh + ) + +if(BUILD_TESTING) + add_subdirectory(UnitTests) +endif() diff --git a/InputOutput/IOMesh.cpp b/IO/IOMesh.cpp similarity index 77% rename from InputOutput/IOMesh.cpp rename to IO/IOMesh.cpp index 79d2f00c214da645ae4ab674749e3463214582d6..c7dd2dd043f8e096830d1a2752aff96133209d39 100644 --- a/InputOutput/IOMesh.cpp +++ b/IO/IOMesh.cpp @@ -23,11 +23,13 @@ #include"IOMesh.h" -IOMesh::IOMesh(IOMesh::ReaderGroup priorityGroup) : mesh(nullptr), fileName(""), fileType(MeshFileType::Unknown) +IOMesh::IOMesh(IOMesh::ReaderGroup priorityGroup) : fileName(""), fileType(MeshFileType::Unknown), mesh(nullptr) { + // + // VTK io for some vtk files (use only vtk to read these files) delegatorList[MeshFileType::VTK] = [](std::shared_ptr<IOMesh> source) { - auto delegate = Factory<IODelegate>::createDefault("VTKMeshReaderDelegate"); + auto delegate = Factory<IOMeshDelegate>::createDefault("VTKMeshReaderDelegate"); if(delegate) { delegate->setSource(source); @@ -36,7 +38,7 @@ IOMesh::IOMesh(IOMesh::ReaderGroup priorityGroup) : mesh(nullptr), fileName(""), }; delegatorList[MeshFileType::VTU] = [](std::shared_ptr<IOMesh> source) { - auto delegate = Factory<IODelegate>::createDefault("VTKMeshReaderDelegate"); + auto delegate = Factory<IOMeshDelegate>::createDefault("VTKMeshReaderDelegate"); if(delegate) { delegate->setSource(source); @@ -45,34 +47,29 @@ IOMesh::IOMesh(IOMesh::ReaderGroup priorityGroup) : mesh(nullptr), fileName(""), }; delegatorList[MeshFileType::VTP] = [](std::shared_ptr<IOMesh> source) { - auto delegate = Factory<IODelegate>::createDefault("VTKMeshReaderDelegate"); - if(delegate) - { - delegate->setSource(source); - } - return delegate; - }; - delegatorList[MeshFileType::VTP] = [](std::shared_ptr<IOMesh> source) - { - auto delegate = Factory<IODelegate>::createDefault("VTKMeshReaderDelegate"); + auto delegate = Factory<IOMeshDelegate>::createDefault("VTKMeshReaderDelegate"); if(delegate) { delegate->setSource(source); } return delegate; }; + // + // Set the vega io, only vega can read/write those files delegatorList[MeshFileType::VEG] = [](std::shared_ptr<IOMesh> source) { - auto delegate = Factory<IODelegate>::createDefault("VegaMeshDelegate"); + auto delegate = Factory<IOMeshDelegate>::createDefault("VegaMeshDelegate"); if(delegate) { delegate->setSource(source); } return delegate; }; + // + // The readers for obj,stl and ply are based on a priority group (defaults to vtk io's) delegatorList[MeshFileType::OBJ] = [](std::shared_ptr<IOMesh> source) { - auto delegate = Factory<IODelegate>::createSubclassForGroup("IODelegate",priorityGroup); + auto delegate = Factory<IOMeshDelegate>::createSubclassForGroup("IOMeshDelegate",priorityGroup); if(delegate) { delegate->setSource(source); @@ -81,7 +78,7 @@ IOMesh::IOMesh(IOMesh::ReaderGroup priorityGroup) : mesh(nullptr), fileName(""), }; delegatorList[MeshFileType::STL] = [](std::shared_ptr<IOMesh> source) { - auto delegate = Factory<IODelegate>::createSubclassForGroup("IODelegate",priorityGroup); + auto delegate = Factory<IOMeshDelegate>::createSubclassForGroup("IOMeshDelegate",priorityGroup); if(delegate) { delegate->setSource(source); @@ -90,7 +87,7 @@ IOMesh::IOMesh(IOMesh::ReaderGroup priorityGroup) : mesh(nullptr), fileName(""), }; delegatorList[MeshFileType::PLY] = [](std::shared_ptr<IOMesh> source) { - auto delegate = Factory<IODelegate>::createSubclassForGroup("IODelegate",priorityGroup); + auto delegate = Factory<IOMeshDelegate>::createSubclassForGroup("IOMeshDelegate",priorityGroup); if(delegate) { delegate->setSource(source); @@ -99,7 +96,7 @@ IOMesh::IOMesh(IOMesh::ReaderGroup priorityGroup) : mesh(nullptr), fileName(""), }; delegatorList[MeshFileType::Unknown] = [](std::shared_ptr<IOMesh> source) { - auto delegate = Factory<IODelegate>::createSubclassForGroup("IODelegate",ReaderGroup::Assimp); + auto delegate = Factory<IOMeshDelegate>::createSubclassForGroup("IOMeshDelegate",ReaderGroup::Assimp); if(delegate) { delegate->setSource(source); @@ -119,7 +116,7 @@ void IOMesh::read(const std::string& filePath) } else { - std::cerr << "Error: Invalid reader!" << std::endl; + std::cerr << "Error: No reader found for " << this->fileName << std::endl; } } diff --git a/InputOutput/IOMesh.h b/IO/IOMesh.h similarity index 73% rename from InputOutput/IOMesh.h rename to IO/IOMesh.h index c90c82281a1db2f6a490a18f58b1683f988c80d4..95f76ead651d2b403a69da7d9d44fba8c1faa0ce 100644 --- a/InputOutput/IOMesh.h +++ b/IO/IOMesh.h @@ -28,14 +28,23 @@ #include <memory> #include <unordered_map> -#include "InputOutput/IODelegate.h" +#include "InputOutput/IOMeshDelegate.h" #include "Core/Factory.h" #include "Core/BaseMesh.h" -class IOMesh : public std::enable_shared_from_this<IOMesh> +/// +/// \brief Mesh input/output class. This class is used to read meshes on several formats. +/// Users can add more readers by implementing delegates for a particular reader +/// \see \VTKMeshDelegate, \VegaMeshDelegarte and \AssimpMeshDelegate +/// +class IOMesh { - typedef std::function<std::shared_ptr<IODelegate>(std::shared_ptr<IOMesh>)> DelegatorType; + typedef std::function<std::shared_ptr<IOMeshDelegate>(std::shared_ptr<IOMesh>)> DelegatorType; public: + /// + /// \brief Enum class for the type of files this mesh io expect, + /// add more types here to extend the mesh io. + /// enum class MeshFileType { VTK, @@ -48,6 +57,10 @@ public: Unknown }; + + /// + /// \brief Enum class for the readers group. Used to prioritize the io delegates in the factory. + /// enum class ReaderGroup : int { VTK, @@ -55,6 +68,10 @@ public: Vega, Other }; + + /// + /// \brief Constructor/Destructors + /// IOMesh(ReaderGroup priorityGroup = ReaderGroup::VTK); ~IOMesh(); @@ -89,9 +106,16 @@ public: const MeshFileType &getFileType() const; private: - std::shared_ptr<Core::BaseMesh> mesh; + // Storage for the mesh file name, used by delegates. std::string fileName; + + // Storage for the file type, used by delegates. MeshFileType fileType; + + // Mesh pointer. + std::shared_ptr<Core::BaseMesh> mesh; + + // Map file types with reader delegates. std::unordered_map<MeshFileType,DelegatorType> delegatorList; }; diff --git a/InputOutput/AssimpMeshDelegate.cpp b/IO/IOMeshAssimpDelegate.cpp similarity index 90% rename from InputOutput/AssimpMeshDelegate.cpp rename to IO/IOMeshAssimpDelegate.cpp index da09f9fd7e6fc68c2d32c7343b4b1d39c5debf63..aa8bdf8cdbbae0fedb6520dfe593c494fea887c7 100644 --- a/InputOutput/AssimpMeshDelegate.cpp +++ b/IO/IOMeshAssimpDelegate.cpp @@ -23,14 +23,15 @@ #include "Core/Factory.h" -#include "InputOutput/IODelegate.h" +#include "InputOutput/IOMeshDelegate.h" +#include "Mesh/SurfaceMesh.h" // Assimp includes #include <assimp/Importer.hpp> #include <assimp/scene.h> #include <assimp/postprocess.h> -class AssimpMeshDelegate : IODelegate +class AssimpMeshDelegate : IOMeshDelegate { public: void read() @@ -61,7 +62,8 @@ public: // Extract the information from the aiScene's mesh objects aiMesh *mesh = scene->mMeshes[0]; //Guarenteed to have atleast one mesh - auto &vertices = this->meshIO->getMesh()->getVertices(); + auto localMesh = std::make_shared<SurfaceMesh>(); + auto &vertices = localMesh->getVertices(); vertices.reserve(mesh->mNumVertices); @@ -72,7 +74,7 @@ public: mesh->mVertices[i][1], mesh->mVertices[i][2]); } - this->meshIO->getMesh()->updateOriginalVertsWithCurrent(); + localMesh->updateOriginalVertsWithCurrent(); // Get indexed texture coordinate data if (mesh->HasTextureCoords(0)) @@ -93,7 +95,7 @@ public: } } - auto &triangles = this->meshIO->getMesh()->getTriangles(); + auto &triangles = localMesh->getTriangles(); triangles.reserve(mesh->mNumFaces); // Setup triangle/face data @@ -111,13 +113,13 @@ public: mesh->mFaces[i].mIndices[2]); } - return true; + this->meshIO->setMesh(localMesh); } void write(){} }; SIMMEDTK_BEGIN_DYNAMIC_LOADER() SIMMEDTK_BEGIN_ONLOAD(register_AssimpMeshReaderDelegate) - SIMMEDTK_REGISTER_CLASS(IODelegate,IODelegate,AssimpMeshDelegate,IOMesh::ReaderGroup::Assimp); + SIMMEDTK_REGISTER_CLASS(IOMeshDelegate,IOMeshDelegate,AssimpMeshDelegate,IOMesh::ReaderGroup::Assimp); SIMMEDTK_FINISH_ONLOAD() SIMMEDTK_FINISH_DYNAMIC_LOADER() diff --git a/InputOutput/IODelegate.h b/IO/IOMeshDelegate.h similarity index 94% rename from InputOutput/IODelegate.h rename to IO/IOMeshDelegate.h index 9b3473bdeb194a4b744ace4aedf74de7890d028d..8b726707a129116af1ec5721a3c2bd72539a1794 100644 --- a/InputOutput/IODelegate.h +++ b/IO/IOMeshDelegate.h @@ -30,10 +30,10 @@ #include "InputOutput/IOMesh.h" #include "Core/Config.h" -class IODelegate +class IOMeshDelegate { public: - typedef std::shared_ptr<IODelegate> Ptr; + typedef std::shared_ptr<IOMeshDelegate> Ptr; public: setSource(std::shared_ptr<IOMesh> src) diff --git a/InputOutput/VTKMeshDelegate.cpp b/IO/IOMeshVTKDelegate.cpp similarity index 97% rename from InputOutput/VTKMeshDelegate.cpp rename to IO/IOMeshVTKDelegate.cpp index 0b91e6d012abb96780ce490df59d140d798a998a..2ae133052363db484b5f0e575391d7213cc201a5 100644 --- a/InputOutput/VTKMeshDelegate.cpp +++ b/IO/IOMeshVTKDelegate.cpp @@ -22,7 +22,7 @@ // Contact: //--------------------------------------------------------------------------- -#include "InputOutput/IODelegate.h" +#include "InputOutput/IOMeshDelegate.h" #include "Core/Factory.h" // VTK includes @@ -36,7 +36,7 @@ #include <vtkPLYReader.h> #include <vtkSTLReader.h> -class VTKMeshDelegate : IODelegate +class VTKMeshDelegate : IOMeshDelegate { public: void read() @@ -203,6 +203,6 @@ public: SIMMEDTK_BEGIN_DYNAMIC_LOADER() SIMMEDTK_BEGIN_ONLOAD(register_VTKMeshReaderDelegate) -SIMMEDTK_REGISTER_CLASS(IODelegate, IODelegate, VTKMeshDelegate, IOMesh::ReaderGroup::VTK); +SIMMEDTK_REGISTER_CLASS(IOMeshDelegate, IOMeshDelegate, VTKMeshDelegate, IOMesh::ReaderGroup::VTK); SIMMEDTK_FINISH_ONLOAD() SIMMEDTK_FINISH_DYNAMIC_LOADER() diff --git a/InputOutput/VegaMeshDelegate.cpp b/IO/IOMeshVegaDelegate.cpp similarity index 92% rename from InputOutput/VegaMeshDelegate.cpp rename to IO/IOMeshVegaDelegate.cpp index c75981785e560abc15701232c00dc9d09caa7955..225773ff775a058d946f09c79c3cb7e9f9b40be2 100644 --- a/InputOutput/VegaMeshDelegate.cpp +++ b/IO/IOMeshVegaDelegate.cpp @@ -25,7 +25,7 @@ #include "Core/Factory.h" -#include "InputOutput/IODelegate.h" +#include "InputOutput/IOMeshDelegate.h" #include "Mesh//VegaVolumetricMesh.h" // Vega includes @@ -33,7 +33,7 @@ #include "cubicMesh.h" #include "tetMesh.h" -class VegaMeshDelegate : IODelegate +class VegaMeshDelegate : IOMeshDelegate { public: void read() @@ -72,6 +72,6 @@ public: SIMMEDTK_BEGIN_DYNAMIC_LOADER() SIMMEDTK_BEGIN_ONLOAD(register_VegaMeshReaderDelegate) -SIMMEDTK_REGISTER_CLASS(IODelegate, IODelegate, VegaMeshDelegate, IOMesh::ReaderGroup::Vega); +SIMMEDTK_REGISTER_CLASS(IOMeshDelegate, IOMeshDelegate, VegaMeshDelegate, IOMesh::ReaderGroup::Vega); SIMMEDTK_FINISH_ONLOAD() SIMMEDTK_FINISH_DYNAMIC_LOADER() diff --git a/InputOutput/CMakeLists.txt b/InputOutput/CMakeLists.txt deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000