Mercurial > hg > orthanc-stone
comparison Framework/Scene2DViewport/AngleMeasureTool.cpp @ 751:712ff6ff3c19
- undo redo now works fine for both measure tool creation commands
- added LayerHolder to streamline layer index management
- added overloads for ORTHANC_ASSERT with no string message (some heavy
preprocessor wizardry in there)
- fixing wasm BasicScene is *not* finished.
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Wed, 22 May 2019 11:55:52 +0200 |
parents | 28b9e3a54200 |
children | 66ac7a2d1e3a |
comparison
equal
deleted
inserted
replaced
750:284f37dc1c66 | 751:712ff6ff3c19 |
---|---|
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, ViewportControllerWPtr 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 { |
64 { | 79 { |
65 center_ = pt; | 80 center_ = pt; |
66 RefreshScene(); | 81 RefreshScene(); |
67 } | 82 } |
68 | 83 |
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() | 84 void AngleMeasureTool::RefreshScene() |
79 { | 85 { |
80 if (IsSceneAlive()) | 86 if (IsSceneAlive()) |
81 { | 87 { |
82 | |
83 if (IsEnabled()) | 88 if (IsEnabled()) |
84 { | 89 { |
85 // get the scaling factor | 90 // get the scaling factor |
86 const double pixelToScene = | 91 const double pixelToScene = |
87 GetScene()->GetCanvasToSceneTransform().ComputeZoom(); | 92 GetScene()->GetCanvasToSceneTransform().ComputeZoom(); |
88 | 93 |
89 if (!layersCreated) | 94 layerHolder_->CreateLayersIfNeeded(); |
95 | |
90 { | 96 { |
91 // Create the layers if need be | 97 // Fill the polyline layer with the measurement lines |
92 | 98 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(); | 99 polylineLayer->ClearAllChains(); |
140 polylineLayer->SetColor(0, 183, 17); | 100 polylineLayer->SetColor(0, 183, 17); |
101 | |
141 | 102 |
142 // sides | 103 // sides |
143 { | 104 { |
144 { | 105 { |
145 PolylineSceneLayer::Chain chain; | 106 PolylineSceneLayer::Chain chain; |
153 chain.push_back(center_); | 114 chain.push_back(center_); |
154 polylineLayer->AddChain(chain, false); | 115 polylineLayer->AddChain(chain, false); |
155 } | 116 } |
156 } | 117 } |
157 | 118 |
158 // handles | 119 // Create the handles |
159 { | 120 { |
160 //void AddSquare(PolylineSceneLayer::Chain& chain,const Scene2D& scene,const ScenePoint2D& centerS,const double& sideLength) | 121 { |
161 | 122 PolylineSceneLayer::Chain chain; |
162 { | 123 //TODO: take DPI into account |
163 PolylineSceneLayer::Chain chain; | 124 AddSquare(chain, GetScene(), side1End_, 10.0 * pixelToScene); |
164 AddSquare(chain, *GetScene(), side1End_, 10.0 * pixelToScene); //TODO: take DPI into account | |
165 polylineLayer->AddChain(chain, true); | 125 polylineLayer->AddChain(chain, true); |
166 } | 126 } |
167 | 127 { |
168 { | 128 PolylineSceneLayer::Chain chain; |
169 PolylineSceneLayer::Chain chain; | 129 //TODO: take DPI into account |
170 AddSquare(chain, *GetScene(), side2End_, 10.0 * pixelToScene); //TODO: take DPI into account | 130 AddSquare(chain, GetScene(), side2End_, 10.0 * pixelToScene); |
171 polylineLayer->AddChain(chain, true); | 131 polylineLayer->AddChain(chain, true); |
172 } | 132 } |
173 } | 133 } |
174 | 134 |
175 // arc | 135 // Create the arc |
176 { | 136 { |
177 PolylineSceneLayer::Chain chain; | 137 PolylineSceneLayer::Chain chain; |
178 | 138 |
179 const double ARC_RADIUS_CANVAS_COORD = 30.0; | 139 const double ARC_RADIUS_CANVAS_COORD = 30.0; |
180 AddShortestArc(chain, *GetScene(), side1End_, center_, side2End_, | 140 AddShortestArc(chain, side1End_, center_, side2End_, |
181 ARC_RADIUS_CANVAS_COORD * pixelToScene); | 141 ARC_RADIUS_CANVAS_COORD * pixelToScene); |
182 polylineLayer->AddChain(chain, false); | 142 polylineLayer->AddChain(chain, false); |
183 } | 143 } |
184 } | 144 } |
185 { | 145 { |
186 // Set the text layer | 146 // Set the text layer |
187 | 147 |
188 double p1cAngle = atan2( | 148 double p1cAngle = atan2( |
189 side1End_.GetY() - center_.GetY(), | 149 side1End_.GetY() - center_.GetY(), |
190 side1End_.GetX() - center_.GetX()); | 150 side1End_.GetX() - center_.GetX()); |
191 | 151 |
192 | |
193 double p2cAngle = atan2( | 152 double p2cAngle = atan2( |
194 side2End_.GetY() - center_.GetY(), | 153 side2End_.GetY() - center_.GetY(), |
195 side2End_.GetX() - center_.GetX()); | 154 side2End_.GetX() - center_.GetX()); |
196 | 155 |
197 double delta = NormalizeAngle(p2cAngle - p1cAngle); | 156 double delta = NormalizeAngle(p2cAngle - p1cAngle); |
198 | |
199 | |
200 double theta = p1cAngle + delta / 2; | 157 double theta = p1cAngle + delta / 2; |
201 | 158 |
202 | |
203 const double TEXT_CENTER_DISTANCE_CANVAS_COORD = 90; | 159 const double TEXT_CENTER_DISTANCE_CANVAS_COORD = 90; |
204 | 160 |
205 double offsetX = TEXT_CENTER_DISTANCE_CANVAS_COORD * cos(theta); | 161 double offsetX = TEXT_CENTER_DISTANCE_CANVAS_COORD * cos(theta); |
206 | |
207 double offsetY = TEXT_CENTER_DISTANCE_CANVAS_COORD * sin(theta); | 162 double offsetY = TEXT_CENTER_DISTANCE_CANVAS_COORD * sin(theta); |
208 | 163 |
209 double pointX = center_.GetX() + offsetX * pixelToScene; | 164 double pointX = center_.GetX() + offsetX * pixelToScene; |
210 double pointY = center_.GetY() + offsetY * pixelToScene; | 165 double pointY = center_.GetY() + offsetY * pixelToScene; |
211 | 166 |
214 | 169 |
215 // http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=00B0&mode=hex | 170 // http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=00B0&mode=hex |
216 sprintf(buf, "%0.02f\xc2\xb0", angleDeg); | 171 sprintf(buf, "%0.02f\xc2\xb0", angleDeg); |
217 | 172 |
218 SetTextLayerOutlineProperties( | 173 SetTextLayerOutlineProperties( |
219 *GetScene(), textBaseZIndex_, buf, ScenePoint2D(pointX, pointY)); | 174 GetScene(), layerHolder_, buf, ScenePoint2D(pointX, pointY)); |
220 | 175 |
221 // TODO:make it togglable | 176 // TODO:make it togglable |
222 bool enableInfoDisplay = false; | 177 bool enableInfoDisplay = false; |
223 if (enableInfoDisplay) | 178 if (enableInfoDisplay) |
224 { | 179 { |
265 boost::lexical_cast<std::string>(pointY)); | 220 boost::lexical_cast<std::string>(pointY)); |
266 | 221 |
267 TrackerSample_SetInfoDisplayMessage("angleDeg", | 222 TrackerSample_SetInfoDisplayMessage("angleDeg", |
268 boost::lexical_cast<std::string>(angleDeg)); | 223 boost::lexical_cast<std::string>(angleDeg)); |
269 } | 224 } |
270 | |
271 | |
272 | |
273 } | 225 } |
274 } | 226 } |
275 else | 227 else |
276 { | 228 { |
277 if (layersCreated) | 229 RemoveFromScene(); |
278 { | |
279 RemoveFromScene(); | |
280 layersCreated = false; | |
281 } | |
282 } | 230 } |
283 } | 231 } |
284 } | 232 } |
285 } | 233 } |