Mercurial > hg > orthanc-stone
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 |