7b796cf5cddff37683db5ba42b82a97766b2ae01
[scilab.git] / scilab / modules / graphics / macros / surf.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2004-2006 - INRIA - Fabrice Leray
3 // Copyright (C) 2012 - 2016 - Scilab Enterprises
4 //
5 // This file is hereby licensed under the terms of the GNU GPL v2.0,
6 // pursuant to article 5.3.4 of the CeCILL v.2.1.
7 // This file was originally licensed under the terms of the CeCILL v2.1,
8 // and continues to be available under such terms.
9 // For more information, see the COPYING file which you should have received
10 // along with this program.
11
12 function surf(varargin)
13     [lhs,rhs] = argn(0);
14
15     // EXAMPLE
16     // -------
17     if ~rhs
18         Z = [
19   0.0001   0.0013   0.0053  -0.0299  -0.1809  -0.2465  -0.1100  -0.0168  -0.0008  -0.0000
20   0.0005   0.0089   0.0259  -0.3673  -1.8670  -2.4736  -1.0866  -0.1602  -0.0067   0.0000
21   0.0004   0.0214   0.1739  -0.3147  -4.0919  -6.4101  -2.7589  -0.2779   0.0131   0.0020
22  -0.0088  -0.0871   0.0364   1.8559   1.4995  -2.2171  -0.2729   0.8368   0.2016   0.0130
23  -0.0308  -0.4313  -1.7334  -0.1148   3.0731   0.4444   2.6145   2.4410   0.4877   0.0301
24  -0.0336  -0.4990  -2.3552  -2.1722   0.8856  -0.0531   2.6416   2.4064   0.4771   0.0294
25  -0.0137  -0.1967  -0.8083   0.2289   3.3983   3.1955   2.4338   1.2129   0.2108   0.0125
26  -0.0014  -0.0017   0.3189   2.7414   7.1622   7.1361   3.1242   0.6633   0.0674   0.0030
27   0.0002   0.0104   0.1733   1.0852   2.6741   2.6725   1.1119   0.1973   0.0152   0.0005
28   0.0000   0.0012   0.0183   0.1099   0.2684   0.2683   0.1107   0.0190   0.0014   0.0000];
29         f = gcf();
30         if size(f.children)==1
31             f.color_map = jetcolormap(64);
32          end
33         s = gca().axes_bounds; delete(gca()); xsetech(s)  // clears the current axes
34         surf(Z,"edgeco","b","marker","d","markersiz",9,"markeredg","red","markerfac","k");
35         return
36     end
37
38     // Detects and sets the current axes now
39     // -------------------------------------
40     ListArg = varargin;
41     argShift = 0;            // To correctly address argins # in error messages
42     if type(ListArg(1)) == 9
43         hdle = ListArg(1);
44         if (hdle.type == "Axes")
45             sca(ListArg(1));
46             ListArg(1) = null(); // remove this parameter from the list
47             argShift = 1;
48         else
49             msg = gettext("%s: Wrong type for input argument #%d: An ''Axes'' handle expected.\n")
50             error(msprintf(msg, "surf", 1))
51         end
52     end
53
54     // Initializations
55     // ---------------
56     X = [];
57     Y = [];
58     Z = [];
59     C = []; // Colors
60
61     CurColor = 0; // current color used if no color specified via LineSpec
62     // nor PropertyName
63     typeOfPlot = "surf";    // used in called functions ?
64     //d = [];
65     nv = size(ListArg);     // Number of input arguments
66
67     // Types of input arguments
68     T = [];
69     for k = 1:nv
70         T(k) = type(ListArg(k))
71     end
72     T = [T' 0 0 0 0]  // Padding to have at least 5 values
73
74     // delay the drawing commands: smart drawlater
75     current_figure = gcf();
76     cur_draw_mode = current_figure.immediate_drawing;
77     current_figure.immediate_drawing = "off";
78
79     colormap_size = size(current_figure.color_map,1);
80
81     // PARSING INPUT ARGUMENTS
82     // =======================
83     //surf(Z)
84     //surf(Z,colors)
85     //surf(X,Y,Z)
86     //surf(X,Y,Z,colors)
87     //surf(X,Y,fun)
88     //surf(X,Y,fun, colors)
89     //surf(X,Y,list(fun,params))
90     //surf(X,Y,list(fun,params), colors)
91
92     // Identifying X and Y
93     // -------------------
94     if and(T(1:2)==[1 0]) | and(T(1:2)==[1 10]) | ..        // surf(Z)
95        and(T(1:3)==[1 1 0]) | and(T(1:3)==[1 1 10])then     // surf(Z, colors)
96         Z = ListArg(1)';    // here a transposition is needed
97         X = 1:size(Z, 1);
98         Y = 1:size(Z, 2);
99         if or(size(Z)==1)
100             ResetFigureDDM(current_figure, cur_draw_mode);
101             msg = gettext("%s: Wrong size for input argument #%d: A matrix of size greater than %d-by-%d expected.\n")
102             error(msprintf(msg, "surf", 1+argShift,  2, 2));
103         end
104
105     else                                                    // surf(X,Y, ..)
106         X = ListArg(1)
107         if T(1)~=1 | ~isreal(X) then
108             msg = gettext("%s: Argument #%d: Decimal numbers expected.\n")
109             error(msprintf(msg, "surf", 1+argShift));
110         end
111         if length(X)<2 then
112             msg = gettext("%s: Argument #%d: At least %d components expected.\n")
113             error(msprintf(msg, "surf", 1+argShift, 2));
114         end
115         //
116         Y = ListArg(2)
117         if T(2)~=1 | ~isreal(Y) then
118             msg = gettext("%s: Argument #%d: Decimal numbers expected.\n")
119             error(msprintf(msg, "surf", 2+argShift));
120         end
121         if length(Y)<2 then
122             msg = gettext("%s: Argument #%d: At least %d components expected.\n")
123             error(msprintf(msg, "surf", 2+argShift, 2));
124         end
125         if ~isvector(X) | ~isvector(Y)
126             if or(size(X)~=size(Y))
127                 msg = gettext("%s: Arguments #%d and #%d: Incompatible sizes.\n")
128                 error(msprintf(msg, "surf", 1+argShift, 2+argShift));
129             end
130         end
131     end
132
133     // Generating Z from fun() or list(fun(), params)
134     // ----------------------------------------------
135     // Separating the function and its parameters
136     withParams = T(3)==15
137     params = list()
138     buildFunc = []
139     if withParams then
140         tmp = ListArg(3)
141         if size(tmp)<2 | and(type(tmp(1))~=[13 130])
142             ResetFigureDDM(current_figure, cur_draw_mode);
143             msg = _("%s: Argument #%d: Wrong list() specification.\n")
144             error(msprintf(msg, "surf", 3))
145         end
146         buildFunc = tmp(1)
147         tmp(1) = null()
148         params = tmp
149         if type(params)~=15
150             params = list(params)
151         end
152     elseif or(T(3)==[13 130])
153         buildFunc = ListArg(3)
154     end
155     // Generating Z. Managing a possible inner error. Checking consistency of Z sizes:
156     if type(buildFunc)~=1 then  // ~=[]
157         if isvector(X) | isvector(Y) then
158             try
159                 Z = buildFunc(X,Y,params(:))
160             catch
161                 // May be buildFunc() expects X and Y as matrices:
162                 [Y, X] = ndgrid(Y,X)
163             end
164         end
165         if Z==[]
166             try
167                 Z = buildFunc(X,Y,params(:))
168             catch
169                 ResetFigureDDM(current_figure, cur_draw_mode);
170
171                 // get error info
172                 [err_message, err_number, err_line, err_func] = lasterror(%t);
173
174                 // yield it
175                 if err_func~="", err_func = """"+err_func+"()""", end
176                 msg = gettext("%s: Argument #%d : Unable to evaluate Z: Error %d at line %d in %s: ''%s''")
177                 error(msprintf(msg, "surf", 3, err_number, err_line, err_func, err_message));
178             end
179         end
180         // Checking size(Z):
181         if isvector(X) | isvector(Y) then
182             nr = length(Y)
183             nc = length(x)
184         else
185             [nr, nc] = size(X)
186         end
187         if or(size(Z)~=[nr nc])
188             msg = gettext("%s: Argument #%d: Inconsistent size of the result.\n")
189             error(msprintf(msg, "surf", 3));
190         end
191     end
192     clear buildFunc params withParams
193     // Z extraction from  surf(X,Y,Z) and surf(X,Y,Z,colors)
194     if Z==[] &  and(T(2:3)==[1 1]) then
195         Z = ListArg(3)
196     end
197
198     // Colors extraction and checking
199     // ------------------------------
200     if and(T(2:3)==[1 0]) | and(T(2:3)==[1 10]) then  //surf(Z,colors)
201         C = ListArg(2)'
202         i = 2
203     elseif and(T(2:4)==[1 1 1])  | ..    // surf(X, Y, Z, colors)
204            and(T(2:4)==[1 15 1]) | ..    // surf(X, Y, list(fun,params), colors)
205            and(T(2:4)==[1 13 1]) | ..    // surf(X, Y, macro, colors)
206            and(T(2:4)==[1 130 1]) then   // surf(X, Y, builtin, colors)
207         C = ListArg(4)
208         i = 4
209     end
210     if C~=[] then
211         if ((size(Z) <> size(C)) & (size(Z)-1 <> size(C)))
212             ResetFigureDDM(current_figure, cur_draw_mode);
213             msg = gettext("%s: Wrong size for input argument #%d: A %d-by-%d or %d-by-%d matrix expected.\n")
214             error(msprintf(msg,"surf", i+argShift, size(Z,2), size(Z,1), size(Z,2)-1, size(Z,1)-1))
215         end
216     end
217
218
219     // GENERATING FACETS
220     // =================
221     P1 = 0       // Position of the first PropertyName field
222     // surf(Z)
223     // -------
224     if and(T(1:2)==[1 0]) | and(T(1:2)==[1 10]) then
225         [XX,YY,ZZ] = genfac3d(X,Y,Z);
226         CC = ZZ; // Add a color matrix based on Z values
227         if T(2)==10 then
228             P1 = 2
229         end
230
231     // surf(Z, colors)
232     // ---------------
233     elseif and(T(1:3)==[1 1 0]) | and(T(1:3)==[1 1 10])
234         [XX, YY, ZZ] = genfac3d(X, Y, Z);
235         if (size(C)==size(Z)) // color number == zdata number
236             [XX,YY,CC] = genfac3d(X,Y,C);    // CC must be a color matrix of size nf x n
237         elseif (size(C) == (size(Z)-1))      // color number -1 == zdata number => ONLY flat mode can be enabled
238             Ctmp = []
239             Ctmp = [C [C(:,$)]]
240             Ctmp = [Ctmp; Ctmp($,:)]
241             [XX,YY,CC] = genfac3d(X,Y,Ctmp); // CC must be a color matrix of size nf x n
242         end
243         if T(3)==10 then
244             P1 = 2
245         end
246     else
247         // check if the call is OK
248         if C==[]
249             err = execstr("[XX,YY,ZZ,CC] = CreateFacetsFromXYZ(X,Y,Z,current_figure, cur_draw_mode)","errcatch","n");
250             if T(4)==10 then
251                 P1 = 4
252             end
253         else
254             err = execstr("[XX,YY,ZZ,CC] = CreateFacetsFromXYZColor(X,Y,Z,C,current_figure, cur_draw_mode)","errcatch","n");
255             if T(5)==10 then
256                 P1 = 5
257             end
258         end
259         if (err <> 0) then
260             // reset data
261             processSurfError(current_figure, cur_draw_mode);
262         end
263     end
264
265
266     // PARSING THE (PROPERTY - VALUE) SERIES
267     // =====================================
268     // P1 is the position of the first PropertyName field.
269     Property = P1;
270
271     while ((Property <> 0) & (Property <= nv-1))
272         PropertyName  = ListArg(Property);
273         PropertyValue = ListArg(Property+1);
274
275         // Xdata
276         PName = getSurfPropertyName(PropertyName);
277         if (PName == "xdata")
278
279             if (type(PropertyValue)<>1)
280                 ResetFigureDDM(current_figure, cur_draw_mode);
281                 error(msprintf(gettext("%s: Wrong type for input argument ''%s'': A Real matrix expected.\n"), "surf", "xdata"));
282             end
283
284             X = PropertyValue;
285             [XX,tmp2,tmp3] = CreateFacetsFromXYZ(PropertyValue,Y,Z,current_figure, cur_draw_mode);
286
287             // Ydata
288         elseif (PName == "ydata")
289
290             if (type(PropertyValue)<>1)
291                 ResetFigureDDM(current_figure, cur_draw_mode);
292                 error(msprintf(gettext("%s: Wrong type for input argument ''%s'': A Real matrix expected.\n"), "surf", "ydata"));
293             end
294
295             Y = PropertyValue;
296             [tmp1,YY,tmp3] = CreateFacetsFromXYZ(X,PropertyValue,Z,current_figure, cur_draw_mode);
297
298             // Zdata
299         elseif (PName == "zdata")
300
301             if (type(PropertyValue)<>1) then
302                 ResetFigureDDM(current_figure, cur_draw_mode);
303                 error(msprintf(gettext("%s: Wrong type for input argument ''%s'': A Real matrix expected.\n"), "surf", "zdata"));
304             end
305             if (or(size(PropertyValue)==1)) then
306                 ResetFigureDDM(current_figure, cur_draw_mode);
307                 error(msprintf(gettext("%s: Wrong size for input argument ''%s'': A matrix of size greater than %d-by-%d expected.\n"), "surf", "zdata",  2, 2));
308             end
309
310             Z = PropertyValue;
311             [tmp1,tmp2,ZZ] = CreateFacetsFromXYZ(X,Y,PropertyValue,current_figure, cur_draw_mode);
312
313         end
314
315         Property = Property+2;
316     end
317
318     if isempty(XX) | isempty(YY) | isempty(ZZ) then
319         // Nothing will be drawn so return (see http://bugzilla.scilab.org/13180 )
320         return
321     end
322
323     // surf is made now !
324
325
326     // PLOTTING THE SURFACE
327     // ====================
328     err = execstr("plot3d(XX,YY,list(ZZ,CC))","errcatch","n");
329     if err <> 0
330         processSurfError(current_figure, cur_draw_mode);
331     end
332     // Default options (as Matlab ones)
333     a = gca();
334     a.cube_scaling = "on";
335     a.rotation_angles = [51 -125];
336     e = gce();
337     e.hiddencolor = 0; // to avoid painting the hidden facets
338     e.color_flag  = 4; // Matlab special flat mode by default (different from mode 2)
339     e.cdata_mapping = "scaled"
340
341
342     // F.Leray
343     // Today: 17.03.05
344     // XYZ-DataMode under Matlab seems really bugged (see following samples and read Matlab doc.):
345     //
346     // surf(X,Y,Z,'XDataMode','auto')
347     // surf(X,Y,Z,'XDataMode','auto')
348     // surf(X+20,Y,Z,'XDataMode','auto')
349     // surf(X+20,Y,Z,'XDataMode','man')
350     // surf(X+20,Y,Z,'XDataMode','auto')
351     // surf(X+20,Y,Z,'Xdata',X-100,'XDataMode','auto')
352     // surf(X+20,Y,Z,'Xdata',X-100,'XDataMode','man')
353     // surf(X+20,Y,Z,'XData',X-100,'XDataMode','auto')
354     // surf(X+20,Y,Z,'XData',X-100,'XDataMode','man')
355     // surf(Z,'XData',X-100,'XDataMode','man')
356     // surf(Z,'XData',X-100,'XDataMode','auto')
357     // surf(X+20,Y,Z,'XDataMode','man')
358     // surf(X+20,Y,Z,'XDataMode','auto')
359     //
360     // That is why I do not support those properties.
361     // Below and in comment is the code we could add to treat those properties.
362     // by giving  XYZ-DataModeVal to setSurfProperty (to better treat XYZ-Data input).
363     //
364     //
365     //XdataModeVal=1;
366     //YdataModeVal=1;
367     //ZdataModeVal=1;
368     //
369     //if Property <> 0
370     //  XdataMode = getIndexInStringTable('xdatam',ListArg([Property nv]))
371     //  if XdataMode <> []
372     //    XdataModeVal = getIndexInStringTable(ListArg(XdataMode+1),['auto','manual'])
373     //    if size(XdataModeVal,'*') <> 1
374     //      disp("Error: Bad XdataMode selected");
375     //      return;
376     //    end
377     //  end
378     //
379     //  YdataMode = getIndexInStringTable('ydatam',ListArg([Property nv]))
380     //  if YdataMode <> []
381     //    YdataModeVal = getIndexInStringTable(ListArg(YdataMode+1),['auto','manual'])
382     //    if size(YdataModeVal,'*') <> 1
383     //      disp("Error: Bad YdataMode selected");
384     //      return;
385     //    end
386     //  end
387     //
388     //  ZdataMode = getIndexInStringTable('zdatam',ListArg([Property nv]))
389     //  if ZdataMode <> []
390     //    ZdataModeVal = getIndexInStringTable(ListArg(ZdataMode+1),['auto','manual'])
391     //    if size(ZdataModeVal,'*') <> 1
392     //      disp("Error: Bad ZdataMode selected");
393     //      return;
394     //   end
395     //  end
396     //end
397     //
398
399
400     // SETTING SPECIFIED PROPERTIES
401     // ============================
402     current_surface = gce();                // get the newly created fac3d
403     current_surface.mark_size_unit = "point";
404     Property = P1;  // Position of the first PropertyName field.
405     while ((Property <> 0) & (Property <= nv-1))
406         setSurfProperty(ListArg(Property),ListArg(Property+1),current_surface,X,Y,Z,C,current_figure,cur_draw_mode)
407         Property = Property+2;
408     end
409
410     //postponed drawings are done now !
411     // smart drawnow
412     ResetFigureDDM(current_figure, cur_draw_mode);
413
414 endfunction
415
416 //
417 //function [C] = build_interp_color(C,colormap_size)
418 //// C is considered as a data value in Matlab
419 //MIN = min(C);
420 //MAX = max(C);
421 //NCOLMIN = 1;
422 //NCOLMAX = colormap_size;
423 //
424 //if MIN <> MAX
425 //  C = (NCOLMIN-NCOLMAX)/(MIN-MAX) * C + (MIN*NCOLMAX - NCOLMIN*MAX)/(MIN-MAX);
426 //  C = round(C);
427 //else
428 //  C = ones(C) * (NCOLMIN+NCOLMAX)/2;
429 //end
430 //endfunction
431 //
432 //
433
434
435 //function k=getIndexInStringTable(pattern,table)
436 //
437 //    str =  convstr(pattern);
438 //    k=find(part(table,1:length(str))==str);
439 //
440 //endfunction
441
442 function [XX,YY,ZZ,CC] = CreateFacetsFromXYZ(X,Y,Z,current_figure, cur_draw_mode)
443
444     if or(size(X)==1) & or(size(Y)==1) // X and Y are vector
445
446         tmp = X;
447         X = Y;
448         Y = tmp;
449
450         if size(X,"*") ~= size(Z,1) then
451             ResetFigureDDM(current_figure, cur_draw_mode);
452             error(msprintf(gettext("%s: Wrong size for input argument ''%s'': A vector of size %d expected.\n"), "surf", "Y", size(Z,1)));
453             return;
454         end
455
456         if size(Y,"*") ~= size(Z,2) then
457             ResetFigureDDM(current_figure, cur_draw_mode);
458             error(msprintf(gettext("%s: Wrong size for input argument ''%s'': A vector of size %d expected.\n"), "surf", "X", size(Z,2)));
459             return;
460         end
461
462         [XX,YY,ZZ] = genfac3d(Y,X,Z');
463
464         // COLOR treatment
465         CC = ZZ;
466
467     elseif and(size(X)>1) & and(size(Y)>1) // X and Y are matrix
468
469         if or(size(X) ~= size(Y)) then
470             ResetFigureDDM(current_figure, cur_draw_mode);
471             error(msprintf(gettext("%s: Wrong size for input arguments ''%s'' and ''%s'': Matrices of same size expected.\n"), "surf", "X", "Y"));
472             return;
473         end
474
475         if or(size(X) ~= size(Z)) then
476             ResetFigureDDM(current_figure, cur_draw_mode);
477             error(msprintf(gettext("%s: Wrong size for input arguments ''%s'' and ''%s'': Matrices of same size expected.\n"), "surf", "X", "Z"));
478             return;
479         end
480
481         [XX,YY,ZZ] = nf3d(X,Y,Z);
482
483         // COLOR treatment
484         CC = ZZ;
485
486     elseif or(size(X)==1) & and(size(Y)>1) // X is a vector and Y is a matrix
487
488         if size(X,"*") ~= size(Z,2) then
489             ResetFigureDDM(current_figure, cur_draw_mode);
490             error(msprintf(gettext("%s: Wrong size for input argument ''%s'': A vector of size %d expected.\n"), "surf", "X", size(Z,2)));
491             return;
492         end
493
494         if or(size(Y) ~= size(Z)) then
495             ResetFigureDDM(current_figure, cur_draw_mode);
496             error(msprintf(gettext("%s: Wrong size for input arguments ''%s'' and ''%s'': Matrices of same size expected.\n"), "surf", "Y", "Z"));
497             return;
498         end
499
500         // X vector
501         // Y matrix
502         // Z matrix
503
504         X=X(:)'; // X is forced to be a row vector
505         XMAT=[];
506
507         for i=1:size(Z,2)
508             XMAT=[XMAT;X];
509         end
510
511         [XX,YY,ZZ] = nf3d(XMAT,Y,Z);
512
513         // COLOR treatment
514         CC = ZZ;
515
516     elseif or(size(Y)==1) & and(size(X)>1) // Y is a vector and X is a matrix
517
518         if or(size(X) ~= size(Z)) then
519             ResetFigureDDM(current_figure, cur_draw_mode);
520             error(msprintf(gettext("%s: Wrong size for input arguments ''%s'' and ''%s'': Matrices of same size expected.\n"), "surf", "X", "Z"));
521             return;
522         end
523
524         if size(Y,"*") ~= size(Z,2) then
525             ResetFigureDDM(current_figure, cur_draw_mode);
526             error(msprintf(gettext("%s: Wrong size for input argument ''%s'': A vector of size %d expected.\n"), "surf", "Y", size(Z,2)));
527             return;
528         end
529
530         // Y vector
531         // X matrix
532         // Z matrix
533
534         Y=Y(:); // Y is forced to be a column vector
535         YMAT=[];
536
537         for i=1:size(Z,1)
538             YMAT=[YMAT,Y];
539         end
540
541         [XX,YY,ZZ] = nf3d(X,YMAT,Z);
542
543         // COLOR treatment
544         CC = ZZ;
545
546     else
547         ResetFigureDDM(current_figure, cur_draw_mode);
548         error(msprintf(gettext("%s: Wrong size for input arguments ''%s'' and ''%s'': Same size expected.\n"), "surf", "X", "Y"));
549         return;
550     end
551
552 endfunction
553
554 function [XX,YY,ZZ,CC] = CreateFacetsFromXYZColor(X,Y,Z,C,current_figure, cur_draw_mode)
555
556     if or(size(X)==1) & or(size(Y)==1) // X and Y are vector
557
558         Z = Z'; // here a transposition is needed
559         C = C'; // here a transposition is needed
560
561         if size(X,"*") ~= size(Z,1) then
562             ResetFigureDDM(current_figure, cur_draw_mode);
563             error(msprintf(gettext("%s: Wrong size for input argument ''%s'': A vector of size %d expected.\n"), "surf", "X", size(Z,1)));
564             return;
565         end
566
567         if size(Y,"*") ~= size(Z,2) then
568             ResetFigureDDM(current_figure, cur_draw_mode);
569             error(msprintf(gettext("%s: Wrong size for input argument ''%s'': A vector of size %d expected.\n"), "surf", "Y", size(Z,2)));
570             return;
571         end
572
573         [XX,YY,ZZ] = genfac3d(X,Y,Z);
574
575         // COLOR treatment
576         if (size(C) == size(Z)) // color number == zdata number
577             [XX,YY,CC] = genfac3d(X,Y,C);     // CC must be a color matrix of size nf x n
578         elseif (size(C) == size(Z)-1) // color number -1 == zdata number => ONLY flat mode can be enabled
579             Ctmp=[];
580             Ctmp = [C [C(:,$)]] ;
581             Ctmp = [Ctmp; Ctmp($,:)];
582             [XX,YY,CC] = genfac3d(X,Y,Ctmp);     // CC must be a color matrix of size nf x n
583         end
584
585     elseif and(size(X)>1) & and(size(Y)>1) // X and Y are matrices
586
587         if or(size(X) ~= size(Y)) then
588             ResetFigureDDM(current_figure, cur_draw_mode);
589             error(msprintf(gettext("%s: Wrong size for input arguments ''%s'' and ''%s'': Matrices of same size expected.\n"), "surf", "X", "Y"));
590             return;
591         end
592
593         if or(size(X) ~= size(Z)) then
594             ResetFigureDDM(current_figure, cur_draw_mode);
595             error(msprintf(gettext("%s: Wrong size for input arguments ''%s'' and ''%s'': Matrices of same size expected.\n"), "surf", "X", "Z"));
596             return;
597         end
598
599         [XX,YY,ZZ] = nf3d(X,Y,Z);
600
601         // COLOR treatment
602         if (size(C) == size(Z)) // color number == zdata number
603             [XX,YY,CC] = nf3d(X,Y,C);     // CC must be a color matrix of size nf x n
604         elseif (size(C) == size(Z)-1) // color number -1 == zdata number => ONLY flat mode can be enabled
605             Ctmp=[];
606             Ctmp = [C [C(:,$)]] ;
607             Ctmp = [Ctmp; Ctmp($,:)];
608             [XX,YY,CC] = nf3d(X,Y,Ctmp);     // CC must be a color matrix of size nf x n
609         end
610
611     elseif or(size(X)==1) & and(size(Y)>1) // X is a vector and Y is a matrix
612
613         if size(X,"*") ~= size(Z,2) then
614             ResetFigureDDM(current_figure, cur_draw_mode);
615             error(msprintf(gettext("%s: Wrong size for input argument ''%s'': A vector of size %d expected.\n"), "surf", "X", size(Z,2)));
616             return;
617         end
618
619         if or(size(Y) ~= size(Z)) then
620             ResetFigureDDM(current_figure, cur_draw_mode);
621             error(msprintf(gettext("%s: Wrong size for input arguments ''%s'' and ''%s'': Matrices of same size expected.\n"), "surf", "Y", "Z"));
622             return;
623         end
624
625         // X vector
626         // Y matrix
627         // Z matrix
628
629         X=X(:)'; // X is forced to be a row vector
630         XMAT=[];
631
632         for i=1:size(Z,2)
633             XMAT=[XMAT;X];
634         end
635
636
637
638         [XX,YY,ZZ] = nf3d(XMAT,Y,Z);
639
640         // COLOR treatment
641         if (size(C) == size(Z)) // color number == zdata number
642             [XX,YY,CC] = nf3d(XMAT,Y,C);     // CC must be a color matrix of size nf x n
643         elseif (size(C) == size(Z)-1) // color number -1 == zdata number => ONLY flat mode can be enabled
644             Ctmp=[];
645             Ctmp = [C [C(:,$)]] ;
646             Ctmp = [Ctmp; Ctmp($,:)];
647             [XX,YY,CC] = nf3d(XMAT,Y,Ctmp);     // CC must be a color matrix of size nf x n
648         end
649
650     elseif or(size(Y)==1) & and(size(X)>1) // Y is a vector and X is a matrix
651
652         if or(size(X) ~= size(Z)) then
653             ResetFigureDDM(current_figure, cur_draw_mode);
654             error(msprintf(gettext("%s: Wrong size for input arguments ''%s'' and ''%s'': Matrices of same size expected.\n"), "surf", "X", "Z"));
655             return;
656         end
657
658         if size(Y,"*") ~= size(Z,2) then
659             ResetFigureDDM(current_figure, cur_draw_mode);
660             error(msprintf(gettext("%s: Wrong size for input argument ''%s'': A vector of size %d expected.\n"), "surf", "Y", size(Z,2)));
661             return;
662         end
663
664
665         // Y vector
666         // X matrix
667         // Z matrix
668
669         Y=Y(:); // Y is forced to be a column vector
670         YMAT=[];
671
672         for i=1:size(Z,1)
673             YMAT=[YMAT,Y];
674         end
675
676         [XX,YY,ZZ] = nf3d(X,YMAT,Z);
677
678         // COLOR treatment
679         if (size(C) == size(Z)) // color number == zdata number
680             [XX,YY,CC] = nf3d(X,YMAT,C);     // CC must be a color matrix of size nf x n
681         elseif (size(C) == size(Z)-1) // color number -1 == zdata number => ONLY flat mode can be enabled
682             Ctmp=[];
683             Ctmp = [C [C(:,$)]] ;
684             Ctmp = [Ctmp; Ctmp($,:)];
685             [XX,YY,CC] = nf3d(X,YMAT,Ctmp);     // CC must be a color matrix of size nf x n
686         end
687
688     else
689         ResetFigureDDM(current_figure, cur_draw_mode);
690         error(msprintf(gettext("%s: Wrong size for input arguments ''%s'' and ''%s'': Matrices of same size expected.\n"), "surf", "X", "Y"));
691         return;
692     end
693
694 endfunction
695
696 // If an error occurs in the surf code, we need to catch it
697 // order to reset some default values
698 function processSurfError(cur_figure, cur_draw_mode)
699     // reset data
700     ResetFigureDDM(current_figure, cur_draw_mode);
701
702     // get the error
703     [err_message, err_number, err_line, err_func] = lasterror(%t);
704
705     // rethrow it
706
707     // for now error can only have a single string as input.
708     // If there are several lines we need to concatane them.
709     err_message_nbLines = size(err_message, "*");
710     if (err_message_nbLines > 1) then
711         // put a \n betwee, each string
712         err_message(1) = strcat(err_message, "\n");
713     end
714     error(err_message(1), err_number);
715 endfunction