diff --git a/Modules/Core/include/mitkMimeType.h b/Modules/Core/include/mitkMimeType.h index be5dad77fb..785409c9ea 100644 --- a/Modules/Core/include/mitkMimeType.h +++ b/Modules/Core/include/mitkMimeType.h @@ -1,102 +1,102 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKMIMETYPE_H #define MITKMIMETYPE_H #include #include #include #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4251) #endif namespace mitk { class CustomMimeType; /** * @ingroup IO * * @brief The MimeType class represens a registered mime-type. It is an immutable wrapper for mitk::CustomMimeType * that makes memory handling easier by providing a stack-object for the user. * * If you want to register a new MimeType, use the CustomMimeType class instead. Wrapping will be performed for you * automatically. * In all other cases you should use mitk::MimeType when working with mime-types. */ class MITKCORE_EXPORT MimeType { public: MimeType(); MimeType(const MimeType &other); MimeType(const CustomMimeType &x, int rank, long id); ~MimeType(); MimeType &operator=(const MimeType &other); bool operator==(const MimeType &other) const; bool operator<(const MimeType &other) const; /** @See mitk::CustomMimeType::GetName()*/ std::string GetName() const; /** @See mitk::CustomMimeType::GetCategory()*/ std::string GetCategory() const; /** @See mitk::CustomMimeType::GetExtensions()*/ std::vector GetExtensions() const; /** @See mitk::CustomMimeType::GetComment()*/ std::string GetComment() const; /** @See mitk::CustomMimeType::GetFileNameWithoutExtension()*/ std::string GetFilenameWithoutExtension(const std::string &path) const; /** @See mitk::CustomMimeType::AppliesTo()*/ bool AppliesTo(const std::string &path) const; /** @See mitk::CustomMimeType::MatchesExtension()*/ bool MatchesExtension(const std::string &path) const; /** @See mitk::CustomMimeType::IsValid()*/ bool IsValid() const; /** @See mitk::CustomMimeType::Swap()*/ void Swap(MimeType &m); private: struct Impl; // Use C++11 shared_ptr instead us::SharedDataPointer m_Data; }; - void swap(MimeType &m1, MimeType &m2); + MITKCORE_EXPORT void swap(MimeType &m1, MimeType &m2); - std::ostream &operator<<(std::ostream &os, const MimeType &mimeType); + MITKCORE_EXPORT std::ostream &operator<<(std::ostream &os, const MimeType &mimeType); } #ifdef _MSC_VER #pragma warning(pop) #endif #endif // MITKMIMETYPE_H diff --git a/Modules/IGT/TrackingDevices/mitkTrackingVolumeGenerator.cpp b/Modules/IGT/TrackingDevices/mitkTrackingVolumeGenerator.cpp index 5f044a9fbf..caed56dd1e 100644 --- a/Modules/IGT/TrackingDevices/mitkTrackingVolumeGenerator.cpp +++ b/Modules/IGT/TrackingDevices/mitkTrackingVolumeGenerator.cpp @@ -1,131 +1,195 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTrackingVolumeGenerator.h" #include "mitkStandardFileLocations.h" #include "mitkConfig.h" #include #include #include #include #include #include #include #include #include #include #include #include #include +#include +#include #include +#include +#include +#include #include "mitkUnspecifiedTrackingTypeInformation.h" #include "mitkTrackingDeviceTypeCollection.h" +#include + +namespace { + +//! Workaround until IOUtil::LoadSurface will guarantee to load mitk::Surface +//! even in presence of reader services that load STL as another type of +//! BaseData (T19825). +mitk::Surface::Pointer LoadCoreSurface(const us::ModuleResource& usResource) +{ + us::ModuleResourceStream resStream(usResource, std::ios_base::in); + + mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); + // get mime types for file (extension) and for surfaces + std::vector mimetypesForFile = mimeTypeProvider->GetMimeTypesForFile(usResource.GetResourcePath()); + std::vector mimetypesForSurface = mimeTypeProvider->GetMimeTypesForCategory(mitk::IOMimeTypes::CATEGORY_SURFACES()); + + // construct our candidates as the intersection of both sets because we need something that + // handles the type type _and_ produces a surface out of it + std::vector mimetypes; + + std::sort(mimetypesForFile.begin(), mimetypesForFile.end()); + std::sort(mimetypesForSurface.begin(), mimetypesForSurface.end()); + std::set_intersection(mimetypesForFile.begin(), mimetypesForFile.end(), + mimetypesForSurface.begin(), mimetypesForSurface.end(), + std::back_inserter(mimetypes)); + + mitk::Surface::Pointer surface; + if (mimetypes.empty()) + { + mitkThrow() << "No mimetype for resource stream: " << usResource.GetResourcePath(); + return surface; + } + + mitk::FileReaderRegistry fileReaderRegistry; + std::vector> refs = fileReaderRegistry.GetReferences(mimetypes[0]); + if (refs.empty()) + { + mitkThrow() << "No reader available for resource stream: " << usResource.GetResourcePath(); + return surface; + } + + mitk::IFileReader *reader = fileReaderRegistry.GetReader(refs[0]); + reader->SetInput(usResource.GetResourcePath(), &resStream); + auto basedatas = reader->Read(); + if (!basedatas.empty()) + { + surface = dynamic_cast(basedatas.front().GetPointer()); + } + + return surface; +} + +} // unnamed namespace + mitk::TrackingVolumeGenerator::TrackingVolumeGenerator() { m_Data = mitk::UnspecifiedTrackingTypeInformation::GetDeviceDataUnspecified(); } void mitk::TrackingVolumeGenerator::SetTrackingDevice (mitk::TrackingDevice::Pointer tracker) { std::vector > refs = us::GetModuleContext()->GetServiceReferences(); if (refs.empty()) { MITK_ERROR << "No tracking device service found!"; } mitk::TrackingDeviceTypeCollection* deviceTypeCollection = us::GetModuleContext()->GetService(refs.front()); this->m_Data = deviceTypeCollection->GetFirstCompatibleDeviceDataForLine(tracker->GetType()); } void mitk::TrackingVolumeGenerator::GenerateData() { mitk::Surface::Pointer output = this->GetOutput(); //the surface wich represents the tracking volume - std::string filepath = ""; // Full path to file (wil be resolved later) std::string filename = this->m_Data.VolumeModelLocation; // Name of the file or possibly a magic String, e.g. "cube" MITK_INFO << "volume: " << filename; // See if filename matches a magic string. if (filename.compare("cube") == 0){ vtkSmartPointer cubeSource = vtkSmartPointer::New(); double bounds[6]; bounds[0] = bounds[2] = bounds[4] = -400.0; // initialize bounds to -400 ... +400 cube. This is the default value of the bounds[1] = bounds[3] = bounds[5] = 400.0; // virtual tracking device, but it can be changed. In that case, // the tracking volume polydata has to be updated manually cubeSource->SetBounds(bounds); cubeSource->Update(); output->SetVtkPolyData(cubeSource->GetOutput()); //set the vtkCubeSource as polyData of the surface return; } if (filename.compare("") == 0) // empty String means no model, return empty output { // initialize with empty poly data (otherwise old surfaces may be returned) => so an empty surface is returned vtkPolyData *emptyPolyData = vtkPolyData::New(); output->SetVtkPolyData(emptyPolyData); emptyPolyData->Delete(); return; } // from here on, we assume that filename contains an actual filename and not a magic string us::Module* module = us::GetModuleContext()->GetModule(); - us::ModuleResource moduleResource = module->GetResource(filename); - std::vector data = mitk::IOUtil::Load(moduleResource); - - if(data.empty()) - MITK_ERROR << "Exception while reading file:"; - - mitk::Surface::Pointer fileoutput = dynamic_cast(data[0].GetPointer()); - - output->SetVtkPolyData(fileoutput->GetVtkPolyData()); + // TODO one would want to call mitk::IOUtils::LoadSurface(moduleResource) here. + // However this function is not guaranteed to find a reader that loads + // named resource as a Surface (given the presence of alternative readers + // that produce another data type but has a higher ranking than the core + // surface reader) - see bug T22608. + mitk::Surface::Pointer fileoutput = LoadCoreSurface(moduleResource); + if (fileoutput == nullptr) + { + MITK_ERROR << "Exception while casting data loaded from file: " << moduleResource.GetResourcePath(); + output->SetVtkPolyData(vtkSmartPointer(vtkPolyData::New())); + } + else + { + output->SetVtkPolyData(fileoutput->GetVtkPolyData()); + } } void mitk::TrackingVolumeGenerator::SetTrackingDeviceType(mitk::TrackingDeviceType deviceType) { std::vector > refs = us::GetModuleContext()->GetServiceReferences(); if (refs.empty()) { MITK_ERROR << "No tracking device service found!"; } mitk::TrackingDeviceTypeCollection* deviceTypeCollection = us::GetModuleContext()->GetService(refs.front()); m_Data = deviceTypeCollection->GetFirstCompatibleDeviceDataForLine(deviceType); } mitk::TrackingDeviceType mitk::TrackingVolumeGenerator::GetTrackingDeviceType() const { return m_Data.Line; } void mitk::TrackingVolumeGenerator::SetTrackingDeviceData(mitk::TrackingDeviceData deviceData) { m_Data= deviceData; } mitk::TrackingDeviceData mitk::TrackingVolumeGenerator::GetTrackingDeviceData() const { return m_Data; }