# HG changeset patch # User Sebastien Jodogne # Date 1559032782 -7200 # Node ID f72b49954f620037df01ab35da11ab2fc2e30b85 # Parent 4fe4b221a31fa2444d449205c19750c0e95571df DicomVolumeImageMPRSlicer diff -r 4fe4b221a31f -r f72b49954f62 Samples/Sdl/Loader.cpp --- a/Samples/Sdl/Loader.cpp Tue May 28 08:49:49 2019 +0200 +++ b/Samples/Sdl/Loader.cpp Tue May 28 10:39:42 2019 +0200 @@ -343,123 +343,148 @@ - class DicomVolumeImageOrthogonalSlice : public IVolumeSlicer::IExtractedSlice + class DicomVolumeImageMPRSlicer : public IVolumeSlicer { - private: - const DicomVolumeImage& volume_; - bool valid_; - VolumeProjection projection_; - unsigned int sliceIndex_; + public: + class Slice : public IExtractedSlice + { + private: + const DicomVolumeImage& volume_; + bool valid_; + VolumeProjection projection_; + unsigned int sliceIndex_; + + void CheckValid() const + { + if (!valid_) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + } + + protected: + // Can be overloaded in subclasses + virtual uint64_t GetRevisionInternal(VolumeProjection projection, + unsigned int sliceIndex) const + { + return volume_.GetRevision(); + } - void CheckValid() const - { - if (!valid_) + public: + Slice(const DicomVolumeImage& volume, + const CoordinateSystem3D& cuttingPlane) : + volume_(volume) + { + valid_ = (volume_.HasDicomParameters() && + volume_.GetGeometry().DetectSlice(projection_, sliceIndex_, cuttingPlane)); + } + + VolumeProjection GetProjection() const + { + CheckValid(); + return projection_; + } + + unsigned int GetSliceIndex() const + { + CheckValid(); + return sliceIndex_; + } + + virtual bool IsValid() + { + return valid_; + } + + virtual uint64_t GetRevision() + { + CheckValid(); + return GetRevisionInternal(projection_, sliceIndex_); + } + + virtual ISceneLayer* CreateSceneLayer(const ILayerStyleConfigurator* configurator, + const CoordinateSystem3D& cuttingPlane) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); - } - } + CheckValid(); + + if (configurator == NULL) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer, + "A style configurator is mandatory for textures"); + } + + std::auto_ptr texture; + + { + const DicomInstanceParameters& parameters = volume_.GetDicomParameters(); + ImageBuffer3D::SliceReader reader(volume_.GetPixelData(), projection_, sliceIndex_); + texture.reset(dynamic_cast + (configurator->CreateTextureFromDicom(reader.GetAccessor(), parameters))); + } + + const CoordinateSystem3D& system = volume_.GetGeometry().GetProjectionGeometry(projection_); + + double x0, y0, x1, y1; + cuttingPlane.ProjectPoint(x0, y0, system.GetOrigin()); + cuttingPlane.ProjectPoint(x1, y1, system.GetOrigin() + system.GetAxisX()); + texture->SetOrigin(x0, y0); - protected: - // Can be overloaded in subclasses - virtual uint64_t GetRevisionInternal(VolumeProjection projection, - unsigned int sliceIndex) const - { - return volume_.GetRevision(); - } + double dx = x1 - x0; + double dy = y1 - y0; + if (!LinearAlgebra::IsCloseToZero(dx) || + !LinearAlgebra::IsCloseToZero(dy)) + { + texture->SetAngle(atan2(dy, dx)); + } + + Vector tmp = volume_.GetGeometry().GetVoxelDimensions(projection_); + texture->SetPixelSpacing(tmp[0], tmp[1]); + + return texture.release(); + +#if 0 + double w = texture->GetTexture().GetWidth() * tmp[0]; + double h = texture->GetTexture().GetHeight() * tmp[1]; + printf("%.1f %.1f %.1f => %.1f %.1f => %.1f %.1f\n", + system.GetOrigin() [0], + system.GetOrigin() [1], + system.GetOrigin() [2], + x0, y0, x0 + w, y0 + h); + + std::auto_ptr toto(new PolylineSceneLayer); + + PolylineSceneLayer::Chain c; + c.push_back(ScenePoint2D(x0, y0)); + c.push_back(ScenePoint2D(x0 + w, y0)); + c.push_back(ScenePoint2D(x0 + w, y0 + h)); + c.push_back(ScenePoint2D(x0, y0 + h)); + + toto->AddChain(c, true); + + return toto.release(); +#endif + } + }; + + private: + boost::shared_ptr volume_; public: - DicomVolumeImageOrthogonalSlice(const DicomVolumeImage& volume, - const CoordinateSystem3D& cuttingPlane) : + DicomVolumeImageMPRSlicer(const boost::shared_ptr& volume) : volume_(volume) { - valid_ = (volume_.HasDicomParameters() && - volume_.GetGeometry().DetectSlice(projection_, sliceIndex_, cuttingPlane)); - } - - VolumeProjection GetProjection() const - { - CheckValid(); - return projection_; - } - - unsigned int GetSliceIndex() const - { - CheckValid(); - return sliceIndex_; - } - - virtual bool IsValid() - { - return valid_; - } - - virtual uint64_t GetRevision() - { - CheckValid(); - return GetRevisionInternal(projection_, sliceIndex_); } - virtual ISceneLayer* CreateSceneLayer(const ILayerStyleConfigurator* configurator, - const CoordinateSystem3D& cuttingPlane) + virtual IExtractedSlice* ExtractSlice(const CoordinateSystem3D& cuttingPlane) { - CheckValid(); - - if (configurator == NULL) + if (volume_->HasGeometry()) { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer, - "A style configurator is mandatory for textures"); - } - - std::auto_ptr texture; - - { - const DicomInstanceParameters& parameters = volume_.GetDicomParameters(); - ImageBuffer3D::SliceReader reader(volume_.GetPixelData(), projection_, sliceIndex_); - texture.reset(dynamic_cast - (configurator->CreateTextureFromDicom(reader.GetAccessor(), parameters))); + return new Slice(*volume_, cuttingPlane); } - - const CoordinateSystem3D& system = volume_.GetGeometry().GetProjectionGeometry(projection_); - - double x0, y0, x1, y1; - cuttingPlane.ProjectPoint(x0, y0, system.GetOrigin()); - cuttingPlane.ProjectPoint(x1, y1, system.GetOrigin() + system.GetAxisX()); - texture->SetOrigin(x0, y0); - - double dx = x1 - x0; - double dy = y1 - y0; - if (!LinearAlgebra::IsCloseToZero(dx) || - !LinearAlgebra::IsCloseToZero(dy)) + else { - texture->SetAngle(atan2(dy, dx)); + return new IVolumeSlicer::InvalidSlice; } - - Vector tmp = volume_.GetGeometry().GetVoxelDimensions(projection_); - texture->SetPixelSpacing(tmp[0], tmp[1]); - - return texture.release(); - -#if 0 - double w = texture->GetTexture().GetWidth() * tmp[0]; - double h = texture->GetTexture().GetHeight() * tmp[1]; - printf("%.1f %.1f %.1f => %.1f %.1f => %.1f %.1f\n", - system.GetOrigin() [0], - system.GetOrigin() [1], - system.GetOrigin() [2], - x0, y0, x0 + w, y0 + h); - - std::auto_ptr toto(new PolylineSceneLayer); - - PolylineSceneLayer::Chain c; - c.push_back(ScenePoint2D(x0, y0)); - c.push_back(ScenePoint2D(x0 + w, y0)); - c.push_back(ScenePoint2D(x0 + w, y0 + h)); - c.push_back(ScenePoint2D(x0, y0 + h)); - - toto->AddChain(c, true); - - return toto.release(); -#endif } }; @@ -664,7 +689,7 @@ }; - class Slice : public DicomVolumeImageOrthogonalSlice + class ExtractedSlice : public DicomVolumeImageMPRSlicer::Slice { private: const OrthancSeriesVolumeProgressiveLoader& that_; @@ -686,11 +711,17 @@ } public: - Slice(const OrthancSeriesVolumeProgressiveLoader& that, - const CoordinateSystem3D& plane) : - DicomVolumeImageOrthogonalSlice(*that.volume_, plane), + ExtractedSlice(const OrthancSeriesVolumeProgressiveLoader& that, + const CoordinateSystem3D& plane) : + DicomVolumeImageMPRSlicer::Slice(*that.volume_, plane), that_(that) { + if (that_.strategy_.get() != NULL && + IsValid() && + GetProjection() == VolumeProjection_Axial) + { + that_.strategy_->SetCurrent(GetSliceIndex()); + } } }; @@ -933,16 +964,7 @@ { if (volume_->HasGeometry()) { - std::auto_ptr slice(new Slice(*this, cuttingPlane)); - - if (strategy_.get() != NULL && - slice->IsValid() && - slice->GetProjection() == VolumeProjection_Axial) - { - strategy_->SetCurrent(slice->GetSliceIndex()); - } - - return slice.release(); + return new ExtractedSlice(*this, cuttingPlane); } else { @@ -955,8 +977,7 @@ class OrthancMultiframeVolumeLoader : public IObserver, - public IObservable, - public IVolumeSlicer + public IObservable { private: class State : public Orthanc::IDynamicObject @@ -1329,19 +1350,6 @@ } } } - - - virtual IExtractedSlice* ExtractSlice(const CoordinateSystem3D& cuttingPlane) - { - if (volume_->HasGeometry()) - { - return new DicomVolumeImageOrthogonalSlice(*volume_, cuttingPlane); - } - else - { - return new IVolumeSlicer::InvalidSlice; - } - } }; @@ -1962,10 +1970,12 @@ { std::auto_ptr config(new OrthancStone::LookupTableStyleConfigurator); config->SetLookupTable(Orthanc::EmbeddedResources::COLORMAP_HOT); - toto->SetVolume2(1, doseLoader, config.release()); + + boost::shared_ptr tmp(new OrthancStone::DicomVolumeImageMPRSlicer(dose)); + toto->SetVolume2(1, tmp, config.release()); } - //oracle.Schedule(*toto, new OrthancStone::SleepOracleCommand(100)); + oracle.Schedule(*toto, new OrthancStone::SleepOracleCommand(100)); if (0) { @@ -2044,8 +2054,8 @@ // 2017-11-17-Anonymized - //ctLoader->LoadSeries("cb3ea4d1-d08f3856-ad7b6314-74d88d77-60b05618"); // CT - //doseLoader->LoadInstance("41029085-71718346-811efac4-420e2c15-d39f99b6"); // RT-DOSE + ctLoader->LoadSeries("cb3ea4d1-d08f3856-ad7b6314-74d88d77-60b05618"); // CT + doseLoader->LoadInstance("41029085-71718346-811efac4-420e2c15-d39f99b6"); // RT-DOSE rtstructLoader->LoadInstance("83d9c0c3-913a7fee-610097d7-cbf0522d-fd75bee6"); // RT-STRUCT // 2015-01-28-Multiframe