annotate Sources/StructureSetGeometry.cpp @ 35:ee3bc8f7df5b

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 04 Apr 2024 20:37:08 +0200
parents
children 8a1daa321afe
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
35
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
1 /**
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
2 * SPDX-FileCopyrightText: 2023-2024 Sebastien Jodogne, UCLouvain, Belgium
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
3 * SPDX-License-Identifier: GPL-3.0-or-later
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
4 */
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
5
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
6 /**
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
7 * STL plugin for Orthanc
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
8 * Copyright (C) 2023-2024 Sebastien Jodogne, UCLouvain, Belgium
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
9 *
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
10 * This program is free software: you can redistribute it and/or
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
11 * modify it under the terms of the GNU General Public License as
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
12 * published by the Free Software Foundation, either version 3 of the
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
13 * License, or (at your option) any later version.
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
14 *
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
15 * This program is distributed in the hope that it will be useful, but
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
18 * General Public License for more details.
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
19 *
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
20 * You should have received a copy of the GNU General Public License
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
22 **/
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
23
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
24
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
25 #include "StructureSetGeometry.h"
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
26
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
27 #include "STLToolbox.h"
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
28
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
29 #include <OrthancException.h>
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
30
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
31 #include <list>
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
32
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
33
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
34 bool StructureSetGeometry::LookupProjectionIndex(size_t& index,
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
35 double z) const
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
36 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
37 if (slicesCount_ == 0)
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
38 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
39 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
40 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
41
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
42 if (z < minProjectionAlongNormal_ ||
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
43 z > maxProjectionAlongNormal_)
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
44 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
45 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
46 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
47
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
48 assert(slicesSpacing_ > 0 &&
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
49 minProjectionAlongNormal_ < maxProjectionAlongNormal_);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
50
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
51 double d = (z - minProjectionAlongNormal_) / slicesSpacing_;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
52
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
53 if (STLToolbox::IsNear(d, round(d)))
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
54 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
55 if (d < 0.0 ||
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
56 d > static_cast<double>(slicesCount_) - 1.0)
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
57 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
58 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
59 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
60 else
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
61 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
62 index = static_cast<size_t>(round(d));
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
63 return true;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
64 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
65 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
66 else
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
67 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
68 return false;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
69 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
70 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
71
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
72
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
73 StructureSetGeometry::StructureSetGeometry(const StructureSet& structures,
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
74 bool strict)
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
75 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
76 bool isValid = false;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
77
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
78 std::vector<double> projections;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
79 projections.reserve(structures.GetPolygonsCount());
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
80
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
81 for (size_t i = 0; i < structures.GetPolygonsCount(); i++)
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
82 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
83 Vector3D normal;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
84 if (structures.GetPolygon(i).IsCoplanar(normal))
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
85 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
86 // Initialize the normal of the whole volume, if need be
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
87 if (!isValid)
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
88 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
89 isValid = true;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
90 slicesNormal_ = normal;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
91 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
92
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
93 if (Vector3D::AreParallel(normal, slicesNormal_))
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
94 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
95 // This is a valid slice (it is parallel to the normal)
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
96 const Vector3D& point = structures.GetPolygon(i).GetPoint(0);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
97 projections.push_back(Vector3D::DotProduct(point, slicesNormal_));
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
98 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
99 else
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
100 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
101 // RT-STRUCT with non-parallel slices
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
102 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
103 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
104 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
105 else
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
106 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
107 // Ignore slices that are not coplanar
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
108 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
109 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
110
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
111 if (projections.empty())
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
112 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
113 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented,
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
114 "Structure set without a valid geometry");
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
115 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
116
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
117 // Only keep unique projections
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
118
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
119 std::sort(projections.begin(), projections.end());
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
120 STLToolbox::RemoveDuplicateValues(projections);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
121 assert(!projections.empty());
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
122
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
123 if (projections.size() == 1)
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
124 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
125 // Volume with one single slice
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
126 minProjectionAlongNormal_ = projections[0];
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
127 maxProjectionAlongNormal_ = projections[0];
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
128 slicesSpacing_ = 1; // Arbitrary value
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
129 slicesCount_ = 1;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
130 return;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
131 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
132
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
133
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
134 // Compute the most probable spacing between the slices
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
135
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
136 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
137 std::vector<double> spacings;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
138 spacings.resize(projections.size() - 1);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
139
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
140 for (size_t i = 0; i < spacings.size(); i++)
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
141 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
142 spacings[i] = projections[i + 1] - projections[i];
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
143 assert(spacings[i] > 0);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
144 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
145
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
146 std::sort(spacings.begin(), spacings.end());
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
147 STLToolbox::RemoveDuplicateValues(spacings);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
148
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
149 if (spacings.empty())
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
150 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
151 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
152 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
153
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
154 slicesSpacing_ = spacings[spacings.size() / 10]; // Take the 90% percentile of smallest spacings
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
155 assert(slicesSpacing_ > 0);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
156 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
157
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
158
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
159 // Find the projection along the normal with the largest support
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
160
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
161 bool first = true;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
162 size_t bestSupport;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
163 double bestProjection;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
164
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
165 std::list<size_t> candidates;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
166 for (size_t i = 0; i < projections.size(); i++)
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
167 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
168 candidates.push_back(i);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
169 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
170
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
171 while (!candidates.empty())
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
172 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
173 std::list<size_t> next;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
174
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
175 size_t countSupport = 0;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
176
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
177 std::list<size_t>::const_iterator it = candidates.begin();
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
178 size_t reference = *it;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
179 it++;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
180
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
181 while (it != candidates.end())
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
182 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
183 double d = (projections[*it] - projections[reference]) / slicesSpacing_;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
184 if (STLToolbox::IsNear(d, round(d)))
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
185 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
186 countSupport ++;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
187 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
188 else
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
189 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
190 next.push_back(*it);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
191 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
192
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
193 it++;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
194 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
195
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
196 if (first ||
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
197 countSupport > bestSupport)
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
198 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
199 first = false;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
200 bestSupport = countSupport;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
201 bestProjection = projections[reference];
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
202 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
203
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
204 if (strict &&
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
205 !next.empty())
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
206 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
207 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
208 "Structure set with multiple support, which is not allowed in Strict mode");
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
209 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
210
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
211 candidates.swap(next);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
212 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
213
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
214
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
215 // Compute the range of the projections
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
216
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
217 minProjectionAlongNormal_ = bestProjection;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
218 maxProjectionAlongNormal_ = bestProjection;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
219
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
220 for (size_t i = 0; i < projections.size(); i++)
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
221 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
222 double d = (projections[i] - bestProjection) / slicesSpacing_;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
223 if (STLToolbox::IsNear(d, round(d)))
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
224 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
225 minProjectionAlongNormal_ = std::min(minProjectionAlongNormal_, projections[i]);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
226 maxProjectionAlongNormal_ = std::max(maxProjectionAlongNormal_, projections[i]);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
227 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
228 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
229
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
230 double d = (maxProjectionAlongNormal_ - minProjectionAlongNormal_) / slicesSpacing_;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
231 if (STLToolbox::IsNear(d, round(d)))
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
232 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
233 slicesCount_ = static_cast<size_t>(round(d)) + 1;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
234 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
235 else
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
236 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
237 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
238 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
239
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
240
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
241 // Sanity check
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
242
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
243 size_t a, b;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
244 if (!LookupProjectionIndex(a, minProjectionAlongNormal_) ||
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
245 !LookupProjectionIndex(b, maxProjectionAlongNormal_) ||
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
246 a != 0 ||
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
247 b + 1 != slicesCount_)
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
248 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
249 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
250 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
251 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
252
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
253
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
254 bool StructureSetGeometry::ProjectAlongNormal(double& z,
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
255 const StructurePolygon& polygon) const
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
256 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
257 Vector3D normal;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
258 if (polygon.IsCoplanar(normal) &&
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
259 Vector3D::AreParallel(normal, slicesNormal_))
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
260 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
261 z = Vector3D::DotProduct(polygon.GetPoint(0), slicesNormal_);
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
262 return true;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
263 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
264 else
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
265 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
266 return false;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
267 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
268 }
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
269
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
270
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
271 bool StructureSetGeometry::LookupSliceIndex(size_t& slice,
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
272 const StructurePolygon& polygon) const
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
273 {
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
274 double z;
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
275 return (ProjectAlongNormal(z, polygon) &&
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
276 LookupProjectionIndex(slice, z));
ee3bc8f7df5b reorganization
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
277 }