comparison Framework/Volumes/DicomVolumeImageMPRSlicer.cpp @ 860:238693c3bc51 am-dev

merge default -> am-dev
author Alain Mazy <alain@mazy.be>
date Mon, 24 Jun 2019 14:35:00 +0200
parents 68f888812af4
children 401808e7ff2e
comparison
equal deleted inserted replaced
856:a6e17a5a39e7 860:238693c3bc51
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2019 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21
22 #include "DicomVolumeImageMPRSlicer.h"
23
24 #include <Core/OrthancException.h>
25
26 namespace OrthancStone
27 {
28 void DicomVolumeImageMPRSlicer::Slice::CheckValid() const
29 {
30 if (!valid_)
31 {
32 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
33 }
34 }
35
36
37 DicomVolumeImageMPRSlicer::Slice::Slice(const DicomVolumeImage& volume,
38 const CoordinateSystem3D& cuttingPlane) :
39 volume_(volume),
40 revision_(volume_.GetRevision())
41 {
42 valid_ = (volume_.HasDicomParameters() &&
43 volume_.GetGeometry().DetectSlice(projection_, sliceIndex_, cuttingPlane));
44 }
45
46
47 VolumeProjection DicomVolumeImageMPRSlicer::Slice::GetProjection() const
48 {
49 CheckValid();
50 return projection_;
51 }
52
53
54 unsigned int DicomVolumeImageMPRSlicer::Slice::GetSliceIndex() const
55 {
56 CheckValid();
57 return sliceIndex_;
58 }
59
60
61 ISceneLayer* DicomVolumeImageMPRSlicer::Slice::CreateSceneLayer(const ILayerStyleConfigurator* configurator,
62 const CoordinateSystem3D& cuttingPlane)
63 {
64 CheckValid();
65
66 if (configurator == NULL)
67 {
68 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer,
69 "A style configurator is mandatory for textures");
70 }
71
72 std::auto_ptr<TextureBaseSceneLayer> texture;
73
74 {
75 const DicomInstanceParameters& parameters = volume_.GetDicomParameters();
76 ImageBuffer3D::SliceReader reader(volume_.GetPixelData(), projection_, sliceIndex_);
77 texture.reset(dynamic_cast<TextureBaseSceneLayer*>
78 (configurator->CreateTextureFromDicom(reader.GetAccessor(), parameters)));
79 }
80
81 const CoordinateSystem3D& system = volume_.GetGeometry().GetProjectionGeometry(projection_);
82
83 double x0, y0, x1, y1;
84 cuttingPlane.ProjectPoint(x0, y0, system.GetOrigin());
85 cuttingPlane.ProjectPoint(x1, y1, system.GetOrigin() + system.GetAxisX());
86 texture->SetOrigin(x0, y0);
87
88 double dx = x1 - x0;
89 double dy = y1 - y0;
90 if (!LinearAlgebra::IsCloseToZero(dx) ||
91 !LinearAlgebra::IsCloseToZero(dy))
92 {
93 texture->SetAngle(atan2(dy, dx));
94 }
95
96 Vector tmp = volume_.GetGeometry().GetVoxelDimensions(projection_);
97 texture->SetPixelSpacing(tmp[0], tmp[1]);
98
99 return texture.release();
100 }
101
102
103 IVolumeSlicer::IExtractedSlice*
104 DicomVolumeImageMPRSlicer::ExtractSlice(const CoordinateSystem3D& cuttingPlane)
105 {
106 if (volume_->HasGeometry())
107 {
108 return new Slice(*volume_, cuttingPlane);
109 }
110 else
111 {
112 return new IVolumeSlicer::InvalidSlice;
113 }
114 }
115 }