comparison OrthancStone/Sources/Loaders/OrthancMultiframeVolumeLoader.cpp @ 2076:990f396484b1

fix rendering of RT-DOSE with negative GridFrameOffsetVector
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 11 Jul 2023 15:58:16 +0200
parents 7053b8a0aaec
children 07964689cb0b
comparison
equal deleted inserted replaced
2075:d84bdcbd8bf1 2076:990f396484b1
213 213
214 double spacingZ; 214 double spacingZ;
215 switch (parameters.GetSopClassUid()) 215 switch (parameters.GetSopClassUid())
216 { 216 {
217 case SopClassUid_RTDose: 217 case SopClassUid_RTDose:
218 spacingZ = parameters.GetSliceThickness(); 218 if (!parameters.ComputeFrameOffsetsSpacing(spacingZ))
219 {
220 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented,
221 "Cannot load RT-DOSE with incorrect GridFrameOffsetVector (3004,000C)");
222 }
219 break; 223 break;
220 224
221 default: 225 default:
222 throw Orthanc::OrthancException( 226 throw Orthanc::OrthancException(
223 Orthanc::ErrorCode_NotImplemented, 227 Orthanc::ErrorCode_NotImplemented,
224 "No support for multiframe instances with SOP class UID: " + GetSopClassUid(dicom)); 228 "No support for multiframe instances with SOP class UID: " + GetSopClassUid(dicom));
225 } 229 }
226 230
231 isReversedFrameOffsets_ = parameters.IsReversedFrameOffsets();
232
227 const unsigned int width = parameters.GetImageInformation().GetWidth(); 233 const unsigned int width = parameters.GetImageInformation().GetWidth();
228 const unsigned int height = parameters.GetImageInformation().GetHeight(); 234 const unsigned int height = parameters.GetImageInformation().GetHeight();
229 const unsigned int depth = parameters.GetImageInformation().GetNumberOfFrames(); 235 const unsigned int depth = parameters.GetImageInformation().GetNumberOfFrames();
230 236
231 { 237 {
232 VolumeImageGeometry geometry; 238 VolumeImageGeometry geometry;
233 geometry.SetSizeInVoxels(width, height, depth); 239 geometry.SetSizeInVoxels(width, height, depth);
234 geometry.SetAxialGeometry(parameters.GetGeometry()); 240 geometry.SetAxialGeometry(parameters.GetMultiFrameGeometry());
235 geometry.SetVoxelDimensions(parameters.GetPixelSpacingX(), 241 geometry.SetVoxelDimensions(parameters.GetPixelSpacingX(),
236 parameters.GetPixelSpacingY(), spacingZ); 242 parameters.GetPixelSpacingY(), spacingZ);
237 volume_->Initialize(geometry, format, true /* Do compute range */); 243 volume_->Initialize(geometry, format, true /* Do compute range */);
238 } 244 }
239 245
240 volume_->GetPixelData().Clear(); 246 volume_->GetPixelData().Clear();
241 247
242 ScheduleFrameDownloads(); 248 ScheduleFrameDownloads();
243
244
245 249
246 BroadcastMessage(DicomVolumeImage::GeometryReadyMessage(*volume_)); 250 BroadcastMessage(DicomVolumeImage::GeometryReadyMessage(*volume_));
247 } 251 }
248 252
249 253
320 { 324 {
321 const uint8_t* source = reinterpret_cast<const uint8_t*>(pixelData.c_str()); 325 const uint8_t* source = reinterpret_cast<const uint8_t*>(pixelData.c_str());
322 326
323 for (unsigned int z = 0; z < depth; z++) 327 for (unsigned int z = 0; z < depth; z++)
324 { 328 {
325 ImageBuffer3D::SliceWriter writer(target, VolumeProjection_Axial, z); 329 unsigned targetZ;
330 if (isReversedFrameOffsets_)
331 {
332 targetZ = depth - 1 - z;
333 }
334 else
335 {
336 targetZ = z;
337 }
338
339 ImageBuffer3D::SliceWriter writer(target, VolumeProjection_Axial, targetZ);
326 340
327 assert(writer.GetAccessor().GetWidth() == width && 341 assert(writer.GetAccessor().GetWidth() == width &&
328 writer.GetAccessor().GetHeight() == height); 342 writer.GetAccessor().GetHeight() == height);
329 #if 0 343 #if 0
330 for (unsigned int y = 0; y < height; y++) 344 for (unsigned int y = 0; y < height; y++)
552 ILoadersContext& loadersContext, 566 ILoadersContext& loadersContext,
553 boost::shared_ptr<DicomVolumeImage> volume, 567 boost::shared_ptr<DicomVolumeImage> volume,
554 float outliersHalfRejectionRate) 568 float outliersHalfRejectionRate)
555 : LoaderStateMachine(loadersContext) 569 : LoaderStateMachine(loadersContext)
556 , volume_(volume) 570 , volume_(volume)
571 , isReversedFrameOffsets_(false)
557 , pixelDataLoaded_(false) 572 , pixelDataLoaded_(false)
558 , outliersHalfRejectionRate_(outliersHalfRejectionRate) 573 , outliersHalfRejectionRate_(outliersHalfRejectionRate)
559 , distributionRawMin_(0) 574 , distributionRawMin_(0)
560 , distributionRawMax_(0) 575 , distributionRawMax_(0)
561 , computedDistributionMin_(0) 576 , computedDistributionMin_(0)