Mercurial > hg > orthanc-stone
annotate Framework/Toolbox/CoordinateSystem3D.cpp @ 627:b7fd0471281c am-dev
fix CodeGeneration unit tests
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Wed, 08 May 2019 10:51:41 +0200 |
parents | b70e9be013e4 |
children | 6af3099ed8da |
rev | line source |
---|---|
0 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
439 | 5 * Copyright (C) 2017-2019 Osimis S.A., Belgium |
0 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
47 | 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. | |
0 | 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 | |
47 | 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 | |
0 | 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 **/ | |
20 | |
21 | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
22 #include "CoordinateSystem3D.h" |
0 | 23 |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
157
diff
changeset
|
24 #include "LinearAlgebra.h" |
0 | 25 #include "GeometryToolbox.h" |
26 | |
212
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
27 #include <Core/Logging.h> |
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
28 #include <Core/Toolbox.h> |
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
29 #include <Core/OrthancException.h> |
0 | 30 |
31 namespace OrthancStone | |
32 { | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
33 void CoordinateSystem3D::CheckAndComputeNormal() |
0 | 34 { |
35 // DICOM expects normal vectors to define the axes: "The row and | |
36 // column direction cosine vectors shall be normal, i.e., the dot | |
37 // product of each direction cosine vector with itself shall be | |
38 // unity." | |
39 // http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.2.html | |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
157
diff
changeset
|
40 if (!LinearAlgebra::IsNear(boost::numeric::ublas::norm_2(axisX_), 1.0) || |
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
157
diff
changeset
|
41 !LinearAlgebra::IsNear(boost::numeric::ublas::norm_2(axisY_), 1.0)) |
0 | 42 { |
43 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | |
44 } | |
45 | |
46 // The vectors within "Image Orientation Patient" must be | |
47 // orthogonal, according to the DICOM specification: "The row and | |
48 // column direction cosine vectors shall be orthogonal, i.e., | |
49 // their dot product shall be zero." | |
50 // http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.6.2.html | |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
157
diff
changeset
|
51 if (!LinearAlgebra::IsCloseToZero(boost::numeric::ublas::inner_prod(axisX_, axisY_))) |
0 | 52 { |
53 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | |
54 } | |
55 | |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
157
diff
changeset
|
56 LinearAlgebra::CrossProduct(normal_, axisX_, axisY_); |
0 | 57 |
157
2309e8d86efe
IntersectPlaneAndLine
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
152
diff
changeset
|
58 d_ = -(normal_[0] * origin_[0] + normal_[1] * origin_[1] + normal_[2] * origin_[2]); |
2309e8d86efe
IntersectPlaneAndLine
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
152
diff
changeset
|
59 |
0 | 60 // Just a sanity check, it should be useless by construction |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
157
diff
changeset
|
61 assert(LinearAlgebra::IsNear(boost::numeric::ublas::norm_2(normal_), 1.0)); |
0 | 62 } |
63 | |
64 | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
65 void CoordinateSystem3D::SetupCanonical() |
0 | 66 { |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
157
diff
changeset
|
67 LinearAlgebra::AssignVector(origin_, 0, 0, 0); |
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
157
diff
changeset
|
68 LinearAlgebra::AssignVector(axisX_, 1, 0, 0); |
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
157
diff
changeset
|
69 LinearAlgebra::AssignVector(axisY_, 0, 1, 0); |
0 | 70 CheckAndComputeNormal(); |
71 } | |
72 | |
73 | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
74 CoordinateSystem3D::CoordinateSystem3D(const Vector& origin, |
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
75 const Vector& axisX, |
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
76 const Vector& axisY) : |
0 | 77 origin_(origin), |
78 axisX_(axisX), | |
79 axisY_(axisY) | |
80 { | |
81 CheckAndComputeNormal(); | |
82 } | |
83 | |
84 | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
85 void CoordinateSystem3D::Setup(const std::string& imagePositionPatient, |
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
86 const std::string& imageOrientationPatient) |
0 | 87 { |
88 std::string tmpPosition = Orthanc::Toolbox::StripSpaces(imagePositionPatient); | |
89 std::string tmpOrientation = Orthanc::Toolbox::StripSpaces(imageOrientationPatient); | |
90 | |
91 Vector orientation; | |
158
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
157
diff
changeset
|
92 if (!LinearAlgebra::ParseVector(origin_, tmpPosition) || |
a053ca7fa5c6
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
157
diff
changeset
|
93 !LinearAlgebra::ParseVector(orientation, tmpOrientation) || |
0 | 94 origin_.size() != 3 || |
95 orientation.size() != 6) | |
96 { | |
97 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | |
98 } | |
99 | |
100 axisX_.resize(3); | |
101 axisX_[0] = orientation[0]; | |
102 axisX_[1] = orientation[1]; | |
103 axisX_[2] = orientation[2]; | |
104 | |
105 axisY_.resize(3); | |
106 axisY_[0] = orientation[3]; | |
107 axisY_[1] = orientation[4]; | |
108 axisY_[2] = orientation[5]; | |
109 | |
110 CheckAndComputeNormal(); | |
111 } | |
112 | |
113 | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
114 CoordinateSystem3D::CoordinateSystem3D(const OrthancPlugins::IDicomDataset& dicom) |
0 | 115 { |
32 | 116 std::string a, b; |
117 | |
118 if (dicom.GetStringValue(a, OrthancPlugins::DICOM_TAG_IMAGE_POSITION_PATIENT) && | |
119 dicom.GetStringValue(b, OrthancPlugins::DICOM_TAG_IMAGE_ORIENTATION_PATIENT)) | |
0 | 120 { |
32 | 121 Setup(a, b); |
0 | 122 } |
123 else | |
124 { | |
125 SetupCanonical(); | |
126 } | |
122
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
127 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
128 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
129 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
130 CoordinateSystem3D::CoordinateSystem3D(const Orthanc::DicomMap& dicom) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
131 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
132 std::string a, b; |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
133 |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
134 if (dicom.CopyToString(a, Orthanc::DICOM_TAG_IMAGE_POSITION_PATIENT, false) && |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
135 dicom.CopyToString(b, Orthanc::DICOM_TAG_IMAGE_ORIENTATION_PATIENT, false)) |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
136 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
137 Setup(a, b); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
138 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
139 else |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
140 { |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
141 SetupCanonical(); |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
142 } |
e3433dabfb8d
refactoring DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
113
diff
changeset
|
143 } |
0 | 144 |
145 | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
146 Vector CoordinateSystem3D::MapSliceToWorldCoordinates(double x, |
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
147 double y) const |
0 | 148 { |
149 return origin_ + x * axisX_ + y * axisY_; | |
150 } | |
151 | |
152 | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
153 double CoordinateSystem3D::ProjectAlongNormal(const Vector& point) const |
0 | 154 { |
155 return boost::numeric::ublas::inner_prod(point, normal_); | |
156 } | |
157 | |
158 | |
110
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
159 void CoordinateSystem3D::ProjectPoint(double& offsetX, |
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
160 double& offsetY, |
53025eecbc95
renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
89
diff
changeset
|
161 const Vector& point) const |
0 | 162 { |
163 // Project the point onto the slice | |
164 Vector projection; | |
165 GeometryToolbox::ProjectPointOntoPlane(projection, point, normal_, origin_); | |
166 | |
167 // As the axes are orthonormal vectors thanks to | |
168 // CheckAndComputeNormal(), the following dot products give the | |
169 // offset of the origin of the slice wrt. the origin of the | |
170 // reference plane https://en.wikipedia.org/wiki/Vector_projection | |
171 offsetX = boost::numeric::ublas::inner_prod(axisX_, projection - origin_); | |
172 offsetY = boost::numeric::ublas::inner_prod(axisY_, projection - origin_); | |
173 } | |
151
c5044bbfc303
CoordinateSystem3D::IntersectSegment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
174 |
c5044bbfc303
CoordinateSystem3D::IntersectSegment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
175 |
152 | 176 bool CoordinateSystem3D::IntersectSegment(Vector& p, |
151
c5044bbfc303
CoordinateSystem3D::IntersectSegment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
177 const Vector& edgeFrom, |
c5044bbfc303
CoordinateSystem3D::IntersectSegment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
178 const Vector& edgeTo) const |
c5044bbfc303
CoordinateSystem3D::IntersectSegment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
179 { |
157
2309e8d86efe
IntersectPlaneAndLine
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
152
diff
changeset
|
180 return GeometryToolbox::IntersectPlaneAndSegment(p, normal_, d_, edgeFrom, edgeTo); |
2309e8d86efe
IntersectPlaneAndLine
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
152
diff
changeset
|
181 } |
2309e8d86efe
IntersectPlaneAndLine
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
152
diff
changeset
|
182 |
2309e8d86efe
IntersectPlaneAndLine
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
152
diff
changeset
|
183 |
2309e8d86efe
IntersectPlaneAndLine
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
152
diff
changeset
|
184 bool CoordinateSystem3D::IntersectLine(Vector& p, |
2309e8d86efe
IntersectPlaneAndLine
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
152
diff
changeset
|
185 const Vector& origin, |
2309e8d86efe
IntersectPlaneAndLine
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
152
diff
changeset
|
186 const Vector& direction) const |
2309e8d86efe
IntersectPlaneAndLine
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
152
diff
changeset
|
187 { |
2309e8d86efe
IntersectPlaneAndLine
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
152
diff
changeset
|
188 return GeometryToolbox::IntersectPlaneAndLine(p, normal_, d_, origin, direction); |
151
c5044bbfc303
CoordinateSystem3D::IntersectSegment()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
135
diff
changeset
|
189 } |
0 | 190 } |