comparison src/graphics.h.in @ 11175:c0a95a5c6d25

Address the speed of plotting large hggroup groups and in particular contours (bug #31305). Changes to address this include - Use __go_patch__ in __contour__ rather than patch so that the cost of setting up the callback functions is avoided. The contourgroup callback handles the updating of properties. - Add children_property class to store children in a list so that adding and deleting children is a low cost operation. - Create a new version of update_axis_limits code that doesn't force the recalculation of all of the objects children. Patch also allows unclosed patch contours with the FLTK backend.
author David Bateman <dbateman@free.fr>
date Tue, 02 Nov 2010 00:47:31 +0100
parents 51ac3a08e53c
children 29b1f7d68665
comparison
equal deleted inserted replaced
11174:2114867f2a50 11175:c0a95a5c6d25
1366 octave_value data; 1366 octave_value data;
1367 }; 1367 };
1368 1368
1369 // --------------------------------------------------------------------- 1369 // ---------------------------------------------------------------------
1370 1370
1371 class children_property : public base_property
1372 {
1373 public:
1374 children_property (void)
1375 : base_property ("", graphics_handle ())
1376 {
1377 do_init_children (Matrix ());
1378 }
1379
1380 children_property (const std::string& nm, const graphics_handle& h,
1381 const Matrix &val)
1382 : base_property (nm, h)
1383 {
1384 do_init_children (val);
1385 }
1386
1387 children_property (const children_property& p)
1388 : base_property (p)
1389 {
1390 do_init_children (p.children_list);
1391 }
1392
1393 children_property& operator = (const octave_value& val)
1394 {
1395 set (val);
1396 return *this;
1397 }
1398
1399 base_property* clone (void) const { return new children_property (*this); }
1400
1401 bool remove_child (const double &val)
1402 {
1403 return do_remove_child (val);
1404 }
1405
1406 void adopt (const double &val)
1407 {
1408 do_adopt_child (val);
1409 }
1410
1411 Matrix get_children (void) const
1412 {
1413 return do_get_children (false);
1414 }
1415
1416 Matrix get_hidden (void) const
1417 {
1418 return do_get_children (true);
1419 }
1420
1421 Matrix get_all (void) const
1422 {
1423 return do_get_all_children ();
1424 }
1425
1426 octave_value get (void) const
1427 {
1428 return octave_value (get_children ());
1429 }
1430
1431 void delete_children (bool clear = false)
1432 {
1433 do_delete_children (clear);
1434 }
1435
1436 private:
1437 typedef std::list<double>::iterator children_list_iterator;
1438 typedef std::list<double>::const_iterator const_children_list_iterator;
1439 std::list<double> children_list;
1440
1441 protected:
1442 bool do_set (const octave_value& val)
1443 {
1444 const Matrix new_kids = val.matrix_value ();
1445
1446 octave_idx_type nel = new_kids.numel ();
1447
1448 const Matrix new_kids_column = new_kids.reshape (dim_vector (nel, 1));
1449
1450 bool is_ok = true;
1451
1452 if (! error_state)
1453 {
1454 const Matrix visible_kids = do_get_children (false);
1455
1456 if (visible_kids.numel () == new_kids.numel ())
1457 {
1458 Matrix t1 = visible_kids.sort ();
1459 Matrix t2 = new_kids_column.sort ();
1460
1461 if (t1 != t2)
1462 is_ok = false;
1463 }
1464 else
1465 is_ok = false;
1466
1467 if (! is_ok)
1468 error ("set: new children must be a permutation of existing children");
1469 }
1470 else
1471 {
1472 is_ok = false;
1473 error ("set: expecting children to be array of graphics handles");
1474 }
1475
1476 if (is_ok)
1477 {
1478 children_list.clear ();
1479 do_init_children (new_kids_column.stack (get_hidden ()));
1480 }
1481
1482 return is_ok;
1483 }
1484
1485 private:
1486 void do_init_children (const Matrix &val)
1487 {
1488 children_list.clear ();
1489 for (octave_idx_type i = 0; i < val.numel (); i++)
1490 children_list.push_front (val.xelem (i));
1491 }
1492
1493 void do_init_children (const std::list<double> &val)
1494 {
1495 children_list.clear ();
1496 for (const_children_list_iterator p = val.begin (); p != val.end (); p++)
1497 children_list.push_front (*p);
1498 }
1499
1500 Matrix do_get_children (bool return_hidden) const;
1501
1502 Matrix do_get_all_children (void) const
1503 {
1504 Matrix retval (children_list.size (), 1);
1505 octave_idx_type i = 0;
1506
1507 for (const_children_list_iterator p = children_list.begin ();
1508 p != children_list.end (); p++)
1509 retval(i++) = *p;
1510 return retval;
1511 }
1512
1513 bool do_remove_child (double child)
1514 {
1515 for (children_list_iterator p = children_list.begin ();
1516 p != children_list.end (); p++)
1517 {
1518 if (*p == child)
1519 {
1520 children_list.erase (p);
1521 return true;
1522 }
1523 }
1524 return false;
1525 }
1526
1527 void do_adopt_child (const double &val)
1528 {
1529 children_list.push_front (val);
1530 }
1531
1532 void do_delete_children (bool clear);
1533 };
1534
1535
1536
1537 // ---------------------------------------------------------------------
1538
1371 class callback_property : public base_property 1539 class callback_property : public base_property
1372 { 1540 {
1373 public: 1541 public:
1374 callback_property (const std::string& nm, const graphics_handle& h, 1542 callback_property (const std::string& nm, const graphics_handle& h,
1375 const octave_value& m) 1543 const octave_value& m)
1846 return false; 2014 return false;
1847 } 2015 }
1848 2016
1849 bool is_modified (void) const { return is___modified__ (); } 2017 bool is_modified (void) const { return is___modified__ (); }
1850 2018
1851 virtual void remove_child (const graphics_handle& h); 2019 virtual void remove_child (const graphics_handle& h)
2020 {
2021 if (children.remove_child (h.value ()))
2022 mark_modified ();
2023 }
1852 2024
1853 virtual void adopt (const graphics_handle& h) 2025 virtual void adopt (const graphics_handle& h)
1854 { 2026 {
1855 octave_idx_type n = children.numel (); 2027 children.adopt (h.value ());
1856 children.resize (n+1, 1);
1857 for (octave_idx_type i = n; i > 0; i--)
1858 children(i) = children(i-1);
1859 children(0) = h.value ();
1860 mark_modified (); 2028 mark_modified ();
1861 } 2029 }
1862 2030
1863 virtual graphics_backend get_backend (void) const; 2031 virtual graphics_backend get_backend (void) const;
1864 2032
1875 2043
1876 void set_tag (const octave_value& val) { tag = val; } 2044 void set_tag (const octave_value& val) { tag = val; }
1877 2045
1878 void set_parent (const octave_value& val); 2046 void set_parent (const octave_value& val);
1879 2047
1880 Matrix get_all_children (void) const { return children; } 2048 Matrix get_children (void) const
1881 2049 {
1882 Matrix get_hidden_children (void) const; 2050 return children.get_children ();
1883 2051 }
1884 void set_children (const octave_value& val); 2052
2053 Matrix get_all_children (void) const
2054 {
2055 return children.get_all ();
2056 }
2057
2058 Matrix get_hidden_children (void) const
2059 {
2060 return children.get_hidden ();
2061 }
1885 2062
1886 void set_modified (const octave_value& val) { set___modified__ (val); } 2063 void set_modified (const octave_value& val) { set___modified__ (val); }
1887 2064
1888 void set___modified__ (const octave_value& val) { __modified__ = val; } 2065 void set___modified__ (const octave_value& val) { __modified__ = val; }
1889 2066
1892 // Update data limits for AXIS_TYPE (xdata, ydata, etc.) in the parent 2069 // Update data limits for AXIS_TYPE (xdata, ydata, etc.) in the parent
1893 // axes object. 2070 // axes object.
1894 2071
1895 virtual void update_axis_limits (const std::string& axis_type) const; 2072 virtual void update_axis_limits (const std::string& axis_type) const;
1896 2073
1897 virtual void delete_children (void); 2074 virtual void update_axis_limits (const std::string& axis_type,
1898 2075 const graphics_handle& h) const;
2076
2077 virtual void delete_children (bool clear = false)
2078 {
2079 children.delete_children (clear);
2080 }
2081
1899 static property_list::pval_map_type factory_defaults (void); 2082 static property_list::pval_map_type factory_defaults (void);
1900 2083
1901 // FIXME -- these functions should be generated automatically by the 2084 // FIXME -- these functions should be generated automatically by the
1902 // genprops.awk script. 2085 // genprops.awk script.
1903 // 2086 //
1938 BEGIN_BASE_PROPERTIES 2121 BEGIN_BASE_PROPERTIES
1939 // properties common to all objects 2122 // properties common to all objects
1940 bool_property beingdeleted , "off" 2123 bool_property beingdeleted , "off"
1941 radio_property busyaction , "{queue}|cancel" 2124 radio_property busyaction , "{queue}|cancel"
1942 callback_property buttondownfcn , Matrix () 2125 callback_property buttondownfcn , Matrix ()
1943 // FIXME -- use a property class for children. 2126 children_property children gf , Matrix ()
1944 Matrix children Gfs , Matrix ()
1945 bool_property clipping , "on" 2127 bool_property clipping , "on"
1946 callback_property createfcn , Matrix () 2128 callback_property createfcn , Matrix ()
1947 callback_property deletefcn , Matrix () 2129 callback_property deletefcn , Matrix ()
1948 radio_property handlevisibility , "{on}|callback|off" 2130 radio_property handlevisibility , "{on}|callback|off"
1949 bool_property hittest , "on" 2131 bool_property hittest , "on"
1981 protected: 2163 protected:
1982 void insert_static_property (const std::string& name, base_property& p) 2164 void insert_static_property (const std::string& name, base_property& p)
1983 { insert_property (name, property (&p, true)); } 2165 { insert_property (name, property (&p, true)); }
1984 2166
1985 virtual void init (void) { } 2167 virtual void init (void) { }
1986
1987 private:
1988 Matrix get_children_internal (bool return_hidden) const;
1989 }; 2168 };
1990 2169
1991 class OCTINTERP_API base_graphics_object 2170 class OCTINTERP_API base_graphics_object
1992 { 2171 {
1993 public: 2172 public:
2149 return properties; 2328 return properties;
2150 } 2329 }
2151 2330
2152 virtual void update_axis_limits (const std::string& axis_type); 2331 virtual void update_axis_limits (const std::string& axis_type);
2153 2332
2333 virtual void update_axis_limits (const std::string& axis_type,
2334 const graphics_handle& h);
2335
2154 virtual bool valid_object (void) const { return false; } 2336 virtual bool valid_object (void) const { return false; }
2155 2337
2156 virtual std::string type (void) const 2338 virtual std::string type (void) const
2157 { 2339 {
2158 return (valid_object () ? get_properties ().graphics_object_name () 2340 return (valid_object () ? get_properties ().graphics_object_name ()
2332 } 2514 }
2333 2515
2334 void update_axis_limits (const std::string& axis_type) 2516 void update_axis_limits (const std::string& axis_type)
2335 { 2517 {
2336 rep->update_axis_limits (axis_type); 2518 rep->update_axis_limits (axis_type);
2519 }
2520
2521 void update_axis_limits (const std::string& axis_type,
2522 const graphics_handle& h)
2523 {
2524 rep->update_axis_limits (axis_type, h);
2337 } 2525 }
2338 2526
2339 bool valid_object (void) const { return rep->valid_object (); } 2527 bool valid_object (void) const { return rep->valid_object (); }
2340 2528
2341 std::string type (void) const { return rep->type (); } 2529 std::string type (void) const { return rep->type (); }
3193 3381
3194 const base_properties& get_properties (void) const { return xproperties; } 3382 const base_properties& get_properties (void) const { return xproperties; }
3195 3383
3196 void update_axis_limits (const std::string& axis_type); 3384 void update_axis_limits (const std::string& axis_type);
3197 3385
3386 void update_axis_limits (const std::string& axis_type,
3387 const graphics_handle& h);
3388
3198 bool valid_object (void) const { return true; } 3389 bool valid_object (void) const { return true; }
3199 3390
3200 void reset_default_properties (void); 3391 void reset_default_properties (void);
3201 3392
3202 private: 3393 private:
3798 update_limits (); 3989 update_limits ();
3799 } 3990 }
3800 3991
3801 void adopt (const graphics_handle& h) 3992 void adopt (const graphics_handle& h)
3802 { 3993 {
3994
3803 base_properties::adopt (h); 3995 base_properties::adopt (h);
3804 update_limits (); 3996 update_limits (h);
3805 } 3997 }
3806 3998
3807 // See the genprops.awk script for an explanation of the 3999 // See the genprops.awk script for an explanation of the
3808 // properties declarations. 4000 // properties declarations.
3809 4001
3820 bool_property climinclude h , "on" 4012 bool_property climinclude h , "on"
3821 bool_property aliminclude h , "on" 4013 bool_property aliminclude h , "on"
3822 END_PROPERTIES 4014 END_PROPERTIES
3823 4015
3824 private: 4016 private:
3825 void update_limits (void) 4017 void update_limits (void) const;
3826 { 4018
3827 update_axis_limits ("xlim"); 4019 void update_limits (const graphics_handle& h) const;
3828 update_axis_limits ("ylim");
3829 update_axis_limits ("zlim");
3830 update_axis_limits ("clim");
3831 update_axis_limits ("alim");
3832 }
3833 4020
3834 protected: 4021 protected:
3835 void init (void) 4022 void init (void)
3836 { } 4023 { }
4024
3837 }; 4025 };
3838 4026
3839 private: 4027 private:
3840 properties xproperties; 4028 properties xproperties;
3841 4029
3851 base_properties& get_properties (void) { return xproperties; } 4039 base_properties& get_properties (void) { return xproperties; }
3852 4040
3853 const base_properties& get_properties (void) const { return xproperties; } 4041 const base_properties& get_properties (void) const { return xproperties; }
3854 4042
3855 bool valid_object (void) const { return true; } 4043 bool valid_object (void) const { return true; }
3856 4044
3857 void update_axis_limits (const std::string& axis_type); 4045 void update_axis_limits (const std::string& axis_type);
4046
4047 void update_axis_limits (const std::string& axis_type,
4048 const graphics_handle& h);
4049
3858 }; 4050 };
3859 4051
3860 // --------------------------------------------------------------------- 4052 // ---------------------------------------------------------------------
3861 4053
3862 class OCTINTERP_API uimenu : public base_graphics_object 4054 class OCTINTERP_API uimenu : public base_graphics_object