diff --git a/CMakeLists.txt b/CMakeLists.txt index c2b543d3..bb1b2b3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,11 +94,11 @@ ENDIF() SET(SNAP_VERSION_MAJOR 4) SET(SNAP_VERSION_MINOR 2) SET(SNAP_VERSION_PATCH 0) -SET(SNAP_VERSION_QUALIFIER "-rc.1") +SET(SNAP_VERSION_QUALIFIER "") # These fields should also be modified each time -SET(SNAP_VERSION_RELEASE_DATE "20240311") -SET(SNAP_VERSION_RELEASE_DATE_FORMATTED "March 11, 2024") +SET(SNAP_VERSION_RELEASE_DATE "20240422") +SET(SNAP_VERSION_RELEASE_DATE_FORMATTED "April 22, 2024") # This field should only change when the format of the settings files changes # in a non backwards-compatible way diff --git a/GUI/Qt/Windows/DropActionDialog.cxx b/GUI/Qt/Windows/DropActionDialog.cxx index f5d867cb..471ce7a7 100644 --- a/GUI/Qt/Windows/DropActionDialog.cxx +++ b/GUI/Qt/Windows/DropActionDialog.cxx @@ -21,8 +21,9 @@ #include "MeshImportWizard.h" #include "ImageIOWizardModel.h" #include "ImageIOWizard.h" -#include "GuidedNativeImageIO.h" +#include "GuidedMeshIO.h" #include +#include DropActionDialog::DropActionDialog(QWidget *parent) : QDialog(parent), @@ -42,21 +43,50 @@ void DropActionDialog::SetDroppedFilename(QString name) bool isWorkspace4D = m_Model->GetDriver()->GetNumberOfTimePoints() > 1; - auto io = GuidedNativeImageIO::New(); - Registry dummyReg; - io->ReadNativeImageHeader(name.toStdString().c_str(), dummyReg); - auto header = io->GetIOBase(); - QString btnLoadSegText("Load as Segmentation"); - QString btnLoadSegToolTip("This will replace the current segmentation image with the dropped image."); + // Check if the file can be loaded as mesh + bool isPolyData = GuidedMeshIO::IsFilePolyData(to_utf8(name).c_str()); + + QFileInfo fileinfo(name); + auto ext = fileinfo.completeSuffix(); + auto fmt = GuidedMeshIO::GetFormatByExtension(ext.toStdString()); - if (header->GetNumberOfDimensions() < 4 && isWorkspace4D) + if (isPolyData) { - btnLoadSegText = QString("Load as Segmentation in Time Point"); - btnLoadSegToolTip = QString("This will replace the segmentation in current time point"); + if (GuidedMeshIO::can_read(fmt)) + { + this->SetIncludeMeshOptions(true); + } + else + { + QMessageBox msgBox; + std::ostringstream oss; + oss << "Unsupported mesh file type (" << ext.toStdString() << ")!"; + msgBox.setText(oss.str().c_str()); + msgBox.exec(); + this->reject(); + return; + } } + else + { + this->SetIncludeMeshOptions(false); + // Run segmentation 3d & 4d check + auto io = GuidedNativeImageIO::New(); + Registry dummyReg; + io->ReadNativeImageHeader(name.toStdString().c_str(), dummyReg); + auto header = io->GetIOBase(); + QString btnLoadSegText("Load as Segmentation"); + QString btnLoadSegToolTip("This will replace the current segmentation image with the dropped image."); + + if (header->GetNumberOfDimensions() < 4 && isWorkspace4D) + { + btnLoadSegText = QString("Load as Segmentation in Time Point"); + btnLoadSegToolTip = QString("This will replace the segmentation in current time point"); + } - ui->btnLoadSegmentation->setText(btnLoadSegText); - ui->btnLoadSegmentation->setToolTip(btnLoadSegToolTip); + ui->btnLoadSegmentation->setText(btnLoadSegText); + ui->btnLoadSegmentation->setToolTip(btnLoadSegToolTip); + } } void DropActionDialog::SetModel(GlobalUIModel *model) @@ -164,20 +194,6 @@ void DropActionDialog::on_btnLoadMeshToTP_clicked() { // Get file extension std::string fn = ui->outFilename->text().toStdString(); - // Get the file extension with the dot. e.g. ".vtk" - std::string ext = fn.substr(fn.find_last_of(".")); - - auto fmt = GuidedMeshIO::GetFormatByExtension(ext); - if (fmt == GuidedMeshIO::FORMAT_COUNT) - { - QMessageBox msgBox; - std::ostringstream oss; - oss << "Unsupported mesh file type (" << ext << ")!"; - msgBox.setText(oss.str().c_str()); - msgBox.exec(); - this->reject(); - return; - } unsigned int displayTP = m_Model->GetDriver()->GetCursorTimePoint() + 1; // always display 1-based tp index QMessageBox *box = MeshImportWizard::CreateLoadToTimePointMessageBox(this, displayTP); @@ -189,7 +205,7 @@ void DropActionDialog::on_btnLoadMeshToTP_clicked() case QMessageBox::Ok: { auto model = m_Model->GetMeshImportModel(); - model->LoadToTP(fn.c_str(), fmt); + model->LoadToTP(fn.c_str(), GuidedMeshIO::GetFormatByFilename((fn.c_str()))); this->accept(); return; } diff --git a/GUI/Qt/Windows/MainImageWindow.cxx b/GUI/Qt/Windows/MainImageWindow.cxx index 44d2e4a3..f86b96d5 100644 --- a/GUI/Qt/Windows/MainImageWindow.cxx +++ b/GUI/Qt/Windows/MainImageWindow.cxx @@ -1289,12 +1289,6 @@ void MainImageWindow::LoadDroppedFile(QString file) m_DropDialog->SetDroppedFilename(file); m_DropDialog->setModal(true); - // Check if the file can be loaded as mesh - QFileInfo fileinfo(file); - auto ext = fileinfo.completeSuffix(); - auto fmt = GuidedMeshIO::GetFormatByExtension(ext.toStdString()); - m_DropDialog->SetIncludeMeshOptions(GuidedMeshIO::can_read(fmt)); - RaiseDialog(m_DropDialog); } else diff --git a/Logic/Mesh/GuidedMeshIO.cxx b/Logic/Mesh/GuidedMeshIO.cxx index 4877c13c..d365cebc 100644 --- a/Logic/Mesh/GuidedMeshIO.cxx +++ b/Logic/Mesh/GuidedMeshIO.cxx @@ -1,13 +1,16 @@ #include "GuidedMeshIO.h" -#include "vtkPolyDataWriter.h" -#include "vtkSTLWriter.h" -#include "vtkBYUWriter.h" -#include "vtkTriangleFilter.h" -#include "itkMacro.h" #include "MeshIODelegates.h" #include "MeshWrapperBase.h" #include "StandaloneMeshWrapper.h" +#include +#include +#include +#include +#include +#include +#include + GuidedMeshIO ::GuidedMeshIO() { @@ -179,3 +182,21 @@ GuidedMeshIO::GetErrorMessage() const { return m_ErrorMessage; } + +bool +GuidedMeshIO +::IsFilePolyData(const char *filename) +{ + auto reader = vtkNew(); + reader->SetFileName(filename); + return reader->IsFilePolyData(); +} + +GuidedMeshIO::FileFormat +GuidedMeshIO +::GetFormatByFilename(const char *filename) +{ + // extract extension + std::string ext = itksys::SystemTools::GetFilenameLastExtension(filename); + return GetFormatByExtension(ext); +} diff --git a/Logic/Mesh/GuidedMeshIO.h b/Logic/Mesh/GuidedMeshIO.h index e5f42043..6dfe6550 100644 --- a/Logic/Mesh/GuidedMeshIO.h +++ b/Logic/Mesh/GuidedMeshIO.h @@ -109,6 +109,11 @@ class GuidedMeshIO /** Get Enum File Format Registry Map */ static RegistryEnumMap &GetEnumFileFormat() { return m_EnumFileFormat; } + + static bool IsFilePolyData(const char *filename); + + static FileFormat GetFormatByFilename(const char *filename); + protected: /** Registry mappings for these enums */ static RegistryEnumMap m_EnumFileFormat;