1 ## Copyright (C) 2007-2012 John W. Eaton, Shai Ayal, Kai Habel
3 ## This file is part of Octave.
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ## General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING. If not, see
17 ## <http://www.gnu.org/licenses/>.
20 ## @deftypefn {Function File} {[@var{h}, @var{fail}] =} __patch__ (@var{p}, @dots{})
21 ## Undocumented internal function.
24 ## __patch__ (p, x, y, c)
25 ## Create patch object from x and y with color c and parent p.
26 ## Return handle to patch object.
30 function [h, failed] = __patch__ (p, varargin)
35 is_numeric_arg = cellfun (@isnumeric, varargin);
37 if (isempty (varargin))
38 args = {"xdata", [0; 1; 0], "ydata", [1; 1; 0], "facecolor", [0, 0, 0]};
39 args = setvertexdata (args);
40 elseif (isstruct (varargin{1}))
41 if (isfield (varargin{1}, "vertices") && isfield (varargin{1}, "faces"))
43 args{2} = getfield(varargin{1}, "faces");
45 args{4} = getfield(varargin{1}, "vertices");
46 args{5} = "facevertexcdata";
47 if (isfield (varargin{1}, "facevertexcdata"))
48 args{6} = getfield(varargin{1}, "facevertexcdata");
52 args = [args; varargin(2:end)];
53 args = setdata (args);
57 elseif (is_numeric_arg(1))
58 if (nargin < 3 || ! is_numeric_arg(2))
62 if (nargin > 4 && all (is_numeric_arg(1:4)))
68 elseif (nargin > 3 && all (is_numeric_arg(1:3)))
72 if (rem (nargin - iarg, 2) == 1)
80 elseif (nargin > 2 && all (is_numeric_arg(1:2)))
85 if (rem (nargin - iarg, 2) == 1)
98 if (isvector (c) && numel (c) == numel (x))
100 elseif (size (c, 1) != numel (x) && size (c, 2) == numel (x))
114 if (ndims (c) == 3 && size (c, 2) == 1)
115 c = permute (c, [1, 3, 2]);
118 if (isvector (c) && numel (c) == columns (x))
120 args{7} = "facecolor";
124 elseif (isnumeric (c))
125 args{7} = "facecolor";
130 error ("patch: color value not valid");
132 elseif (isvector (c) && numel (c) == 3)
133 args{7} = "facecolor";
137 elseif (ndims (c) == 3 && size (c, 3) == 3)
138 ## CDATA is specified as RGB data
139 if ((size (c, 1) == 1 && size (c, 2) == 1) ...
140 || (size (c, 1) == 1 && size (c, 2) == columns (x)))
141 ## Single patch color or per-face color
142 args{7} = "facecolor";
146 elseif (size (c, 1) == rows (x) && size (c, 2) == columns (x))
148 args{7} = "facecolor";
153 error ("patch: color value not valid");
158 args{7} = "facecolor";
162 elseif (isequal (size (c), size (x)) && isequal (size (c), size (y)))
163 args{7} = "facecolor";
168 error ("patch: size of x, y, and c must be equal");
171 elseif (ischar (c) && rem (nargin - iarg, 2) == 0)
172 ## Assume that any additional argument over an even number is
174 args{7} = "facecolor";
175 args{8} = tolower (c);
179 args{7} = "facecolor";
185 args = [args, varargin(iarg:end)];
186 args = setvertexdata (args);
190 if (any (strcmpi (args, "faces") | strcmpi (args, "vertices")))
191 args = setdata (args);
193 args = setvertexdata (args);
198 h = __go_patch__ (p, args {:});
200 ## Setup listener functions
201 addlistener (h, "xdata", @update_data);
202 addlistener (h, "ydata", @update_data);
203 addlistener (h, "zdata", @update_data);
204 addlistener (h, "cdata", @update_data);
206 addlistener (h, "faces", @update_fvc);
207 addlistener (h, "vertices", @update_fvc);
208 addlistener (h, "facevertexcdata", @update_fvc);
212 function args = delfields(args, flds)
213 idx = cellfun (@(x) any (strcmpi (x, flds)), args);
215 idx = idx | [false, idx(1:end-1)];
217 idx = idx | [false; idx(1:end-1)];
222 function args = setdata (args)
223 args = delfields (args, {"xdata", "ydata", "zdata", "cdata"});
224 ## Remove the readonly fields as well
225 args = delfields (args, {"type", "uicontextmenu"});
226 nargs = length (args);
227 idx = find (strcmpi (args, "faces"), 1, "last") + 1;
233 idx = find (strcmpi (args, "vertices"), 1, "last") + 1;
239 idx = find (strcmpi (args, "facevertexcdata"), 1, "last") + 1;
240 if (isempty(idx) || idx > nargs)
245 idx = find (strcmpi (args, "facecolor"), 1, "last") + 1;
246 if (isempty(idx) || idx > nargs)
252 args = {"facecolor", fc, args{:}};
255 nc = size (faces, 1);
258 for i = find (any (t1))
259 first_idx_in_column = find (t1(:,i), 1);
260 idx(first_idx_in_column:end,i) = idx(first_idx_in_column-1,i);
262 x = reshape (vert(:,1)(idx), size (idx));
263 y = reshape (vert(:,2)(idx), size (idx));
264 if (size(vert,2) > 2)
265 z = reshape (vert(:,3)(idx), size (idx));
270 if (size(fvc, 1) == nc || size (fvc, 1) == 1)
271 c = reshape (fvc, [1, size(fvc)]);
273 if (size(fvc, 2) == 3)
274 c = cat(3, reshape (fvc(idx, 1), size(idx)),
275 reshape (fvc(idx, 2), size(idx)),
276 reshape (fvc(idx, 3), size(idx)));
277 elseif (isempty (fvc))
279 else ## if (size (fvc, 2) == 1)
280 c = permute (fvc(faces), [2, 1]);
283 args = {"xdata", x, "ydata", y, "zdata", z, "cdata", c, args{:}};
286 function args = setvertexdata (args)
287 args = delfields (args, {"vertices", "faces", "facevertexcdata"});
288 ## Remove the readonly fields as well
289 args = delfields (args, {"type", "uicontextmenu"});
290 nargs = length (args);
291 idx = find (strcmpi (args, "xdata"), 1, "last") + 1;
297 idx = find (strcmpi (args, "ydata"), 1, "last") + 1;
303 idx = find (strcmpi (args, "zdata"), 1, "last") + 1;
304 if (isempty(idx) || idx > nargs)
309 idx = find (strcmpi (args, "cdata"), 1, "last") + 1;
310 if (isempty(idx) || idx > nargs)
315 idx = find (strcmpi (args, "facecolor"), 1, "last") + 1;
316 if (isempty(idx) || idx > nargs)
322 args = {"facecolor", fc, args{:}};
326 if (nr == 1 && nc > 1)
331 vert = [x(:), y(:), z(:)];
335 faces = reshape (1:numel(x), nr, nc);
339 fvc = reshape (c, size (c, 1) * size (c, 2), size(c, 3));
344 args = {"faces", faces, "vertices", vert, "facevertexcdata", fvc, args{:}};
347 function update_data (h, d)
348 update_handle (h, false);
351 function update_fvc (h, d)
352 update_handle (h, true);
355 function update_handle (h, isfv)
356 persistent recursive = false;
362 set (h, setdata ([fieldnames(f), struct2cell(f)].'(:)){:});
364 set (h, setvertexdata ([fieldnames(f), struct2cell(f)].'(:)){:});