diff --git a/Examples/VolumeRendering/VolumeRenderingExample.cpp b/Examples/VolumeRendering/VolumeRenderingExample.cpp index efc5dabc4567e2a76bad36f2656d7c6a8ac11e68..f4941787e1c85d58aff8fa43562257164fda97c9 100644 --- a/Examples/VolumeRendering/VolumeRenderingExample.cpp +++ b/Examples/VolumeRendering/VolumeRenderingExample.cpp @@ -22,6 +22,7 @@ #include "imstkCamera.h" #include "imstkImageData.h" #include "imstkKeyboardSceneControl.h" +#include "imstkLogger.h" #include "imstkMeshIO.h" #include "imstkMouseSceneControl.h" #include "imstkNew.h" @@ -44,6 +45,8 @@ using namespace imstk; int main() { + Logger::startLogger(); + // SDK and Scene imstkNew<Scene> scene("VolumeRendering"); diff --git a/Source/DynamicalModels/ObjectModels/imstkSPHModel.cpp b/Source/DynamicalModels/ObjectModels/imstkSPHModel.cpp index 1f7199aa59205e81f3ce26b731e13045ee5a893f..e9b3f59b35bd59bf9061227f2c392eee2411a4ed 100644 --- a/Source/DynamicalModels/ObjectModels/imstkSPHModel.cpp +++ b/Source/DynamicalModels/ObjectModels/imstkSPHModel.cpp @@ -886,7 +886,7 @@ SPHModel::writeStateToVtk() VTKMeshIO vtkWriter; std::string filePath = std::string("sph_output_") + std::to_string(m_totalTime) + std::string(".vtu"); - vtkWriter.write(m_geomUnstructuredGrid, filePath, VTU); + vtkWriter.write(m_geomUnstructuredGrid, filePath, MeshFileType::VTU); m_vtkTimeModulo += m_writeToOutputModulo; m_vtkPreviousTime = m_totalTime; diff --git a/Source/MeshIO/imstkMeshIO.cpp b/Source/MeshIO/imstkMeshIO.cpp index 79663bb56f5d68ef668f49a6fd32b84b1c20e042..adb53e471231d1af1bef5c04b788edb9194ebc2e 100644 --- a/Source/MeshIO/imstkMeshIO.cpp +++ b/Source/MeshIO/imstkMeshIO.cpp @@ -29,9 +29,29 @@ #include "imstkVTKMeshIO.h" #include <sys/stat.h> +#include <unordered_map> namespace imstk { +static std::unordered_map<std::string, MeshFileType> extToType = +{ + { "vtk", MeshFileType::VTK }, + { "vtp", MeshFileType::VTP }, + { "vtu", MeshFileType::VTU }, + { "obj", MeshFileType::OBJ }, + { "stl", MeshFileType::STL }, + { "ply", MeshFileType::PLY }, + { "dae", MeshFileType::DAE }, + { "fbx", MeshFileType::FBX }, + { "3ds", MeshFileType::_3DS }, + { "veg", MeshFileType::VEG }, + { "msh", MeshFileType::MSH }, + { "dcm", MeshFileType::DCM }, + { "nrrd", MeshFileType::NRRD }, + { "nii", MeshFileType::NII }, + { "mhd", MeshFileType::MHD } +}; + std::shared_ptr<PointSet> MeshIO::read(const std::string& filePath) { @@ -54,6 +74,7 @@ MeshIO::read(const std::string& filePath) case MeshFileType::NRRD: case MeshFileType::NII: case MeshFileType::DCM: + case MeshFileType::MHD: return VTKMeshIO::read(filePath, meshType); break; case MeshFileType::OBJ: @@ -68,7 +89,7 @@ MeshIO::read(const std::string& filePath) case MeshFileType::MSH: return MSHMeshIO::read(filePath, meshType); break; - case UNKNOWN: + case MeshFileType::UNKNOWN: default: break; } @@ -102,74 +123,20 @@ MeshIO::fileExists(const std::string& file, bool& isDirectory) const MeshFileType MeshIO::getFileType(const std::string& filePath) { - MeshFileType meshType = MeshFileType::UNKNOWN; - std::string extString = filePath.substr(filePath.find_last_of(".") + 1); CHECK(!extString.empty()) << "MeshIO::getFileType error: invalid file name"; - if (extString == "vtk" || extString == "VTK") - { - meshType = MeshFileType::VTK; - } - else if (extString == "vtp" || extString == "VTP") - { - meshType = MeshFileType::VTP; - } - else if (extString == "vtu" || extString == "VTU") - { - meshType = MeshFileType::VTU; - } - else if (extString == "obj" || extString == "OBJ") - { - meshType = MeshFileType::OBJ; - } - else if (extString == "stl" || extString == "STL") - { - meshType = MeshFileType::STL; - } - else if (extString == "ply" || extString == "PLY") - { - 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; - } - else if (extString == "msh" || extString == "MSH") - { - meshType = MeshFileType::MSH; - } - else if (extString == "dcm" || extString == "DCM") - { - meshType = MeshFileType::DCM; - } - else if (extString == "nrrd" || extString == "NRRD") - { - meshType = MeshFileType::NRRD; - } - else if (extString == "nii" || extString == "NII") - { - meshType = MeshFileType::NII; - } - else + // To lowercase + std::transform(extString.begin(), extString.end(), extString.begin(), + [](unsigned char c) { return std::tolower(static_cast<int>(c)); }); + + if (extToType.count(extString) == 0) { LOG(FATAL) << "MeshIO::getFileType error: unknown file extension"; } - return meshType; + return extToType[extString]; } bool @@ -194,6 +161,7 @@ MeshIO::write(const std::shared_ptr<imstk::PointSet> imstkMesh, const std::strin case MeshFileType::VTP: case MeshFileType::STL: case MeshFileType::PLY: + case MeshFileType::MHD: return VTKMeshIO::write(imstkMesh, filePath, meshType); break; case MeshFileType::UNKNOWN: diff --git a/Source/MeshIO/imstkMeshIO.h b/Source/MeshIO/imstkMeshIO.h index 889ac9de5bf270d9d8b0af2ad44d795cb46640ee..3577b64d38ceaf7ede07db32258a3073ced48834 100644 --- a/Source/MeshIO/imstkMeshIO.h +++ b/Source/MeshIO/imstkMeshIO.h @@ -31,7 +31,7 @@ class PointSet; /// /// \brief Enumeration the mesh file type /// -enum MeshFileType +enum class MeshFileType { UNKNOWN, VTK, @@ -47,7 +47,8 @@ enum MeshFileType MSH, NRRD, DCM, - NII + NII, + MHD }; /// diff --git a/Source/MeshIO/imstkVTKMeshIO.cpp b/Source/MeshIO/imstkVTKMeshIO.cpp index 2356f502bd41d4231a2cf92171910f1d93ba84d4..0997d2f99c04cd21fefb2d78363da9e1a16e7306 100644 --- a/Source/MeshIO/imstkVTKMeshIO.cpp +++ b/Source/MeshIO/imstkVTKMeshIO.cpp @@ -32,6 +32,8 @@ #include <vtkGenericDataObjectReader.h> #include <vtkGenericDataObjectWriter.h> #include <vtkImageData.h> +#include <vtkMetaImageReader.h> +#include <vtkMetaImageWriter.h> #include <vtkNIFTIImageReader.h> #include <vtkNIFTIImageWriter.h> #include <vtkNrrdReader.h> @@ -91,6 +93,10 @@ VTKMeshIO::read(const std::string& filePath, MeshFileType meshType) { return VTKMeshIO::readVtkImageDataNIFTI(filePath); } + case MeshFileType::MHD: + { + return VTKMeshIO::readVtkImageData<vtkMetaImageReader>(filePath); + } default: { LOG(FATAL) << "VTKMeshIO::read error: file type not supported"; @@ -110,6 +116,10 @@ VTKMeshIO::write(const std::shared_ptr<PointSet> imstkMesh, const std::string& f { return VTKMeshIO::writeVtkImageDataNIFTI(imgMesh, filePath); } + case MeshFileType::MHD: + { + return VTKMeshIO::writeMetaImageData(imgMesh, filePath); + } default: LOG(WARNING) << "VTKMeshIO::write error: file type not supported for volumetric mesh."; return false; @@ -250,7 +260,14 @@ VTKMeshIO::writeVtkImageData(const std::shared_ptr<ImageData> imstkMesh, const s int* dim = vtkMesh->GetDimensions(); auto writer = vtkSmartPointer<WriterType>::New(); - writer->SetFileDimensionality(3); + if (vtkMesh->GetDimensions()[2] == 1) + { + writer->SetFileDimensionality(2); + } + else + { + writer->SetFileDimensionality(3); + } writer->SetInputData(vtkMesh); writer->SetFileName(filePath.c_str()); writer->Write(); @@ -385,9 +402,6 @@ VTKMeshIO::writeVtkUnstructuredGrid(std::shared_ptr<HexahedralMesh> hMesh, const return true; } -/// -/// \brief Reads vtk image data -/// template<typename ReaderType> std::shared_ptr<ImageData> VTKMeshIO::readVtkImageData(const std::string& filePath) @@ -400,9 +414,6 @@ VTKMeshIO::readVtkImageData(const std::string& filePath) return imageData; } -/// -/// \brief Reads nifti/nii format image data -/// std::shared_ptr<ImageData> VTKMeshIO::readVtkImageDataNIFTI(const std::string& filePath) { @@ -415,9 +426,6 @@ VTKMeshIO::readVtkImageDataNIFTI(const std::string& filePath) return imageData; } -/// -/// \brief Write nifti/nii format image data -/// bool VTKMeshIO::writeVtkImageDataNIFTI(std::shared_ptr<ImageData> imageData, const std::string& filePath) { @@ -431,9 +439,40 @@ VTKMeshIO::writeVtkImageDataNIFTI(std::shared_ptr<ImageData> imageData, const st auto writer = vtkSmartPointer<vtkNIFTIImageWriter>::New(); writer->SetFileName(filePath.c_str()); - writer->SetFileDimensionality(3); + if (vtkMesh->GetDimensions()[2] == 1) + { + writer->SetFileDimensionality(2); + } + else + { + writer->SetFileDimensionality(3); + } writer->SetInputData(vtkMesh); writer->Update(); return true; } + +bool +VTKMeshIO::writeMetaImageData(std::shared_ptr<ImageData> imageData, const std::string& filePath) +{ + vtkSmartPointer<vtkImageData> vtkMesh = GeometryUtils::copyToVtkImageData(imageData); + if (!vtkMesh) + { + return false; + } + + auto writer = vtkSmartPointer<vtkMetaImageWriter>::New(); + if (vtkMesh->GetDimensions()[2] == 1) + { + writer->SetFileDimensionality(2); + } + else + { + writer->SetFileDimensionality(3); + } + writer->SetInputData(vtkMesh); + writer->SetFileName(filePath.c_str()); + writer->SetRAWFileName((filePath + ".raw").c_str()); + writer->Write(); +} } // imstk diff --git a/Source/MeshIO/imstkVTKMeshIO.h b/Source/MeshIO/imstkVTKMeshIO.h index 92dbafda083db45a22578d26af6d9a24ba05707f..24b470ddcc399c7a8b0bcde3a1026e22e061cbe7 100644 --- a/Source/MeshIO/imstkVTKMeshIO.h +++ b/Source/MeshIO/imstkVTKMeshIO.h @@ -133,5 +133,10 @@ protected: /// \brief Write nifti/nii format image data /// static bool writeVtkImageDataNIFTI(std::shared_ptr<ImageData> imageData, const std::string& filePath); + + /// + /// \brief Write meta/mhd format image data + /// + static bool writeMetaImageData(std::shared_ptr<ImageData> imageData, const std::string& filePath); }; } // imstk