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 }