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