7 #include "fwVtkIO/helper/Mesh.hpp" 8 #include "fwVtkIO/helper/vtkLambdaCommand.hpp" 9 #include "fwVtkIO/SeriesDBReader.hpp" 10 #include "fwVtkIO/vtk.hpp" 12 #include <fwCore/base.hpp> 14 #include <fwJobs/IJob.hpp> 15 #include <fwJobs/Observer.hpp> 17 #include <fwData/Image.hpp> 18 #include <fwData/Mesh.hpp> 19 #include <fwData/Reconstruction.hpp> 21 #include <fwDataIO/reader/registry/macros.hpp> 23 #include <fwMedData/Equipment.hpp> 24 #include <fwMedData/ImageSeries.hpp> 25 #include <fwMedData/ModelSeries.hpp> 26 #include <fwMedData/Patient.hpp> 27 #include <fwMedData/Study.hpp> 29 #include <fwMemory/BufferObject.hpp> 30 #include <fwMemory/stream/in/IFactory.hpp> 32 #include <fwTools/dateAndTime.hpp> 33 #include <fwTools/UUID.hpp> 35 #include <boost/algorithm/string/join.hpp> 36 #include <boost/date_time/posix_time/posix_time.hpp> 37 #include <boost/filesystem/operations.hpp> 38 #include <boost/filesystem/path.hpp> 39 #include <boost/iostreams/categories.hpp> 40 #include <boost/iostreams/filtering_stream.hpp> 41 #include <boost/iostreams/stream.hpp> 43 #include <vtkDataSetAttributes.h> 44 #include <vtkGenericDataObjectReader.h> 45 #include <vtkImageData.h> 46 #include <vtkInformation.h> 47 #include <vtkMetaImageReader.h> 48 #include <vtkPolyData.h> 49 #include <vtkSmartPointer.h> 50 #include <vtkStreamingDemandDrivenPipeline.h> 51 #include <vtkStructuredPoints.h> 52 #include <vtkStructuredPointsReader.h> 53 #include <vtkXMLGenericDataObjectReader.h> 54 #include <vtkXMLImageDataReader.h> 66 void initSeries(::fwMedData::Series::sptr series,
const std::string& instanceUID)
68 const std::string unknown =
"unknown";
69 series->setModality(
"OT");
70 ::boost::posix_time::ptime now = ::boost::posix_time::second_clock::local_time();
71 const std::string date = ::fwTools::getDate(now);
72 const std::string time = ::fwTools::getTime(now);
73 series->setDate(date);
74 series->setTime(time);
78 series->getEquipment()->setInstitutionName(unknown);
80 series->getPatient()->setName(unknown);
81 series->getPatient()->setPatientId(unknown);
82 series->getPatient()->setBirthdate(unknown);
83 series->getPatient()->setSex(unknown);
85 series->getStudy()->setInstanceUID(instanceUID);
86 series->getStudy()->setDate(date);
87 series->getStudy()->setTime(time);
88 series->getStudy()->setReferringPhysicianName(unknown);
89 series->getStudy()->setDescription(unknown);
90 series->getStudy()->setPatientAge(unknown);
97 ::
fwData::location::enableMultiFiles< ::
fwDataIO::reader::IObjectReader >(this),
99 m_job(::
fwJobs::Observer::New(
"SeriesDB reader"))
112 template <
typename T,
typename FILE>
113 vtkSmartPointer< vtkDataObject > getObj(FILE &file, const ::fwJobs::Observer::sptr& job)
117 vtkSmartPointer< T > reader = vtkSmartPointer< T >::New();
118 reader->SetFileName(file.string().c_str());
122 vtkSmartPointer<vtkLambdaCommand> progressCallback;
123 progressCallback = vtkSmartPointer<vtkLambdaCommand>::New();
124 progressCallback->SetCallback([&](vtkObject* caller,
long unsigned int,
void* )
126 auto filter =
static_cast<T*
>(caller);
127 job->doneWork( filter->GetProgress()*100 );
129 reader->AddObserver(vtkCommand::ProgressEvent, progressCallback);
131 job->addSimpleCancelHook( [&]()
133 reader->AbortExecuteOn();
142 return reader->GetOutput();
147 ::fwData::Object::sptr getDataObject(
const vtkSmartPointer< vtkDataObject > &obj,
const boost::filesystem::path &file)
149 vtkSmartPointer< vtkPolyData > mesh = vtkPolyData::SafeDownCast(obj);
150 vtkSmartPointer< vtkImageData > img = vtkImageData::SafeDownCast(obj);
151 vtkSmartPointer< vtkUnstructuredGrid > grid = vtkUnstructuredGrid::SafeDownCast(obj);
152 ::fwData::Object::sptr dataObj;
156 ::fwData::Mesh::sptr meshObj = ::fwData::Mesh::New();
159 ::fwData::Reconstruction::sptr rec = ::fwData::Reconstruction::New();
160 rec->setMesh(meshObj);
161 rec->setOrganName(file.stem().string());
162 rec->setIsVisible(
true);
167 ::fwData::Mesh::sptr meshObj = ::fwData::Mesh::New();
169 ::fwData::Reconstruction::sptr rec = ::fwData::Reconstruction::New();
170 rec->setMesh(meshObj);
171 rec->setOrganName(file.stem().string());
172 rec->setIsVisible(
true);
179 ::fwData::Image::sptr imgObj = ::fwData::Image::New();
180 ::fwVtkIO::fromVTKImage( img, imgObj);
183 catch( std::exception &e)
185 FW_RAISE(
"VTKImage to fwData::Image failed "<<e.what());
195 typedef ::boost::iostreams::stream< ::boost::iostreams::array_source > BufferStreamType;
200 m_bufferObject(source->getDataArray()->getBufferObject()),
201 m_lock( m_bufferObject->lock() ),
202 m_bufferStream( std::make_shared<BufferStreamType>(static_cast<char *>(m_lock.getBuffer()),
203 m_bufferObject->getSize()) )
205 this->push(*m_bufferStream);
219 ::fwData::Image::sptr m_image;
220 ::fwMemory::BufferObject::sptr m_bufferObject;
222 SPTR(BufferStreamType) m_bufferStream;
227 template<
typename READER >
232 ImageStream( const ::boost::filesystem::path& path ) : m_path(path)
238 ::fwData::Image::sptr getImage()
240 if(!::boost::filesystem::exists(m_path))
242 FW_RAISE(
"file "<< m_path.string() <<
" does not exist anymore or has moved.");
245 vtkSmartPointer< vtkDataObject > obj;
246 obj = getObj<READER>(m_path,
nullptr);
248 return ::fwData::Image::dynamicCast(getDataObject(obj, m_path));
251 SPTR(std::istream)
get()
254 = std::make_shared< FilteringStream>( this->getImage() );
259 ::boost::filesystem::path m_path;
265 bool checkIfReadDataTypeIsImage(
const vtkSmartPointer< vtkMetaImageReader > &reader)
270 bool checkIfReadDataTypeIsImage(
const vtkSmartPointer< vtkGenericDataObjectReader > &reader)
272 return reader->IsFileStructuredPoints();
275 bool checkIfReadDataTypeIsImage(
const vtkSmartPointer< vtkXMLGenericDataObjectReader > &reader)
277 return (reader->GetImageDataOutput () != 0);
280 void updateImageFromVtkInfo(
const vtkSmartPointer< vtkInformation > &info, const ::fwData::Image::sptr &imgObj)
283 info->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent);
285 size[0] = extent[1]-extent[0]+1;
286 size[1] = extent[3]-extent[2]+1;
287 size[2] = extent[5]-extent[4]+1;
288 imgObj->setSize(size);
291 info->Get(vtkDataObject::SPACING(), &spacing[0]);
292 imgObj->setSpacing(spacing);
295 info->Get(vtkDataObject::ORIGIN(), &origin[0]);
296 imgObj->setOrigin(origin);
298 vtkInformation *attrInfo = vtkDataObject::GetActiveFieldInformation(info, vtkDataObject::FIELD_ASSOCIATION_POINTS,
299 vtkDataSetAttributes::SCALARS);
300 int type = attrInfo->Get(vtkDataObject::FIELD_ARRAY_TYPE());
301 int nbOfComponents = attrInfo->Get(vtkDataObject::FIELD_NUMBER_OF_COMPONENTS());
302 imgObj->setType( ::fwVtkIO::TypeTranslator::translate( attrInfo->Get(vtkDataObject::FIELD_ARRAY_TYPE()) ) );
303 imgObj->setNumberOfComponents(nbOfComponents);
304 imgObj->getDataArray()->setType(imgObj->getType());
307 void getInfo(
const vtkSmartPointer< vtkGenericDataObjectReader > &reader, const ::fwData::Image::sptr &imgObj)
309 vtkSmartPointer< vtkStructuredPointsReader > imgReader = vtkSmartPointer< vtkStructuredPointsReader >::New();
310 imgReader->SetFileName(reader->GetFileName());
312 vtkSmartPointer< vtkInformation > info = vtkSmartPointer< vtkInformation >::New();
313 imgReader->ReadMetaData(info);
315 updateImageFromVtkInfo(info, imgObj);
316 imgObj->getDataArray()->resize(imgObj->getSize(),
false);
318 ::fwMemory::BufferObject::sptr buffObj = imgObj->getDataArray()->getBufferObject();
319 boost::filesystem::path file = reader->GetFileName();
321 imgObj->getSizeInBytes());
325 void getInfo(
const vtkSmartPointer< vtkXMLGenericDataObjectReader > &reader, const ::fwData::Image::sptr &imgObj)
327 vtkSmartPointer< vtkXMLImageDataReader > imgReader = vtkSmartPointer< vtkXMLImageDataReader >::New();
328 imgReader->SetFileName(reader->GetFileName());
330 vtkSmartPointer< vtkInformation > info = vtkSmartPointer< vtkInformation >::New();
331 imgReader->UpdateInformation();
332 imgReader->CopyOutputInformation(info,0);
334 updateImageFromVtkInfo(info, imgObj);
335 imgObj->getDataArray()->resize(imgObj->getSize(),
false);
337 ::fwMemory::BufferObject::sptr buffObj = imgObj->getDataArray()->getBufferObject();
338 boost::filesystem::path file = reader->GetFileName();
340 imgObj->getSizeInBytes());
346 template<
typename DATA_READER >
347 ::fwData::Image::sptr lazyRead( const ::boost::filesystem::path &file, const ::fwJobs::Observer::sptr& job)
349 vtkSmartPointer< DATA_READER > reader = vtkSmartPointer< DATA_READER >::New();
350 reader->SetFileName(file.string().c_str());
351 reader->UpdateInformation();
353 ::fwData::Image::sptr imgObj;
355 if(checkIfReadDataTypeIsImage(reader))
357 imgObj = ::fwData::Image::New();
358 getInfo(reader, imgObj);
374 const ::fwData::location::ILocation::VectPathType files = this->
getFiles();
377 ::fwMedData::ModelSeries::ReconstructionVectorType recs;
378 std::vector< std::string > errorFiles;
379 for(const ::fwData::location::ILocation::VectPathType::value_type& file : files)
381 vtkSmartPointer< vtkDataObject > obj;
382 ::fwData::Image::sptr img;
383 ::fwData::Reconstruction::sptr rec;
385 if(file.extension().string() ==
".vtk")
389 img = lazyRead<vtkGenericDataObjectReader>(file, m_job);
393 obj = getObj<vtkGenericDataObjectReader>(file, m_job);
396 else if(file.extension().string() ==
".vti")
400 img = lazyRead<vtkXMLGenericDataObjectReader>(file, m_job);
404 obj = getObj<vtkXMLGenericDataObjectReader>(file, m_job);
407 else if(file.extension().string() ==
".mhd")
409 obj = getObj<vtkMetaImageReader>(file, m_job);
411 else if(file.extension().string() ==
".vtu")
413 obj = getObj<vtkXMLGenericDataObjectReader>(file, m_job);
418 ::fwData::Object::sptr dataObj = getDataObject(obj, file);
419 img = ::fwData::Image::dynamicCast(dataObj);
420 rec = ::fwData::Reconstruction::dynamicCast(dataObj);
424 ::fwMedData::ImageSeries::sptr imgSeries = ::fwMedData::ImageSeries::New();
425 initSeries(imgSeries, instanceUID);
426 imgSeries->setImage(img);
427 seriesDB->getContainer().push_back(imgSeries);
435 errorFiles.push_back(file.string());
439 if (!errorFiles.empty())
441 FW_RAISE(
"SeriesDBReader cannot read VTK file(s) : "<< ::boost::algorithm::join(errorFiles,
", ") );
447 ::fwMedData::ModelSeries::sptr modelSeries = ::fwMedData::ModelSeries::New();
448 initSeries(modelSeries, instanceUID);
449 modelSeries->setReconstructionDB(recs);
450 seriesDB->getContainer().push_back(modelSeries);
FWVTKIO_API void read() override
Reading operator.
#define SLM_TRACE_FUNC()
Trace contextual function signature.
This namespace fwDataIO contains reader and writer for several framework's data.
Key class used to restrict access to Object construction. See http://www.drdobbs.com/184402053.
base class for BufferObject Lock
std::shared_ptr< ::fwJobs::IJob > sptr
Cancel request callback type.
FWVTKIO_API SeriesDBReader(::fwDataIO::reader::IObjectReader::Key key)
Constructor.
static FWVTKIO_API void fromVTKGrid(vtkSmartPointer< vtkUnstructuredGrid > grid,::fwData::Mesh::sptr mesh)
Convert a vtkUnstructuredGrid to a ::fwData::Mesh::sptr.
FWVTKIO_API ~SeriesDBReader()
Destructor.
virtual std::shared_ptr< DataType > getConcreteObject()
m_object getter.
std::vector< double > SpacingType
Image spacing type.
ILocation::VectPathType getFiles()
Get file system paths.
FWVTKIO_API std::shared_ptr< ::fwJobs::IJob > getJob() const override
Contains the representation of the data objects used in the framework.
static FWVTKIO_API void fromVTKMesh(vtkSmartPointer< vtkPolyData > _polyData,::fwData::Mesh::sptr _mesh)
Convert a vtkPolyData to a ::fwData::Mesh::sptr.
This namespace fwJobs provides jobs management.
::fwData::Array::SizeType SizeType
Image size type.
FWVTKIO_API std::string extension() override
std::vector< double > OriginType
Image origin type.