Mercurial > hg > orthanc-stone
comparison Framework/Scene2DViewport/AngleMeasureTool.cpp @ 698:8b6adfb62a2f refactor-viewport-controller
Code is broken -- stashing ongoing work in a branch
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Wed, 15 May 2019 16:56:17 +0200 |
parents | |
children | 28b9e3a54200 |
comparison
equal
deleted
inserted
replaced
660:cb3b76d16234 | 698:8b6adfb62a2f |
---|---|
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 #include "AngleMeasureTool.h" | |
22 #include "MeasureToolsToolbox.h" | |
23 | |
24 #include <Core/Logging.h> | |
25 | |
26 #include <boost/math/constants/constants.hpp> | |
27 | |
28 extern void TrackerSample_SetInfoDisplayMessage(std::string key, std::string value); | |
29 | |
30 namespace OrthancStone | |
31 { | |
32 AngleMeasureTool::~AngleMeasureTool() | |
33 { | |
34 // this measuring tool is a RABI for the corresponding visual layers | |
35 // stored in the 2D scene | |
36 Disable(); | |
37 RemoveFromScene(); | |
38 } | |
39 | |
40 void AngleMeasureTool::RemoveFromScene() | |
41 { | |
42 if (layersCreated) | |
43 { | |
44 assert(GetScene()->HasLayer(polylineZIndex_)); | |
45 assert(GetScene()->HasLayer(textBaseZIndex_)); | |
46 GetScene()->DeleteLayer(polylineZIndex_); | |
47 GetScene()->DeleteLayer(textBaseZIndex_); | |
48 } | |
49 } | |
50 | |
51 void AngleMeasureTool::SetSide1End(ScenePoint2D pt) | |
52 { | |
53 side1End_ = pt; | |
54 RefreshScene(); | |
55 } | |
56 | |
57 void AngleMeasureTool::SetSide2End(ScenePoint2D pt) | |
58 { | |
59 side2End_ = pt; | |
60 RefreshScene(); | |
61 } | |
62 | |
63 void AngleMeasureTool::SetCenter(ScenePoint2D pt) | |
64 { | |
65 center_ = pt; | |
66 RefreshScene(); | |
67 } | |
68 | |
69 PolylineSceneLayer* AngleMeasureTool::GetPolylineLayer() | |
70 { | |
71 assert(GetScene()->HasLayer(polylineZIndex_)); | |
72 ISceneLayer* layer = &(GetScene()->GetLayer(polylineZIndex_)); | |
73 PolylineSceneLayer* concreteLayer = dynamic_cast<PolylineSceneLayer*>(layer); | |
74 assert(concreteLayer != NULL); | |
75 return concreteLayer; | |
76 } | |
77 | |
78 void AngleMeasureTool::RefreshScene() | |
79 { | |
80 if (IsEnabled()) | |
81 { | |
82 // get the scaling factor | |
83 const double pixelToScene = | |
84 GetScene()->GetCanvasToSceneTransform().ComputeZoom(); | |
85 | |
86 if (!layersCreated) | |
87 { | |
88 // Create the layers if need be | |
89 | |
90 assert(textBaseZIndex_ == -1); | |
91 { | |
92 polylineZIndex_ = GetScene()->GetMaxDepth() + 100; | |
93 //LOG(INFO) << "set polylineZIndex_ to: " << polylineZIndex_; | |
94 std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer()); | |
95 GetScene()->SetLayer(polylineZIndex_, layer.release()); | |
96 | |
97 } | |
98 { | |
99 textBaseZIndex_ = GetScene()->GetMaxDepth() + 100; | |
100 // create the four text background layers | |
101 { | |
102 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); | |
103 GetScene()->SetLayer(textBaseZIndex_, layer.release()); | |
104 } | |
105 { | |
106 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); | |
107 GetScene()->SetLayer(textBaseZIndex_+1, layer.release()); | |
108 } | |
109 { | |
110 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); | |
111 GetScene()->SetLayer(textBaseZIndex_+2, layer.release()); | |
112 } | |
113 { | |
114 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); | |
115 GetScene()->SetLayer(textBaseZIndex_+3, layer.release()); | |
116 } | |
117 | |
118 // and the text layer itself | |
119 { | |
120 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); | |
121 GetScene()->SetLayer(textBaseZIndex_+4, layer.release()); | |
122 } | |
123 | |
124 } | |
125 layersCreated = true; | |
126 } | |
127 else | |
128 { | |
129 assert(GetScene()->HasLayer(polylineZIndex_)); | |
130 assert(GetScene()->HasLayer(textBaseZIndex_)); | |
131 } | |
132 { | |
133 // Fill the polyline layer with the measurement line | |
134 | |
135 PolylineSceneLayer* polylineLayer = GetPolylineLayer(); | |
136 polylineLayer->ClearAllChains(); | |
137 polylineLayer->SetColor(0, 183, 17); | |
138 | |
139 // sides | |
140 { | |
141 { | |
142 PolylineSceneLayer::Chain chain; | |
143 chain.push_back(side1End_); | |
144 chain.push_back(center_); | |
145 polylineLayer->AddChain(chain, false); | |
146 } | |
147 { | |
148 PolylineSceneLayer::Chain chain; | |
149 chain.push_back(side2End_); | |
150 chain.push_back(center_); | |
151 polylineLayer->AddChain(chain, false); | |
152 } | |
153 } | |
154 | |
155 // handles | |
156 { | |
157 //void AddSquare(PolylineSceneLayer::Chain& chain,const Scene2D& scene,const ScenePoint2D& centerS,const double& sideLength) | |
158 | |
159 { | |
160 PolylineSceneLayer::Chain chain; | |
161 AddSquare(chain, *GetScene(), side1End_, 10.0* pixelToScene); //TODO: take DPI into account | |
162 polylineLayer->AddChain(chain, true); | |
163 } | |
164 | |
165 { | |
166 PolylineSceneLayer::Chain chain; | |
167 AddSquare(chain, *GetScene(), side2End_, 10.0* pixelToScene); //TODO: take DPI into account | |
168 polylineLayer->AddChain(chain, true); | |
169 } | |
170 } | |
171 | |
172 // arc | |
173 { | |
174 PolylineSceneLayer::Chain chain; | |
175 | |
176 const double ARC_RADIUS_CANVAS_COORD = 30.0; | |
177 AddShortestArc(chain, *GetScene(), side1End_, center_, side2End_, | |
178 ARC_RADIUS_CANVAS_COORD*pixelToScene); | |
179 polylineLayer->AddChain(chain, false); | |
180 } | |
181 } | |
182 { | |
183 // Set the text layer | |
184 | |
185 double p1cAngle = atan2( | |
186 side1End_.GetY() - center_.GetY(), | |
187 side1End_.GetX() - center_.GetX()); | |
188 | |
189 | |
190 double p2cAngle = atan2( | |
191 side2End_.GetY() - center_.GetY(), | |
192 side2End_.GetX() - center_.GetX()); | |
193 | |
194 double delta = NormalizeAngle(p2cAngle - p1cAngle); | |
195 | |
196 | |
197 double theta = p1cAngle + delta/2; | |
198 | |
199 | |
200 const double TEXT_CENTER_DISTANCE_CANVAS_COORD = 90; | |
201 | |
202 double offsetX = TEXT_CENTER_DISTANCE_CANVAS_COORD * cos(theta); | |
203 | |
204 double offsetY = TEXT_CENTER_DISTANCE_CANVAS_COORD * sin(theta); | |
205 | |
206 double pointX = center_.GetX() + offsetX * pixelToScene; | |
207 double pointY = center_.GetY() + offsetY * pixelToScene; | |
208 | |
209 char buf[64]; | |
210 double angleDeg = RadiansToDegrees(delta); | |
211 | |
212 // http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=00B0&mode=hex | |
213 sprintf(buf, "%0.02f\xc2\xb0", angleDeg); | |
214 | |
215 SetTextLayerOutlineProperties( | |
216 *GetScene(), textBaseZIndex_, buf, ScenePoint2D(pointX, pointY)); | |
217 | |
218 // TODO:make it togglable | |
219 bool enableInfoDisplay = false; | |
220 if (enableInfoDisplay) | |
221 { | |
222 TrackerSample_SetInfoDisplayMessage("center_.GetX()", | |
223 boost::lexical_cast<std::string>(center_.GetX())); | |
224 | |
225 TrackerSample_SetInfoDisplayMessage("center_.GetY()", | |
226 boost::lexical_cast<std::string>(center_.GetY())); | |
227 | |
228 TrackerSample_SetInfoDisplayMessage("side1End_.GetX()", | |
229 boost::lexical_cast<std::string>(side1End_.GetX())); | |
230 | |
231 TrackerSample_SetInfoDisplayMessage("side1End_.GetY()", | |
232 boost::lexical_cast<std::string>(side1End_.GetY())); | |
233 | |
234 TrackerSample_SetInfoDisplayMessage("side2End_.GetX()", | |
235 boost::lexical_cast<std::string>(side2End_.GetX())); | |
236 | |
237 TrackerSample_SetInfoDisplayMessage("side2End_.GetY()", | |
238 boost::lexical_cast<std::string>(side2End_.GetY())); | |
239 | |
240 TrackerSample_SetInfoDisplayMessage("p1cAngle (deg)", | |
241 boost::lexical_cast<std::string>(RadiansToDegrees(p1cAngle))); | |
242 | |
243 TrackerSample_SetInfoDisplayMessage("delta (deg)", | |
244 boost::lexical_cast<std::string>(RadiansToDegrees(delta))); | |
245 | |
246 TrackerSample_SetInfoDisplayMessage("theta (deg)", | |
247 boost::lexical_cast<std::string>(RadiansToDegrees(theta))); | |
248 | |
249 TrackerSample_SetInfoDisplayMessage("p2cAngle (deg)", | |
250 boost::lexical_cast<std::string>(RadiansToDegrees(p2cAngle))); | |
251 | |
252 TrackerSample_SetInfoDisplayMessage("offsetX (pix)", | |
253 boost::lexical_cast<std::string>(offsetX)); | |
254 | |
255 TrackerSample_SetInfoDisplayMessage("offsetY (pix)", | |
256 boost::lexical_cast<std::string>(offsetY)); | |
257 | |
258 TrackerSample_SetInfoDisplayMessage("pointX", | |
259 boost::lexical_cast<std::string>(pointX)); | |
260 | |
261 TrackerSample_SetInfoDisplayMessage("pointY", | |
262 boost::lexical_cast<std::string>(pointY)); | |
263 | |
264 TrackerSample_SetInfoDisplayMessage("angleDeg", | |
265 boost::lexical_cast<std::string>(angleDeg)); | |
266 } | |
267 | |
268 | |
269 | |
270 } | |
271 } | |
272 else | |
273 { | |
274 if (layersCreated) | |
275 { | |
276 RemoveFromScene(); | |
277 layersCreated = false; | |
278 } | |
279 } | |
280 } | |
281 | |
282 | |
283 } |