Mercurial > hg > orthanc-stone
comparison Framework/Scene2DViewport/AngleMeasureTool.cpp @ 722:28b9e3a54200
Undo mechanism implemented (not connected to UI yet). Undo stack and measuring
tools are now handled by the ViewportController. Multi-touch does not crash
trackers anymore.
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Tue, 21 May 2019 10:27:54 +0200 |
parents | 8b6adfb62a2f |
children | 712ff6ff3c19 |
comparison
equal
deleted
inserted
replaced
721:af0aa0c149fa | 722:28b9e3a54200 |
---|---|
75 return concreteLayer; | 75 return concreteLayer; |
76 } | 76 } |
77 | 77 |
78 void AngleMeasureTool::RefreshScene() | 78 void AngleMeasureTool::RefreshScene() |
79 { | 79 { |
80 if (IsEnabled()) | 80 if (IsSceneAlive()) |
81 { | 81 { |
82 // get the scaling factor | 82 |
83 const double pixelToScene = | 83 if (IsEnabled()) |
84 GetScene()->GetCanvasToSceneTransform().ComputeZoom(); | |
85 | |
86 if (!layersCreated) | |
87 { | 84 { |
88 // Create the layers if need be | 85 // get the scaling factor |
89 | 86 const double pixelToScene = |
90 assert(textBaseZIndex_ == -1); | 87 GetScene()->GetCanvasToSceneTransform().ComputeZoom(); |
91 { | 88 |
92 polylineZIndex_ = GetScene()->GetMaxDepth() + 100; | 89 if (!layersCreated) |
93 //LOG(INFO) << "set polylineZIndex_ to: " << polylineZIndex_; | 90 { |
94 std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer()); | 91 // Create the layers if need be |
95 GetScene()->SetLayer(polylineZIndex_, layer.release()); | 92 |
96 | 93 assert(textBaseZIndex_ == -1); |
97 } | 94 { |
98 { | 95 polylineZIndex_ = GetScene()->GetMaxDepth() + 100; |
99 textBaseZIndex_ = GetScene()->GetMaxDepth() + 100; | 96 //LOG(INFO) << "set polylineZIndex_ to: " << polylineZIndex_; |
100 // create the four text background layers | 97 std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer()); |
101 { | 98 GetScene()->SetLayer(polylineZIndex_, layer.release()); |
102 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); | 99 |
103 GetScene()->SetLayer(textBaseZIndex_, layer.release()); | 100 } |
104 } | 101 { |
105 { | 102 textBaseZIndex_ = GetScene()->GetMaxDepth() + 100; |
106 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); | 103 // create the four text background layers |
107 GetScene()->SetLayer(textBaseZIndex_+1, layer.release()); | 104 { |
108 } | 105 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); |
109 { | 106 GetScene()->SetLayer(textBaseZIndex_, layer.release()); |
110 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); | 107 } |
111 GetScene()->SetLayer(textBaseZIndex_+2, layer.release()); | 108 { |
112 } | 109 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); |
113 { | 110 GetScene()->SetLayer(textBaseZIndex_ + 1, layer.release()); |
114 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); | 111 } |
115 GetScene()->SetLayer(textBaseZIndex_+3, layer.release()); | 112 { |
116 } | 113 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); |
117 | 114 GetScene()->SetLayer(textBaseZIndex_ + 2, layer.release()); |
118 // and the text layer itself | 115 } |
119 { | 116 { |
120 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); | 117 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); |
121 GetScene()->SetLayer(textBaseZIndex_+4, layer.release()); | 118 GetScene()->SetLayer(textBaseZIndex_ + 3, layer.release()); |
122 } | 119 } |
123 | 120 |
124 } | 121 // and the text layer itself |
125 layersCreated = true; | 122 { |
123 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); | |
124 GetScene()->SetLayer(textBaseZIndex_ + 4, layer.release()); | |
125 } | |
126 | |
127 } | |
128 layersCreated = true; | |
129 } | |
130 else | |
131 { | |
132 assert(GetScene()->HasLayer(polylineZIndex_)); | |
133 assert(GetScene()->HasLayer(textBaseZIndex_)); | |
134 } | |
135 { | |
136 // Fill the polyline layer with the measurement line | |
137 | |
138 PolylineSceneLayer* polylineLayer = GetPolylineLayer(); | |
139 polylineLayer->ClearAllChains(); | |
140 polylineLayer->SetColor(0, 183, 17); | |
141 | |
142 // sides | |
143 { | |
144 { | |
145 PolylineSceneLayer::Chain chain; | |
146 chain.push_back(side1End_); | |
147 chain.push_back(center_); | |
148 polylineLayer->AddChain(chain, false); | |
149 } | |
150 { | |
151 PolylineSceneLayer::Chain chain; | |
152 chain.push_back(side2End_); | |
153 chain.push_back(center_); | |
154 polylineLayer->AddChain(chain, false); | |
155 } | |
156 } | |
157 | |
158 // handles | |
159 { | |
160 //void AddSquare(PolylineSceneLayer::Chain& chain,const Scene2D& scene,const ScenePoint2D& centerS,const double& sideLength) | |
161 | |
162 { | |
163 PolylineSceneLayer::Chain chain; | |
164 AddSquare(chain, *GetScene(), side1End_, 10.0 * pixelToScene); //TODO: take DPI into account | |
165 polylineLayer->AddChain(chain, true); | |
166 } | |
167 | |
168 { | |
169 PolylineSceneLayer::Chain chain; | |
170 AddSquare(chain, *GetScene(), side2End_, 10.0 * pixelToScene); //TODO: take DPI into account | |
171 polylineLayer->AddChain(chain, true); | |
172 } | |
173 } | |
174 | |
175 // arc | |
176 { | |
177 PolylineSceneLayer::Chain chain; | |
178 | |
179 const double ARC_RADIUS_CANVAS_COORD = 30.0; | |
180 AddShortestArc(chain, *GetScene(), side1End_, center_, side2End_, | |
181 ARC_RADIUS_CANVAS_COORD * pixelToScene); | |
182 polylineLayer->AddChain(chain, false); | |
183 } | |
184 } | |
185 { | |
186 // Set the text layer | |
187 | |
188 double p1cAngle = atan2( | |
189 side1End_.GetY() - center_.GetY(), | |
190 side1End_.GetX() - center_.GetX()); | |
191 | |
192 | |
193 double p2cAngle = atan2( | |
194 side2End_.GetY() - center_.GetY(), | |
195 side2End_.GetX() - center_.GetX()); | |
196 | |
197 double delta = NormalizeAngle(p2cAngle - p1cAngle); | |
198 | |
199 | |
200 double theta = p1cAngle + delta / 2; | |
201 | |
202 | |
203 const double TEXT_CENTER_DISTANCE_CANVAS_COORD = 90; | |
204 | |
205 double offsetX = TEXT_CENTER_DISTANCE_CANVAS_COORD * cos(theta); | |
206 | |
207 double offsetY = TEXT_CENTER_DISTANCE_CANVAS_COORD * sin(theta); | |
208 | |
209 double pointX = center_.GetX() + offsetX * pixelToScene; | |
210 double pointY = center_.GetY() + offsetY * pixelToScene; | |
211 | |
212 char buf[64]; | |
213 double angleDeg = RadiansToDegrees(delta); | |
214 | |
215 // http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=00B0&mode=hex | |
216 sprintf(buf, "%0.02f\xc2\xb0", angleDeg); | |
217 | |
218 SetTextLayerOutlineProperties( | |
219 *GetScene(), textBaseZIndex_, buf, ScenePoint2D(pointX, pointY)); | |
220 | |
221 // TODO:make it togglable | |
222 bool enableInfoDisplay = false; | |
223 if (enableInfoDisplay) | |
224 { | |
225 TrackerSample_SetInfoDisplayMessage("center_.GetX()", | |
226 boost::lexical_cast<std::string>(center_.GetX())); | |
227 | |
228 TrackerSample_SetInfoDisplayMessage("center_.GetY()", | |
229 boost::lexical_cast<std::string>(center_.GetY())); | |
230 | |
231 TrackerSample_SetInfoDisplayMessage("side1End_.GetX()", | |
232 boost::lexical_cast<std::string>(side1End_.GetX())); | |
233 | |
234 TrackerSample_SetInfoDisplayMessage("side1End_.GetY()", | |
235 boost::lexical_cast<std::string>(side1End_.GetY())); | |
236 | |
237 TrackerSample_SetInfoDisplayMessage("side2End_.GetX()", | |
238 boost::lexical_cast<std::string>(side2End_.GetX())); | |
239 | |
240 TrackerSample_SetInfoDisplayMessage("side2End_.GetY()", | |
241 boost::lexical_cast<std::string>(side2End_.GetY())); | |
242 | |
243 TrackerSample_SetInfoDisplayMessage("p1cAngle (deg)", | |
244 boost::lexical_cast<std::string>(RadiansToDegrees(p1cAngle))); | |
245 | |
246 TrackerSample_SetInfoDisplayMessage("delta (deg)", | |
247 boost::lexical_cast<std::string>(RadiansToDegrees(delta))); | |
248 | |
249 TrackerSample_SetInfoDisplayMessage("theta (deg)", | |
250 boost::lexical_cast<std::string>(RadiansToDegrees(theta))); | |
251 | |
252 TrackerSample_SetInfoDisplayMessage("p2cAngle (deg)", | |
253 boost::lexical_cast<std::string>(RadiansToDegrees(p2cAngle))); | |
254 | |
255 TrackerSample_SetInfoDisplayMessage("offsetX (pix)", | |
256 boost::lexical_cast<std::string>(offsetX)); | |
257 | |
258 TrackerSample_SetInfoDisplayMessage("offsetY (pix)", | |
259 boost::lexical_cast<std::string>(offsetY)); | |
260 | |
261 TrackerSample_SetInfoDisplayMessage("pointX", | |
262 boost::lexical_cast<std::string>(pointX)); | |
263 | |
264 TrackerSample_SetInfoDisplayMessage("pointY", | |
265 boost::lexical_cast<std::string>(pointY)); | |
266 | |
267 TrackerSample_SetInfoDisplayMessage("angleDeg", | |
268 boost::lexical_cast<std::string>(angleDeg)); | |
269 } | |
270 | |
271 | |
272 | |
273 } | |
126 } | 274 } |
127 else | 275 else |
128 { | 276 { |
129 assert(GetScene()->HasLayer(polylineZIndex_)); | 277 if (layersCreated) |
130 assert(GetScene()->HasLayer(textBaseZIndex_)); | 278 { |
131 } | 279 RemoveFromScene(); |
132 { | 280 layersCreated = false; |
133 // Fill the polyline layer with the measurement line | 281 } |
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 } | 282 } |
271 } | 283 } |
272 else | 284 } |
273 { | |
274 if (layersCreated) | |
275 { | |
276 RemoveFromScene(); | |
277 layersCreated = false; | |
278 } | |
279 } | |
280 } | |
281 | |
282 | |
283 } | 285 } |