# HG changeset patch # User Michael Goffioul # Date 1203597904 -3600 # Node ID 4fb2db9c87dd83dc77f621636f8a287060a340a7 # Parent ca8b97bb952cb49c70cfd4f4479bf66eb1ec8c22 Turn cdata properties into array_property. Add min/max computation to array_property. diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -19,6 +19,32 @@ 2008-06-04 Michael Goffioul + * graphics.h.in (array_property::array_property(void)): New default + constructor. + (array_property::xmin, array_property:xmax, array_property::xminp, + array_property::min_val, array_property::max_val, + array_property::min_pos): New fields and accessors to hold min/max + values of the array data. + (array_property::get_data_limits): New method to compute min/max + values of the array data. + (base_properties::get_cdata_property, + graphics_object::get_cdata_property): Return array_property. + (image::properties::cdata, surface::properties::cdata, + patch::properties::cdata, patch::properties::facevertexcdata): Turn + into array_property type. + (image::properties::init, surface::properties::init, + patch::properties::init): Add constraint initialization for cdata and + facevertexcdata (patch only). + * genprops.awk (emit_get_array): New function to emit accessor for + array_property. + (emit_declarations): Use it. + * graphics.cc (get_array_limits): New template function to compute + min/max values of an Array object. + (array_property::get_data_limits): New method to compute min/max + values of the array data, using get_array_limits. + (check_limit_vals): Overridden function with array_property. + (axes::update_axis_limits): Turn cdata property into array_property. + * graphics.h.in (patch::properties::get_color_data): New utility function to retrieve actual color data. * graphics.cc (patch::properties::get_color_data): Likewise. diff --git a/src/genprops.awk b/src/genprops.awk --- a/src/genprops.awk +++ b/src/genprops.awk @@ -211,6 +211,16 @@ name[i], name[i]); } +## array_property + +function emit_get_array (i) +{ + emit_get_accessor(i, "octave_value", "get"); + + printf (" array_property get_%s_property (void) const { return %s; }\n", + name[i], name[i]); +} + ## common section function emit_common_declarations () @@ -244,9 +254,7 @@ { if (emit_get[i]) { - if (type[i] == "array_property" \ - || type[i] == "row_vector_property" \ - || type[i] == "any_property") + if (type[i] == "any_property") emit_get_accessor(i, "octave_value", "get"); else if (type[i] == "handle_property") emit_get_accessor(i, "graphics_handle", "handle_value"); @@ -256,6 +264,9 @@ emit_get_accessor(i, "double", "double_value"); else if (type[i] == "data_property") emit_get_data(i); + else if (type[i] == "array_property" \ + || type[i] == "row_vector_property") + emit_get_array(i); else if (type[i] == "bool_property") emit_get_bool(i); else if (type[i] == "radio_property") diff --git a/src/graphics.cc b/src/graphics.cc --- a/src/graphics.cc +++ b/src/graphics.cc @@ -428,6 +428,32 @@ return octave_value (a); } +template +static void +get_array_limits (const Array& m, double& emin, double& emax, + double& eminp) +{ + const T *data = m.data (); + int n = m.numel (); + + for (int i = 0; i < n; i++) + { + double e = double (data[i]); + + if (! (xisinf (e) || xisnan (e))) + { + if (e < emin) + emin = e; + + if (e > emax) + emax = e; + + if (e >= 0 && e < eminp) + eminp = e; + } + } +} + // --------------------------------------------------------------------- radio_values::radio_values (const std::string& opt_string) @@ -569,7 +595,7 @@ { for (std::list::const_iterator it = type_constraints.begin (); ! xok && it != type_constraints.end (); ++it) - if ((*it) == v.type_name ()) + if ((*it) == v.class_name ()) xok = true; } else @@ -606,6 +632,38 @@ } void +array_property::get_data_limits (void) +{ + xmin = xminp = octave_Inf; + xmax = -octave_Inf; + + if (! data.is_empty ()) + { + if (data.is_integer_type ()) + { + if (data.is_int8_type ()) + get_array_limits (data.int8_array_value (), xmin, xmax, xminp); + else if (data.is_uint8_type ()) + get_array_limits (data.uint8_array_value (), xmin, xmax, xminp); + else if (data.is_int16_type ()) + get_array_limits (data.int16_array_value (), xmin, xmax, xminp); + else if (data.is_uint16_type ()) + get_array_limits (data.uint16_array_value (), xmin, xmax, xminp); + else if (data.is_int32_type ()) + get_array_limits (data.int32_array_value (), xmin, xmax, xminp); + else if (data.is_uint32_type ()) + get_array_limits (data.uint32_array_value (), xmin, xmax, xminp); + else if (data.is_int64_type ()) + get_array_limits (data.int64_array_value (), xmin, xmax, xminp); + else if (data.is_uint64_type ()) + get_array_limits (data.uint64_array_value (), xmin, xmax, xminp); + } + else + get_array_limits (data.array_value (), xmin, xmax, xminp); + } +} + +void handle_property::set (const octave_value& v) { double dv = v.double_value (); @@ -2378,6 +2436,8 @@ return retval; } +// FIXME: Remove in case all data_property are converted into +// array_property static void check_limit_vals (double& min_val, double& max_val, double& min_pos, const data_property& data) @@ -2393,6 +2453,22 @@ min_pos = val; } +// FIXME: Maybe this should go into array_property class? +static void +check_limit_vals (double& min_val, double& max_val, double& min_pos, + const array_property& data) +{ + double val = data.min_val (); + if (! (xisinf (val) || xisnan (val)) && val < min_val) + min_val = val; + val = data.max_val (); + if (! (xisinf (val) || xisnan (val)) && val > max_val) + max_val = val; + val = data.min_pos (); + if (! (xisinf (val) || xisnan (val)) && val > 0 && val < min_pos) + min_pos = val; +} + // magform(x) Returns (a, b), where x = a * 10^b, a >= 1., and b is // integral. @@ -2681,7 +2757,7 @@ if (obj.isa ("image") || obj.isa ("patch") || obj.isa ("surface")) { - data_property cdata = obj.get_cdata_property (); + array_property cdata = obj.get_cdata_property (); check_limit_vals (min_val, max_val, min_pos, cdata); } diff --git a/src/graphics.h.in b/src/graphics.h.in --- a/src/graphics.h.in +++ b/src/graphics.h.in @@ -717,16 +717,29 @@ class array_property : public base_property { public: + array_property (void) + : base_property ("", graphics_handle ()), data (Matrix ()) + { + get_data_limits (); + } + array_property (const std::string& nm, const graphics_handle& h, const octave_value& m) - : base_property (nm, h), data (m) { } + : base_property (nm, h), data (m) + { + get_data_limits (); + } octave_value get (void) const { return data; } void set (const octave_value& v) { if (validate (v)) - data = v; + { + data = v; + + get_data_limits (); + } else error ("invalid value for array property \"%s\"", get_name ().c_str ()); @@ -738,6 +751,10 @@ void add_constraint (const dim_vector& dims) { size_constraints.push_back (dims); } + double min_val (void) const { return xmin; } + double max_val (void) const { return xmax; } + double min_pos (void) const { return xminp; } + array_property& operator = (const octave_value& val) { set (val); @@ -747,8 +764,13 @@ private: OCTINTERP_API bool validate (const octave_value& v); + OCTINTERP_API void get_data_limits (void); + protected: octave_value data; + double xmin; + double xmax; + double xminp; std::list type_constraints; std::list size_constraints; }; @@ -1657,10 +1679,10 @@ return data_property (); } - virtual data_property get_cdata_property (void) const + virtual array_property get_cdata_property (void) const { error ("get: invalid property \"cdata\""); - return data_property (); + return array_property (); } protected: @@ -2032,7 +2054,7 @@ return props.get_xudata_property (); } - data_property get_cdata_property (void) const + array_property get_cdata_property (void) const { const base_properties& props = get_properties (); return props.get_cdata_property (); @@ -2857,13 +2879,17 @@ BEGIN_PROPERTIES(image) data_property xdata l , Matrix () data_property ydata l , Matrix () - data_property cdata l , Matrix () + array_property cdata l , Matrix () radio_property cdatamapping a , "{scaled}|direct" END_PROPERTIES protected: void init (void) { + cdata.add_constraint ("double"); + cdata.add_constraint ("uint8"); + cdata.add_constraint (dim_vector (-1, -1)); + cdata.add_constraint (dim_vector (-1, -1, 3)); } }; @@ -2903,11 +2929,11 @@ data_property xdata l , Matrix () data_property ydata l , Matrix () data_property zdata l , Matrix () - data_property cdata l , Matrix () + array_property cdata l , Matrix () radio_property cdatamapping , "{scaled}|direct" array_property faces , Matrix () data_property facevertexalphadata , Matrix () - data_property facevertexcdata , Matrix () + array_property facevertexcdata , Matrix () array_property vertices , Matrix () array_property vertexnormals , Matrix () radio_property normalmode , "{auto}|manual" @@ -2939,6 +2965,10 @@ { vertices.add_constraint (dim_vector (-1, 2)); vertices.add_constraint (dim_vector (-1, 3)); + cdata.add_constraint (dim_vector (-1, -1)); + cdata.add_constraint (dim_vector (-1, -1, 3)); + facevertexcdata.add_constraint (dim_vector (-1, 1)); + facevertexcdata.add_constraint (dim_vector (-1, 3)); } }; @@ -2978,8 +3008,7 @@ data_property xdata lu , Matrix () data_property ydata lu , Matrix () data_property zdata lu , Matrix () - // FIXME: cdata can be of type "double" or "uint8" - data_property cdata l , Matrix () + array_property cdata l , Matrix () radio_property cdatamapping a , "{scaled}|direct" color_property facecolor , "{flat}|none|interp|texturemap" // FIXME: should be a double-radio property @@ -3018,11 +3047,10 @@ alphadata.add_constraint ("uint8"); alphadata.add_constraint (dim_vector (-1, -1)); vertexnormals.add_constraint (dim_vector (-1, -1, 3)); - // FIXME: uncomment this when cdata has the right type - //cdata.add_constraint ("double"); - //cdata.add_constraint ("double"); - //cdata.add_constraint (dim_vector (-1, -1)); - //cdata.add_constraint (dim_vector (-1, -1, 3)); + cdata.add_constraint ("double"); + cdata.add_constraint ("uint8"); + cdata.add_constraint (dim_vector (-1, -1)); + cdata.add_constraint (dim_vector (-1, -1, 3)); } private: