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 }