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 }