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 {