Mercurial > hg > orthanc-stone
comparison Samples/Common/MeasureTools.cpp @ 645:1e9ed656318e
Merge + ongoing measure work
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Mon, 13 May 2019 15:12:56 +0200 |
parents | f939f449482c |
children | 462a5074f914 |
comparison
equal
deleted
inserted
replaced
644:f939f449482c | 645:1e9ed656318e |
---|---|
16 * | 16 * |
17 * You should have received a copy of the GNU Affero General Public License | 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/>. | 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 **/ | 19 **/ |
20 | 20 |
21 #include "MeasureTools.h" | |
22 | |
21 #include <Core/Logging.h> | 23 #include <Core/Logging.h> |
22 #include "MeasureTools.h" | 24 |
23 #include <boost/math/constants/constants.hpp> | 25 #include <boost/math/constants/constants.hpp> |
24 | 26 |
25 namespace OrthancStone | 27 namespace OrthancStone |
26 { | 28 { |
27 void MeasureTool::Enable() | 29 void MeasureTool::Enable() |
33 void MeasureTool::Disable() | 35 void MeasureTool::Disable() |
34 { | 36 { |
35 enabled_ = false; | 37 enabled_ = false; |
36 RefreshScene(); | 38 RefreshScene(); |
37 } | 39 } |
38 | |
39 LineMeasureTool::~LineMeasureTool() | |
40 { | |
41 // this measuring tool is a RABI for the corresponding visual layers | |
42 // stored in the 2D scene | |
43 Disable(); | |
44 RemoveFromScene(); | |
45 } | |
46 | |
47 void LineMeasureTool::RemoveFromScene() | |
48 { | |
49 if (layersCreated) | |
50 { | |
51 assert(GetScene().HasLayer(polylineZIndex_)); | |
52 assert(GetScene().HasLayer(textZIndex_)); | |
53 GetScene().DeleteLayer(polylineZIndex_); | |
54 GetScene().DeleteLayer(textZIndex_); | |
55 } | |
56 } | |
57 | |
58 | |
59 void LineMeasureTool::SetStart(ScenePoint2D start) | |
60 { | |
61 start_ = start; | |
62 RefreshScene(); | |
63 } | |
64 | |
65 void LineMeasureTool::SetEnd(ScenePoint2D end) | |
66 { | |
67 end_ = end; | |
68 RefreshScene(); | |
69 } | |
70 | |
71 void LineMeasureTool::Set(ScenePoint2D start, ScenePoint2D end) | |
72 { | |
73 start_ = start; | |
74 end_ = end; | |
75 RefreshScene(); | |
76 } | |
77 | |
78 PolylineSceneLayer* LineMeasureTool::GetPolylineLayer() | |
79 { | |
80 assert(GetScene().HasLayer(polylineZIndex_)); | |
81 ISceneLayer* layer = &(GetScene().GetLayer(polylineZIndex_)); | |
82 PolylineSceneLayer* concreteLayer = dynamic_cast<PolylineSceneLayer*>(layer); | |
83 assert(concreteLayer != NULL); | |
84 return concreteLayer; | |
85 } | |
86 | |
87 TextSceneLayer* LineMeasureTool::GetTextLayer() | |
88 { | |
89 assert(GetScene().HasLayer(textZIndex_)); | |
90 ISceneLayer* layer = &(GetScene().GetLayer(textZIndex_)); | |
91 TextSceneLayer* concreteLayer = dynamic_cast<TextSceneLayer*>(layer); | |
92 assert(concreteLayer != NULL); | |
93 return concreteLayer; | |
94 } | |
95 | |
96 namespace | |
97 { | |
98 /** | |
99 This function will create a square around the center point supplied in | |
100 scene coordinates, with a side length given in canvas coordinates. The | |
101 square sides are parallel to the canvas boundaries. | |
102 */ | |
103 void AddSquare(PolylineSceneLayer::Chain& chain, | |
104 const Scene2D& scene, | |
105 const ScenePoint2D& centerS, | |
106 const double& sideLength) | |
107 { | |
108 chain.clear(); | |
109 chain.reserve(4); | |
110 ScenePoint2D centerC = centerS.Apply(scene.GetSceneToCanvasTransform()); | |
111 //TODO: take DPI into account | |
112 double handleLX = centerC.GetX() - sideLength / 2; | |
113 double handleTY = centerC.GetY() - sideLength / 2; | |
114 double handleRX = centerC.GetX() + sideLength / 2; | |
115 double handleBY = centerC.GetY() + sideLength / 2; | |
116 ScenePoint2D LTC(handleLX, handleTY); | |
117 ScenePoint2D RTC(handleRX, handleTY); | |
118 ScenePoint2D RBC(handleRX, handleBY); | |
119 ScenePoint2D LBC(handleLX, handleBY); | |
120 | |
121 ScenePoint2D startLT = LTC.Apply(scene.GetCanvasToSceneTransform()); | |
122 ScenePoint2D startRT = RTC.Apply(scene.GetCanvasToSceneTransform()); | |
123 ScenePoint2D startRB = RBC.Apply(scene.GetCanvasToSceneTransform()); | |
124 ScenePoint2D startLB = LBC.Apply(scene.GetCanvasToSceneTransform()); | |
125 | |
126 chain.push_back(startLT); | |
127 chain.push_back(startRT); | |
128 chain.push_back(startRB); | |
129 chain.push_back(startLB); | |
130 } | |
131 | |
132 void AddCircle(PolylineSceneLayer::Chain& chain, | |
133 const Scene2D& scene, | |
134 const ScenePoint2D& centerS, | |
135 const double& radiusS) | |
136 { | |
137 chain.clear(); | |
138 chain.reserve(4); | |
139 //ScenePoint2D centerC = centerS.Apply(scene.GetSceneToCanvasTransform()); | |
140 //TODO: take DPI into account | |
141 | |
142 // TODO: automatically compute the number for segments for smooth | |
143 // display based on the radius in pixels. | |
144 int lineCount = 50; | |
145 | |
146 double angleIncr = (2.0 * boost::math::constants::pi<double>()) | |
147 / static_cast<double>(lineCount); | |
148 | |
149 double theta = 0; | |
150 for (int i = 0; i < lineCount; ++i) | |
151 { | |
152 double offsetX = radiusS * cos(theta); | |
153 double offsetY = radiusS * sin(theta); | |
154 double pointX = centerS.GetX() + offsetX; | |
155 double pointY = centerS.GetY() + offsetY; | |
156 chain.push_back(ScenePoint2D(pointX, pointY)); | |
157 theta += angleIncr; | |
158 } | |
159 } | |
160 | |
161 #if 0 | |
162 void AddEllipse(PolylineSceneLayer::Chain& chain, | |
163 const Scene2D& scene, | |
164 const ScenePoint2D& centerS, | |
165 const double& halfHAxis, | |
166 const double& halfVAxis) | |
167 { | |
168 chain.clear(); | |
169 chain.reserve(4); | |
170 ScenePoint2D centerC = centerS.Apply(scene.GetSceneToCanvasTransform()); | |
171 //TODO: take DPI into account | |
172 double handleLX = centerC.GetX() - sideLength / 2; | |
173 double handleTY = centerC.GetY() - sideLength / 2; | |
174 double handleRX = centerC.GetX() + sideLength / 2; | |
175 double handleBY = centerC.GetY() + sideLength / 2; | |
176 ScenePoint2D LTC(handleLX, handleTY); | |
177 ScenePoint2D RTC(handleRX, handleTY); | |
178 ScenePoint2D RBC(handleRX, handleBY); | |
179 ScenePoint2D LBC(handleLX, handleBY); | |
180 | |
181 ScenePoint2D startLT = LTC.Apply(scene.GetCanvasToSceneTransform()); | |
182 ScenePoint2D startRT = RTC.Apply(scene.GetCanvasToSceneTransform()); | |
183 ScenePoint2D startRB = RBC.Apply(scene.GetCanvasToSceneTransform()); | |
184 ScenePoint2D startLB = LBC.Apply(scene.GetCanvasToSceneTransform()); | |
185 | |
186 chain.push_back(startLT); | |
187 chain.push_back(startRT); | |
188 chain.push_back(startRB); | |
189 chain.push_back(startLB); | |
190 } | |
191 #endif | |
192 | |
193 | |
194 } | |
195 | |
196 | |
197 void LineMeasureTool::RefreshScene() | |
198 { | |
199 if (IsEnabled()) | |
200 { | |
201 if (!layersCreated) | |
202 { | |
203 // Create the layers if need be | |
204 | |
205 assert(textZIndex_ == -1); | |
206 { | |
207 polylineZIndex_ = GetScene().GetMaxDepth() + 100; | |
208 //LOG(INFO) << "set polylineZIndex_ to: " << polylineZIndex_; | |
209 std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer()); | |
210 GetScene().SetLayer(polylineZIndex_, layer.release()); | |
211 } | |
212 { | |
213 textZIndex_ = GetScene().GetMaxDepth() + 100; | |
214 //LOG(INFO) << "set textZIndex_ to: " << textZIndex_; | |
215 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); | |
216 GetScene().SetLayer(textZIndex_, layer.release()); | |
217 } | |
218 layersCreated = true; | |
219 } | |
220 else | |
221 { | |
222 assert(GetScene().HasLayer(polylineZIndex_)); | |
223 assert(GetScene().HasLayer(textZIndex_)); | |
224 } | |
225 { | |
226 // Fill the polyline layer with the measurement line | |
227 | |
228 PolylineSceneLayer* polylineLayer = GetPolylineLayer(); | |
229 polylineLayer->ClearAllChains(); | |
230 polylineLayer->SetColor(0, 223, 21); | |
231 | |
232 { | |
233 PolylineSceneLayer::Chain chain; | |
234 chain.push_back(start_); | |
235 chain.push_back(end_); | |
236 polylineLayer->AddChain(chain, false); | |
237 } | |
238 | |
239 // handles | |
240 { | |
241 //void AddSquare(PolylineSceneLayer::Chain& chain,const Scene2D& scene,const ScenePoint2D& centerS,const double& sideLength) | |
242 | |
243 { | |
244 PolylineSceneLayer::Chain chain; | |
245 AddSquare(chain, GetScene(), start_, 10.0); //TODO: take DPI into account | |
246 polylineLayer->AddChain(chain, true); | |
247 } | |
248 | |
249 { | |
250 PolylineSceneLayer::Chain chain; | |
251 AddSquare(chain, GetScene(), end_, 10.0); //TODO: take DPI into account | |
252 polylineLayer->AddChain(chain, true); | |
253 } | |
254 | |
255 //ScenePoint2D startC = start_.Apply(GetScene().GetSceneToCanvasTransform()); | |
256 //double squareSize = 10.0; | |
257 //double startHandleLX = startC.GetX() - squareSize/2; | |
258 //double startHandleTY = startC.GetY() - squareSize / 2; | |
259 //double startHandleRX = startC.GetX() + squareSize / 2; | |
260 //double startHandleBY = startC.GetY() + squareSize / 2; | |
261 //ScenePoint2D startLTC(startHandleLX, startHandleTY); | |
262 //ScenePoint2D startRTC(startHandleRX, startHandleTY); | |
263 //ScenePoint2D startRBC(startHandleRX, startHandleBY); | |
264 //ScenePoint2D startLBC(startHandleLX, startHandleBY); | |
265 | |
266 //ScenePoint2D startLT = startLTC.Apply(GetScene().GetCanvasToSceneTransform()); | |
267 //ScenePoint2D startRT = startRTC.Apply(GetScene().GetCanvasToSceneTransform()); | |
268 //ScenePoint2D startRB = startRBC.Apply(GetScene().GetCanvasToSceneTransform()); | |
269 //ScenePoint2D startLB = startLBC.Apply(GetScene().GetCanvasToSceneTransform()); | |
270 | |
271 //PolylineSceneLayer::Chain chain; | |
272 //chain.push_back(startLT); | |
273 //chain.push_back(startRT); | |
274 //chain.push_back(startRB); | |
275 //chain.push_back(startLB); | |
276 //polylineLayer->AddChain(chain, true); | |
277 } | |
278 | |
279 } | |
280 { | |
281 // Set the text layer proporeties | |
282 | |
283 TextSceneLayer* textLayer = GetTextLayer(); | |
284 double deltaX = end_.GetX() - start_.GetX(); | |
285 double deltaY = end_.GetY() - start_.GetY(); | |
286 double squareDist = deltaX * deltaX + deltaY * deltaY; | |
287 double dist = sqrt(squareDist); | |
288 char buf[64]; | |
289 sprintf(buf, "%0.02f units", dist); | |
290 textLayer->SetText(buf); | |
291 textLayer->SetColor(0, 223, 21); | |
292 | |
293 // TODO: for now we simply position the text overlay at the middle | |
294 // of the measuring segment | |
295 double midX = 0.5*(end_.GetX() + start_.GetX()); | |
296 double midY = 0.5*(end_.GetY() + start_.GetY()); | |
297 textLayer->SetPosition(midX, midY); | |
298 } | |
299 } | |
300 else | |
301 { | |
302 if (layersCreated) | |
303 { | |
304 RemoveFromScene(); | |
305 layersCreated = false; | |
306 } | |
307 } | |
308 } | |
309 } | 40 } |
310 | 41 |