Mercurial > hg > orthanc-stone
comparison Framework/Widgets/LayerWidget.cpp @ 97:d18dcc963930 wasm
separation of the renderers vs. viewport slice
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 30 May 2017 14:09:11 +0200 |
parents | f8bce1bebe01 |
children | efd9ef2b67f1 |
comparison
equal
deleted
inserted
replaced
96:f8bce1bebe01 | 97:d18dcc963930 |
---|---|
103 { | 103 { |
104 return countMissing_; | 104 return countMissing_; |
105 } | 105 } |
106 | 106 |
107 bool RenderScene(CairoContext& context, | 107 bool RenderScene(CairoContext& context, |
108 const ViewportGeometry& view) | 108 const ViewportGeometry& view, |
109 const SliceGeometry& viewportSlice) | |
109 { | 110 { |
110 bool fullQuality = true; | 111 bool fullQuality = true; |
112 cairo_t *cr = context.GetObject(); | |
111 | 113 |
112 for (size_t i = 0; i < renderers_.size(); i++) | 114 for (size_t i = 0; i < renderers_.size(); i++) |
113 { | 115 { |
114 if (renderers_[i] != NULL && | 116 if (renderers_[i] != NULL) |
115 !renderers_[i]->RenderLayer(context, view, slice_)) | |
116 { | 117 { |
117 return false; | 118 const SliceGeometry& frameSlice = renderers_[i]->GetLayerSlice(); |
119 | |
120 double x0, y0, x1, y1, x2, y2; | |
121 viewportSlice.ProjectPoint(x0, y0, frameSlice.GetOrigin()); | |
122 viewportSlice.ProjectPoint(x1, y1, frameSlice.GetOrigin() + frameSlice.GetAxisX()); | |
123 viewportSlice.ProjectPoint(x2, y2, frameSlice.GetOrigin() + frameSlice.GetAxisY()); | |
124 | |
125 /** | |
126 * Now we solve the system of linear equations Ax + b = x', given: | |
127 * A [0 ; 0] + b = [x0 ; y0] | |
128 * A [1 ; 0] + b = [x1 ; y1] | |
129 * A [0 ; 1] + b = [x2 ; y2] | |
130 * <=> | |
131 * b = [x0 ; y0] | |
132 * A [1 ; 0] = [x1 ; y1] - b = [x1 - x0 ; y1 - y0] | |
133 * A [0 ; 1] = [x2 ; y2] - b = [x2 - x0 ; y2 - y0] | |
134 * <=> | |
135 * b = [x0 ; y0] | |
136 * [a11 ; a21] = [x1 - x0 ; y1 - y0] | |
137 * [a12 ; a22] = [x2 - x0 ; y2 - y0] | |
138 **/ | |
139 | |
140 cairo_matrix_t transform; | |
141 cairo_matrix_init(&transform, x1 - x0, y1 - y0, x2 - x0, y2 - y0, x0, y0); | |
142 | |
143 cairo_save(cr); | |
144 cairo_transform(cr, &transform); | |
145 | |
146 if (!renderers_[i]->RenderLayer(context, view)) | |
147 { | |
148 cairo_restore(cr); | |
149 return false; | |
150 } | |
151 | |
152 cairo_restore(cr); | |
118 } | 153 } |
119 | 154 |
120 if (renderers_[i] != NULL && | 155 if (renderers_[i] != NULL && |
121 !renderers_[i]->IsFullQuality()) | 156 !renderers_[i]->IsFullQuality()) |
122 { | 157 { |
127 if (!fullQuality) | 162 if (!fullQuality) |
128 { | 163 { |
129 double x, y; | 164 double x, y; |
130 view.MapDisplayToScene(x, y, static_cast<double>(view.GetDisplayWidth()) / 2.0, 10); | 165 view.MapDisplayToScene(x, y, static_cast<double>(view.GetDisplayWidth()) / 2.0, 10); |
131 | 166 |
132 cairo_t *cr = context.GetObject(); | |
133 cairo_translate(cr, x, y); | 167 cairo_translate(cr, x, y); |
134 | 168 |
135 #if 1 | 169 #if 1 |
136 double s = 5.0 / view.GetZoom(); | 170 double s = 5.0 / view.GetZoom(); |
137 cairo_rectangle(cr, -s, -s, 2.0 * s, 2.0 * s); | 171 cairo_rectangle(cr, -s, -s, 2.0 * s, 2.0 * s); |
178 return true; | 212 return true; |
179 } | 213 } |
180 } | 214 } |
181 | 215 |
182 | 216 |
183 bool LayerWidget::GetAndFixExtent(double& x1, | 217 void LayerWidget::GetLayerExtent(Extent& extent, |
184 double& y1, | 218 ILayerSource& source) const |
185 double& x2, | 219 { |
186 double& y2, | 220 extent.Reset(); |
187 ILayerSource& source) const | 221 |
188 { | 222 std::vector<Vector> points; |
189 if (source.GetExtent(x1, y1, x2, y2, slice_)) | 223 if (source.GetExtent(points, slice_)) |
190 { | 224 { |
191 if (x1 > x2) | 225 for (size_t i = 0; i < points.size(); i++) |
192 { | 226 { |
193 std::swap(x1, x2); | 227 double x, y; |
194 } | 228 slice_.ProjectPoint(x, y, points[i]); |
195 | 229 extent.AddPoint(x, y); |
196 if (y1 > y2) | 230 } |
197 { | |
198 std::swap(y1, y2); | |
199 } | |
200 | |
201 return true; | |
202 } | |
203 else | |
204 { | |
205 return false; | |
206 } | 231 } |
207 } | 232 } |
208 | 233 |
209 | 234 |
210 void LayerWidget::GetSceneExtent(double& x1, | 235 void LayerWidget::GetSceneExtent(double& x1, |
211 double& y1, | 236 double& y1, |
212 double& x2, | 237 double& x2, |
213 double& y2) | 238 double& y2) |
214 { | 239 { |
215 bool first = true; | 240 Extent sceneExtent; |
216 | 241 |
217 for (size_t i = 0; i < layers_.size(); i++) | 242 for (size_t i = 0; i < layers_.size(); i++) |
218 { | 243 { |
219 double ax, ay, bx, by; | 244 double ax, ay, bx, by; |
220 | 245 |
221 assert(layers_[i] != NULL); | 246 assert(layers_[i] != NULL); |
222 if (GetAndFixExtent(ax, ay, bx, by, *layers_[i])) | 247 Extent layerExtent; |
223 { | 248 GetLayerExtent(layerExtent, *layers_[i]); |
224 LOG(INFO) << "Extent of layer " << i << ": (" << ax << "," << ay | 249 |
225 << ")->(" << bx << "," << by << ")"; | 250 sceneExtent.Union(layerExtent); |
226 | 251 } |
227 if (first) | 252 |
228 { | 253 if (sceneExtent.IsEmpty()) |
229 x1 = ax; | |
230 y1 = ay; | |
231 x2 = bx; | |
232 y2 = by; | |
233 first = false; | |
234 } | |
235 else | |
236 { | |
237 x1 = std::min(x1, ax); | |
238 y1 = std::min(y1, ay); | |
239 x2 = std::max(x2, bx); | |
240 y2 = std::max(y2, by); | |
241 } | |
242 } | |
243 } | |
244 | |
245 if (first) | |
246 { | 254 { |
247 // Set a default extent of (-1,-1) -> (0,0) | 255 // Set a default extent of (-1,-1) -> (0,0) |
248 x1 = -1; | 256 x1 = -1; |
249 y1 = -1; | 257 y1 = -1; |
250 x2 = 1; | 258 x2 = 1; |
251 y2 = 1; | 259 y2 = 1; |
252 } | 260 } |
253 | 261 else |
254 // Ensure the extent is non-empty | 262 { |
255 if (x1 >= x2) | 263 x1 = sceneExtent.GetX1(); |
256 { | 264 y1 = sceneExtent.GetY1(); |
257 double tmp = x1; | 265 x2 = sceneExtent.GetX2(); |
258 x1 = tmp - 0.5; | 266 y2 = sceneExtent.GetY2(); |
259 x2 = tmp + 0.5; | 267 |
260 } | 268 // Ensure the extent is non-empty |
261 | 269 if (x1 >= x2) |
262 if (y1 >= y2) | 270 { |
263 { | 271 double tmp = x1; |
264 double tmp = y1; | 272 x1 = tmp - 0.5; |
265 y1 = tmp - 0.5; | 273 x2 = tmp + 0.5; |
266 y2 = tmp + 0.5; | 274 } |
275 | |
276 if (y1 >= y2) | |
277 { | |
278 double tmp = y1; | |
279 y1 = tmp - 0.5; | |
280 y2 = tmp + 0.5; | |
281 } | |
267 } | 282 } |
268 } | 283 } |
269 | 284 |
270 | 285 |
271 bool LayerWidget::RenderScene(CairoContext& context, | 286 bool LayerWidget::RenderScene(CairoContext& context, |
272 const ViewportGeometry& view) | 287 const ViewportGeometry& view) |
273 { | 288 { |
274 if (currentScene_.get() != NULL) | 289 if (currentScene_.get() != NULL) |
275 { | 290 { |
276 return currentScene_->RenderScene(context, view); | 291 return currentScene_->RenderScene(context, view, slice_); |
277 } | 292 } |
278 else | 293 else |
279 { | 294 { |
280 return true; | 295 return true; |
281 } | 296 } |
397 << "," << slice.GetOrigin()[1] | 412 << "," << slice.GetOrigin()[1] |
398 << "," << slice.GetOrigin()[2] << ")"; | 413 << "," << slice.GetOrigin()[2] << ")"; |
399 | 414 |
400 Slice displayedSlice(slice_, THIN_SLICE_THICKNESS); | 415 Slice displayedSlice(slice_, THIN_SLICE_THICKNESS); |
401 | 416 |
402 if (!displayedSlice.ContainsPlane(slice)) | 417 //if (!displayedSlice.ContainsPlane(slice)) |
403 { | 418 { |
404 if (currentScene_.get() == NULL || | 419 if (currentScene_.get() == NULL || |
405 (pendingScene_.get() != NULL && | 420 (pendingScene_.get() != NULL && |
406 pendingScene_->IsComplete())) | 421 pendingScene_->IsComplete())) |
407 { | 422 { |