comparison src/graphics.cc @ 7829:8ca8e97e8c0a

Add rendering interface for surface object (no implementation yet). * * * Add surface properties. * * * Add cdata -> RGB color conversion function. Use it in surface objects. * * * Add normals automatic computation to surface objects. * * * Make sure the correct "get" method is called. * * * Extend scaler interface to accept NDArray. * * * Surface rendering (1st part). * * * Fix wrong indexing. * * * Fix bug in xget_ancestor argument declaration. * * * Initialize OpenGL context correctly. Fix bug in surface rendering. * * * Set material color when rendering surface facets. * * * Add rendering of surface mesh and markers.
author Michael Goffioul <michael.goffioul@gmail.com>
date Thu, 14 Feb 2008 12:17:44 +0100
parents 4739b6a1925c
children 8ff92634982d
comparison
equal deleted inserted replaced
7828:4739b6a1925c 7829:8ca8e97e8c0a
329 } 329 }
330 } 330 }
331 } 331 }
332 332
333 return retval; 333 return retval;
334 }
335
336 static graphics_object
337 xget_ancestor (graphics_object go, const std::string& type)
338 {
339 do
340 {
341 if (go.valid_object ())
342 {
343 if (go.isa (type))
344 return go;
345 else
346 go = gh_manager::get_object (go.get_parent ());
347 }
348 else
349 return graphics_object ();
350 } while (true);
351 }
352
353 static octave_value
354 convert_cdata (const base_properties& props, const octave_value& cdata,
355 bool is_scaled, int cdim)
356 {
357 dim_vector dv (cdata.dims ());
358
359 if (dv.length () == cdim && dv(cdim-1) == 3)
360 return cdata;
361
362 Matrix cmap (1, 3, 0.0);
363 Matrix clim (1, 2, 0.0);
364
365 graphics_object go = gh_manager::get_object (props.get___myhandle__ ());
366 graphics_object fig = xget_ancestor (go, "figure");
367
368 if (fig.valid_object ())
369 {
370 Matrix _cmap = fig.get (caseless_str ("colormap")).matrix_value ();
371
372 if (! error_state)
373 cmap = _cmap;
374 }
375
376 if (is_scaled)
377 {
378 graphics_object ax = xget_ancestor (go, "axes");
379
380 if (ax.valid_object ())
381 {
382 Matrix _clim = ax.get (caseless_str ("clim")).matrix_value ();
383
384 if (! error_state)
385 clim = _clim;
386 }
387 }
388
389 dv.resize (cdim);
390 dv(cdim-1) = 3;
391
392 NDArray a (dv);
393
394 int lda = static_cast<int> (a.numel () / 3);
395 int nc = cmap.rows ();
396
397 double *av = a.fortran_vec ();
398 const double *cmapv = cmap.data ();
399 const double *cv = 0;
400 const octave_uint8 *icv = 0;
401
402 if (cdata.is_integer_type ())
403 icv = cdata.uint8_array_value ().data ();
404 else
405 cv = cdata.array_value ().data ();
406
407 for (int i = 0; i < lda; i++)
408 {
409 double x = (cv ? cv[i] : double (icv[i]));
410
411 if (is_scaled)
412 x = xround ((nc - 1) * (x - clim(0)) / (clim(1) - clim(0)));
413 else
414 x = xround (x - 1);
415
416 if (x < 0)
417 x = 0;
418 else if (x >= nc)
419 x = (nc - 1);
420
421 int idx = static_cast<int> (x);
422
423 av[i] = cmapv[idx];
424 av[i+lda] = cmapv[idx+nc];
425 av[i+2*lda] = cmapv[idx+2*nc];
426 }
427
428 return octave_value (a);
334 } 429 }
335 430
336 // --------------------------------------------------------------------- 431 // ---------------------------------------------------------------------
337 432
338 radio_values::radio_values (const std::string& opt_string) 433 radio_values::radio_values (const std::string& opt_string)
2658 2753
2659 // Note: "patch" code is entirely auto-generated 2754 // Note: "patch" code is entirely auto-generated
2660 2755
2661 // --------------------------------------------------------------------- 2756 // ---------------------------------------------------------------------
2662 2757
2663 // Note: "surface" code is entirely auto-generated 2758 octave_value
2759 surface::properties::get_color_data (void) const
2760 {
2761 return convert_cdata (*this, get_cdata (), cdatamapping_is ("scaled"), 3);
2762 }
2763
2764 inline void
2765 cross_product (double x1, double y1, double z1,
2766 double x2, double y2, double z2,
2767 double& x, double& y, double& z)
2768 {
2769 x += (y1 * z2 - z1 * y2);
2770 y += (z1 * x2 - x1 * z2);
2771 z += (x1 * y2 - y1 * x2);
2772 }
2773
2774 void
2775 surface::properties::update_normals (void)
2776 {
2777 if (normalmode_is ("auto"))
2778 {
2779 Matrix x = get_xdata ().matrix_value ();
2780 Matrix y = get_ydata ().matrix_value ();
2781 Matrix z = get_zdata ().matrix_value ();
2782
2783 int p = z.columns (), q = z.rows ();
2784 int i1, i2, i3;
2785 int j1, j2, j3;
2786
2787 bool x_mat = (x.rows () == q);
2788 bool y_mat = (y.columns () == p);
2789
2790 NDArray n (dim_vector (q, p, 3), 0.0);
2791
2792 i1 = i2 = i3 = 0;
2793 j1 = j2 = j3 = 0;
2794
2795 // FIXME: normal computation at boundaries
2796 for (int i = 1; i < (p-1); i++)
2797 {
2798 if (y_mat)
2799 {
2800 i1 = i-1;
2801 i2 = i;
2802 i3 = i+1;
2803 }
2804
2805 for (int j = 1; j < (q-1); j++)
2806 {
2807 if (x_mat)
2808 {
2809 j1 = j-1;
2810 j2 = j;
2811 j3 = j+1;
2812 }
2813
2814 double& nx = n(j, i, 0);
2815 double& ny = n(j, i, 1);
2816 double& nz = n(j, i, 2);
2817
2818 cross_product (x(j3,i)-x(j2,i), y(j+1,i2)-y(j,i2), z(j+1,i)-z(j,i),
2819 x(j2,i+1)-x(j2,i), y(j,i3)-y(j,i2), z(j,i+1)-z(i,j),
2820 nx, ny, nz);
2821 cross_product (x(j2,i-1)-x(j2,i), y(j,i1)-y(j,i2), z(j,i-1)-z(j,i),
2822 x(j3,i)-x(j2,i), y(j+1,i2)-y(j,i2), z(j+1,i)-z(i,j),
2823 nx, ny, nz);
2824 cross_product (x(j1,i)-x(j2,i), y(j-1,i2)-y(j,i2), z(j-1,i)-z(j,i),
2825 x(j2,i-1)-x(j2,i), y(j,i1)-y(j,i2), z(j,i-1)-z(i,j),
2826 nx, ny, nz);
2827 cross_product (x(j2,i+1)-x(j2,i), y(j,i3)-y(j,i2), z(j,i+1)-z(j,i),
2828 x(j1,i)-x(j2,i), y(j-1,i2)-y(j,i2), z(j-1,i)-z(i,j),
2829 nx, ny, nz);
2830
2831 double d = - sqrt (nx*nx + ny*ny + nz*nz);
2832
2833 nx /= d;
2834 ny /= d;
2835 nz /= d;
2836 }
2837 }
2838
2839 vertexnormals = n;
2840 }
2841 }
2664 2842
2665 // --------------------------------------------------------------------- 2843 // ---------------------------------------------------------------------
2666 2844
2667 octave_value 2845 octave_value
2668 base_graphics_object::get_default (const caseless_str& name) const 2846 base_graphics_object::get_default (const caseless_str& name) const