comparison Samples/Common/MeasureTools.cpp @ 632:500c3f70b6c2

- Added a ClearAllChains method to PolylineSceneLayer --> revision must change when calling it ==> BumpRevision has been added to base class - Added some docs = Added GetMinDepth + GetMaxDepth to Scene2D (to alleviate the need for app- specific "Z depth registry" : clients may simply add a new layer on top or at the bottom of the existing layer set. - Added the line tracker measurement tools, commands and trackers. Generic base classes + Line measure - started work on the line measure handles
author Benjamin Golinvaux <bgo@osimis.io>
date Thu, 09 May 2019 10:41:31 +0200
parents
children 6a144a45b2d8
comparison
equal deleted inserted replaced
618:0925b27e8750 632:500c3f70b6c2
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2019 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21 #include <Core/Logging.h>
22 #include "MeasureTools.h"
23
24 namespace OrthancStone
25 {
26 void MeasureTool::Enable()
27 {
28 enabled_ = true;
29 RefreshScene();
30 }
31
32 void MeasureTool::Disable()
33 {
34 enabled_ = false;
35 RefreshScene();
36 }
37
38 LineMeasureTool::~LineMeasureTool()
39 {
40 // this measuring tool is a RABI for the corresponding visual layers
41 // stored in the 2D scene
42 Disable();
43 RemoveFromScene();
44 }
45
46 void LineMeasureTool::RemoveFromScene()
47 {
48 if (layersCreated)
49 {
50 assert(GetScene().HasLayer(polylineZIndex_));
51 assert(GetScene().HasLayer(textZIndex_));
52 GetScene().DeleteLayer(polylineZIndex_);
53 GetScene().DeleteLayer(textZIndex_);
54 }
55 }
56
57
58 void LineMeasureTool::SetStart(ScenePoint2D start)
59 {
60 start_ = start;
61 RefreshScene();
62 }
63
64 void LineMeasureTool::SetEnd(ScenePoint2D end)
65 {
66 end_ = end;
67 RefreshScene();
68 }
69
70 void LineMeasureTool::Set(ScenePoint2D start, ScenePoint2D end)
71 {
72 start_ = start;
73 end_ = end;
74 RefreshScene();
75 }
76
77 PolylineSceneLayer* LineMeasureTool::GetPolylineLayer()
78 {
79 assert(GetScene().HasLayer(polylineZIndex_));
80 ISceneLayer* layer = &(GetScene().GetLayer(polylineZIndex_));
81 PolylineSceneLayer* concreteLayer = dynamic_cast<PolylineSceneLayer*>(layer);
82 assert(concreteLayer != NULL);
83 return concreteLayer;
84 }
85
86 TextSceneLayer* LineMeasureTool::GetTextLayer()
87 {
88 assert(GetScene().HasLayer(textZIndex_));
89 ISceneLayer* layer = &(GetScene().GetLayer(textZIndex_));
90 TextSceneLayer* concreteLayer = dynamic_cast<TextSceneLayer*>(layer);
91 assert(concreteLayer != NULL);
92 return concreteLayer;
93 }
94
95 void LineMeasureTool::RefreshScene()
96 {
97 if (IsEnabled())
98 {
99 if (!layersCreated)
100 {
101 // Create the layers if need be
102
103 assert(textZIndex_ == -1);
104 {
105 polylineZIndex_ = GetScene().GetMaxDepth() + 100;
106 LOG(INFO) << "set polylineZIndex_ to: " << polylineZIndex_;
107 std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer());
108 GetScene().SetLayer(polylineZIndex_, layer.release());
109 }
110 {
111 textZIndex_ = GetScene().GetMaxDepth() + 100;
112 LOG(INFO) << "set textZIndex_ to: " << textZIndex_;
113 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer());
114 GetScene().SetLayer(textZIndex_, layer.release());
115 }
116 layersCreated = true;
117 }
118 else
119 {
120 assert(GetScene().HasLayer(polylineZIndex_));
121 assert(GetScene().HasLayer(textZIndex_));
122 }
123 {
124 // Fill the polyline layer with the measurement line
125
126 PolylineSceneLayer* polylineLayer = GetPolylineLayer();
127 polylineLayer->ClearAllChains();
128 polylineLayer->SetColor(0, 223, 21);
129
130 {
131 PolylineSceneLayer::Chain chain;
132 chain.push_back(start_);
133 chain.push_back(end_);
134 polylineLayer->AddChain(chain, false);
135 }
136
137 // handles
138 {
139 auto startC = start_.Apply(GetScene().GetSceneToCanvasTransform());
140 auto squareSize = 10; //TODO: take DPI into account
141 auto startHandleLX = startC.GetX() - squareSize/2;
142 auto startHandleTY = startC.GetY() - squareSize / 2;
143 auto startHandleRX = startC.GetX() + squareSize / 2;
144 auto startHandleBY = startC.GetY() + squareSize / 2;
145 auto startLTC = ScenePoint2D(startHandleLX, startHandleTY);
146 auto startRTC = ScenePoint2D(startHandleRX, startHandleTY);
147 auto startRBC = ScenePoint2D(startHandleRX, startHandleBY);
148 auto startLBC = ScenePoint2D(startHandleLX, startHandleBY);
149
150 auto startLT = startLTC.Apply(GetScene().GetCanvasToSceneTransform());
151 auto startRT = startRTC.Apply(GetScene().GetCanvasToSceneTransform());
152 auto startRB = startRBC.Apply(GetScene().GetCanvasToSceneTransform());
153 auto startLB = startLBC.Apply(GetScene().GetCanvasToSceneTransform());
154
155 PolylineSceneLayer::Chain chain;
156 chain.push_back(startLT);
157 chain.push_back(startRT);
158 chain.push_back(startRB);
159 chain.push_back(startLB);
160 polylineLayer->AddChain(chain, true);
161 }
162
163
164
165 }
166 {
167 // Set the text layer proporeties
168
169 TextSceneLayer* textLayer = GetTextLayer();
170 double deltaX = end_.GetX() - start_.GetX();
171 double deltaY = end_.GetY() - start_.GetY();
172 double squareDist = deltaX * deltaX + deltaY * deltaY;
173 double dist = sqrt(squareDist);
174 char buf[64];
175 sprintf(buf, "%0.02f units", dist);
176 textLayer->SetText(buf);
177 textLayer->SetColor(0, 223, 21);
178
179 // TODO: for now we simply position the text overlay at the middle
180 // of the measuring segment
181 double midX = 0.5*(end_.GetX() + start_.GetX());
182 double midY = 0.5*(end_.GetY() + start_.GetY());
183 textLayer->SetPosition(midX, midY);
184 }
185 }
186 else
187 {
188 if (layersCreated)
189 {
190 RemoveFromScene();
191 layersCreated = false;
192 }
193 }
194 }
195 }
196