1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 
9 #include <dxconfig.h>
10 
11 #if defined(HAVE_STRING_H)
12 #include <string.h>
13 #endif
14 
15 #include "interact.h"
16 #include "vectors.h"
17 
18 #define MAX_INPUTS 9
19 
20 extern Array DXScalarConvert(Array ); /* from libdx/stats.h */
21 
22 static Error vec_minmax(Object, int , int *,int , float *, float *);
23 static Error constant_minmax(Array , Type ,int ,float *, float *);
24 static Error IsInvalid(Object, InvalidComponentHandle *);
25 static Error vec_reset(float *, float *, int , int , int , start_type, float *);
26 static Error setoutput(float *, int , int , int , int , Object *);
27 static int isthisint(float *,int ,int );
28 
29 int
m_Vector(Object * in,Object * out)30 m_Vector(Object *in, Object *out)
31 {
32    if (!_dxfvector_base(in, out,0))
33       return ERROR;
34    return OK;
35 }
36 
_dxfvector_base(Object * in,Object * out,int islist)37 Error _dxfvector_base(Object *in, Object *out, int islist)
38 {
39    struct einfo ei;
40    float valtemp=0;
41    float *min, *max, *incr;
42    int *decimal;
43    float *val,min1,max1,incr1;
44    char *label, *id, *incrmethod, *startstr;
45    int i,item=0,change=0,j,n,nitem=-1,range=0,isint=0, start=START_MIDPOINT;
46    int rank=1,dim=3,size,valdim,dec1;
47    int change1,change4,change5,changen=0,req_param=1 /*,decimalzero=1*/;
48    method_type method;
49    Object idobj;
50    int iprint[MAXPRINT],ip[MAXPRINT],msglen=0,shape[1];
51    int refresh = 0;
52 
53    /* required parameters */
54    if (!in[1] && (!in[4] || !in[5]))
55       req_param=0;
56     ei.msgbuf=NULL;
57 
58     /* get id */
59     if (!DXExtractString(in[0], &id)){
60         DXSetError(ERROR_BAD_PARAMETER,"#10000","id");
61         return ERROR;
62     }
63     idobj=in[0];
64 
65    val = NULL;
66    /* initialize ip to 0 (print nothing) */
67    for (i=0; i<MAXPRINT; i++)
68       ip[i]=0;
69 
70    /* get the dimension (all inputs must be same dimension)
71     * find first existing input and set dimension
72     * allocate space for all inputs
73     */
74    for (i=1; i<MAX_INPUTS; i++){
75       if (in[i] && i!=7 && i!=2){
76          if (!DXGetType(in[i],NULL,NULL,&n,&j))
77             return ERROR;
78          if (n==1){
79             rank = n;
80             dim = j;
81             break;
82          }
83       }
84    }
85    min = (float *)DXAllocate(sizeof(float) *dim);
86    max = (float *)DXAllocate(sizeof(float) *dim);
87    incr = (float *)DXAllocate(sizeof(float) *dim);
88    decimal = (int *)DXAllocate(sizeof(int) *dim);
89    for (i=0; i<dim; i++){
90       min[i] = DXD_MAX_FLOAT;
91       max[i] = -DXD_MAX_FLOAT;
92    }
93 
94    /* read in object, data comp must be vector(any dimension)
95     * check cache if change then get min and max else change=0
96     * find min,max of each dimension
97     */
98    change1 = _dxfcheck_obj_cache(in[1],id,0,idobj);
99    change4 = _dxfcheck_obj_cache(in[4],id,4,idobj);
100    change5 = _dxfcheck_obj_cache(in[5],id,5,idobj);
101 
102    if (change1 > 0 || change4 >0 || change5 >0 ){
103       change=1;
104       /* DXWarning("getting min max, change=%d",change); */
105 
106       if (in[1]){
107       /* function vec_minmax takes vector array and returns min,max
108        * of each dimension
109        */
110          if (!DXGetType(in[1],NULL,NULL,&rank,NULL))
111             goto error;
112          if (rank!=1){
113             DXSetError(ERROR_DATA_INVALID,"#10221","input data");
114             goto error;
115          }
116          if (!in[4] || !in[5]){
117             if (!vec_minmax(in[1],dim,&size,rank,min,max))
118                goto error;
119          }
120       }
121 
122       if (in[4]){
123          if (DXExtractFloat(in[4],&min1)){
124             for (i=0; i<dim; i++)
125                min[i] = min1;
126          }
127          else{
128             if (!DXExtractParameter(in[4], TYPE_FLOAT,dim,1,(Pointer)min)){
129                DXSetError(ERROR_BAD_PARAMETER,"#10230","min",dim);
130                goto error;
131             }
132          }
133       }
134       else if (!in[1]){
135          for (i=0; i<dim; i++)
136             min[i] = -1000000;
137       }
138       if (in[5]){
139          if (DXExtractFloat(in[5],&max1)){
140             for (i=0; i<dim; i++)
141                max[i] = max1;
142          }
143          else{
144             if (!DXExtractParameter(in[5], TYPE_FLOAT,dim,1,(Pointer)max)){
145                DXSetError(ERROR_BAD_PARAMETER,"#10230","max",dim);
146                goto error;
147             }
148          }
149       }
150       else if (!in[1]){
151          for (i=0; i<dim; i++)
152             max[i] = 1000000;
153       }
154 
155       /* Print warning if max<min */
156       for (i=0; i<dim; i++){
157          if (max[i] < min[i]){
158             DXSetError(ERROR_BAD_PARAMETER,"#10150","min",max[i] );
159             goto error;
160          }
161       }
162       if (in[1] && (in[4] || in[5]))
163          DXWarning("the min and/or max values have been specified; these override the min/max of the data");
164    }
165 
166    /* read increment(default 1/20), decimal and label
167     * make them the same dimension as data
168     */
169    if (in[7]){
170       if (!DXExtractString(in[7],&incrmethod)){
171          DXSetError(ERROR_BAD_PARAMETER,"#10200","increment method");
172          goto error1;
173        }
174        if (!strncmp("absolute",incrmethod,8))
175           method = ABSOLUTE;
176        else if (!strncmp("relative",incrmethod,8)){
177           if (req_param==0){
178              DXSetError(ERROR_BAD_PARAMETER,
179               "#10925",incrmethod,"use 'absolute'");
180              goto error;
181           }
182           method = PERCENT;
183        }
184        else if (!strncmp("rounded",incrmethod,7)){
185           if (req_param==0){
186              DXSetError(ERROR_BAD_PARAMETER,
187               "#10925",incrmethod,"use 'absolute'");
188              goto error;
189           }
190           method = PERCENT_ROUND;
191        }
192        else{
193           DXSetError(ERROR_BAD_PARAMETER,"#10480","method");
194           goto error1;
195        }
196    }
197    else{
198       if (req_param==0) method = ABSOLUTE;
199       else method = PERCENT_ROUND;
200    }
201 
202    if (in[6]){
203       if (DXExtractFloat(in[6], &incr1)){
204          for (i=0; i<dim; i++)
205             incr[i] = incr1;
206       }
207       else{
208          if (!DXExtractParameter(in[6], TYPE_FLOAT,dim,1,(Pointer)incr)){
209            DXSetError(ERROR_BAD_PARAMETER,"#10230","delta",dim);
210            goto error1;
211          }
212       }
213       for (i=0; i<dim; i++){
214          if (method!=ABSOLUTE && (incr[i] < 0.0 || incr[i] > 1.0)){
215             DXSetError(ERROR_BAD_PARAMETER,"#10110","delta",0,1);
216             goto error1;
217          }
218          else if (method==ABSOLUTE && incr[i] < 0.0){
219             DXSetError(ERROR_BAD_PARAMETER,"#10010","delta");
220             goto error1;
221          }
222       }
223    }
224    else{
225       if (in[7] && method==ABSOLUTE){
226          for (i=0; i<dim; i++)
227             incr[i] = 1.0;
228       }
229       else{
230          for (i=0; i<dim; i++)
231             incr[i] = .01;
232       }
233    }
234 
235    if (in[10]){
236       if (!DXExtractString(in[10], &label)){
237         DXSetError(ERROR_BAD_PARAMETER,"#10200","label");
238         goto error1;
239       }
240    }
241    else
242       label="";
243 
244    if (in[8]){
245       if (DXExtractInteger(in[8],&dec1)){
246          for (i=0; i<dim; i++)
247             decimal[i] = dec1;
248       }
249       else{
250          if (!DXExtractParameter(in[8],TYPE_INT,dim,1,(Pointer)decimal)){
251 	    DXSetError(ERROR_BAD_PARAMETER,"#10230","decimal",dim);
252             goto error1;
253          }
254       }
255       n=0;
256       for (i=0; i<dim; i++){
257 	 if (decimal[i] != 0) n++;
258          if (decimal[i] < 0 || decimal[i] > 6){
259              DXSetError(ERROR_BAD_PARAMETER,"#10040","decimal",0,6);
260              goto error1;
261          }
262       }
263       /*if (n > 0)decimalzero = 0;*/
264    }
265    else{
266       if (req_param==0){
267          for (i=0; i<dim; i++)
268             decimal[i]=5;
269       }
270       else{
271          for (i=0; i<dim; i++)
272             decimal[i]=DXD_MAX_INT;
273       }
274    }
275 
276    if (islist){
277       if (in[9]){
278          if (req_param==0){
279             DXSetError(ERROR_BAD_PARAMETER,
280                 "#10925","nitems","");
281             goto error1;
282          }
283          if (!DXExtractInteger(in[9],&nitem) || nitem<0){
284             DXSetError(ERROR_BAD_PARAMETER,"#10020","default");
285             goto error1;
286          }
287       }
288       else
289          item = 11;
290    }
291    else {
292       item=1;
293       if(in[9]) {
294 		  if (!DXExtractString(in[9],&startstr)){
295 			 DXSetError(ERROR_BAD_PARAMETER,"#10200","start");
296 			 goto error1;
297 		   }
298 		   if (!strncmp("minimum",startstr,7))
299 			  start = START_MINIMUM;
300 		   else if (!strncmp("midpoint",startstr,8))
301 			  start = START_MIDPOINT;
302 		   else if (!strncmp("maximum",startstr,7))
303 			  start = START_MAXIMUM;
304 		   else{
305 			  DXSetError(ERROR_BAD_PARAMETER,"#10480","start");
306 			  goto error1;
307 		   }
308       }
309    }
310 
311    if (in[3]) {
312       if (req_param==0){
313          DXSetError(ERROR_BAD_PARAMETER,"#10925","refresh","");
314          goto error1;
315       }
316       if (!DXExtractInteger(in[3],&refresh) || refresh<0 || refresh > 1){
317          DXSetError(ERROR_BAD_PARAMETER,"must be 0 or 1");
318          goto error1;
319       }
320    }
321    else
322       refresh = 0;
323 
324    /* cache attributes and get min and max if unchanged */
325    for (n=0; n<dim; n++){
326       if (! _dxfinteract_float(id,idobj,&min[n],&max[n],
327                             &incr[n],&decimal[n],label,n,method,&nitem,iprint))
328          goto error;
329       for (j=0; j<MAXPRINT; j++)
330          if (iprint[j]==1)
331             ip[j]=iprint[j];
332    }
333 
334    if (refresh == 1){
335       if (nitem >=0) item=nitem;
336       val = (float *)DXAllocate(sizeof(float)*item *dim);
337       if (!vec_reset(min,max,item,dim,-1,start,val))
338          goto error1;
339       ip[4]=1;
340    }
341    else {
342    if (islist) changen=ip[6];
343    if (ip[0]==1 || ip[1]==1) change=1;
344    else change=0;
345 
346    /* read in scalar parameter
347     * if no change then pass flag and use previously cached value
348     * possible exec changed it previously
349     */
350    if (in[2]){
351       if (!DXGetArrayInfo((Array)in[2],&item,NULL,NULL,NULL,&valdim))
352          goto error1;
353       if (req_param==1 && (valdim != dim || changen==1)){
354          /* if dimension or number of items change, reset */
355          if (nitem >=0) item=nitem;
356          val = (float *)DXAllocate(sizeof(float)*item *dim);
357          if (!vec_reset(min,max,item,dim,-1,start,val))
358             goto error1;
359          ip[4]=1;
360       }
361       else{
362        if (change==0){
363          val = (float *)DXAllocate(sizeof(float)*item *dim);
364          if (!DXExtractParameter(in[2],TYPE_FLOAT,valdim,item, (Pointer)val)){
365             DXSetError(ERROR_INTERNAL,"can't extract current value");
366             goto error1;
367          }
368        }
369        /* check for outofrange the min or max have changed*/
370        else{
371          val = (float *)DXAllocate(sizeof(float)*item *dim);
372          if (valdim != dim){
373           for (i=0; i<item; i++){
374             for (j=0; j<dim; j++){
375                if (in[4]) val[i*dim +j] = min[j];
376                else if (in[5]) val[i*dim +j] = max[j];
377                else val[i*dim +j] = 0.0;
378             }
379           }
380           ip[4]=1;
381          }
382          else{
383           if (!DXExtractParameter(in[2],TYPE_FLOAT,valdim,item, (Pointer)val)){
384             DXSetError(ERROR_INTERNAL,"can't extract current value");
385             goto error1;
386           }
387          }
388          if (req_param==1){
389             for (i=0; i<item; i++){
390                for (j=0; j<dim; j++){
391                   range = OUTOFRANGE(val[i*dim +j],min[j],max[j]);
392                   if (range==1){
393                      if (nitem >=0) item=nitem;
394 		     DXFree((Pointer)val);
395                      val = (float *)DXAllocate(sizeof(float)*item *dim);
396                      if (!vec_reset(min,max,item,dim,-1,start,val))
397                         goto error1;
398                      ip[4]=1;
399    		     break;
400                   }
401 	       }
402 	       if (range==1)
403      		 break;
404             }
405          }
406          else{
407             for (i=0; i<item; i++){
408                for (j=0; j<dim; j++){
409                if (in[4]) valtemp = CLAMPMIN(val[i*dim +j],min[j]);
410                if (in[5]) valtemp = CLAMPMAX(val[i*dim +j],max[j]);
411                if (valtemp != val[i*dim +j])
412                   ip[4]=1;
413                val[i*dim +j] = valtemp;
414                }
415             }
416          }
417        }
418       }
419    }
420    else if (req_param==1){
421       /* first time placed */
422       if (nitem>=0) item=nitem;
423       val = (float *)DXAllocate(sizeof(float)*item*dim);
424       if (!vec_reset(min,max,item,dim,-1,start,val))
425          goto error1;
426       ip[4]=1;
427    }
428    else{
429       item=1;
430       val = (float *)DXAllocate(sizeof(float)*item *dim);
431       for (j=0; j<dim; j++){
432          val[j] = 0.0;
433          if (in[4]) valtemp = CLAMPMIN(val[j],min[j]);
434          if (in[5]) valtemp = CLAMPMAX(val[j],max[j]);
435          val[j] = valtemp;
436       }
437       ip[4]=1;
438    }
439    }
440    /* are these integer or float values, if decimal specified > 0 float */
441    if (!in[8])
442       isint = isthisint(val,dim,item);
443    else{
444       for(n=0; n<dim; n++){
445 	 isint=1;
446          if (decimal[n] > 0) isint = 0;
447       }
448    }
449    if (isint==0){
450       for(n=0; n<dim; n++)
451 	 if (decimal[n] == 0) decimal[n]=1;
452    }
453    else{	/* change values to be integers (still fp) */
454       ip[4]=1;
455       for (i=0; i<item*dim; i++)
456 	 val[i] = (int)val[i];
457    }
458 
459    /* if req_params don't exist print out what is specified */
460    if (req_param==0){
461       if (ip[0]==1 && !in[4]) ip[0]=0;
462       if (ip[1]==1 && !in[5]) ip[1]=0;
463       if (ip[2]==1 && !in[6]) ip[2]=0;
464       if (ip[3]==1 && !in[8]) ip[3]=0;
465    }
466 
467    /* calculate the size of the UI message */
468    if (ip[4] == 1) msglen += (dim*item*NUMBER_CHARS);
469    if (ip[5] == 1) msglen += strlen(label);
470 
471    for (i=0; i < MAXPRINT; i++){
472       if (ip[i] == 1)
473 	 msglen += (dim*NUMBER_CHARS + NAME_CHARS);
474    }
475    if (in[7])
476       msglen += (NAME_CHARS + METHOD_CHARS);
477    if (!islist && in[9])
478       msglen = msglen + NAME_CHARS + METHOD_CHARS;
479 
480    msglen += NAME_CHARS; /* for the dim statement */
481 
482    /* Print out the message
483     * min,max,new value(s)
484     */
485    ei.maxlen = msglen;
486    ei.atend = 0;
487    ei.msgbuf = (char *)DXAllocateZero(ei.maxlen+SLOP);
488    if (!ei.msgbuf)
489       return ERROR;
490    ei.mp =ei.msgbuf;
491 
492    shape[0] = 1;
493    strcpy(ei.mp,"");
494    if (ip[0]==1 || ip[1]==1 || ip[2]==1 || ip[3]==1 || ip[4]==1){
495       sprintf(ei.mp,"dim="); while(*ei.mp) ei.mp++;
496       if (!_dxfprint_message(&dim, &ei, TYPE_INT,0,shape,1))
497          goto error1;
498    }
499    shape[0] = dim;
500    if (ip[0]==1){
501      sprintf(ei.mp,"min="); while(*ei.mp) ei.mp++;
502      if (!_dxfprint_message(min, &ei, TYPE_FLOAT,rank,shape,1))
503         goto error1;
504    }
505    if (ip[1]==1){
506      sprintf(ei.mp, "max="); while(*ei.mp) ei.mp++;
507      if (!_dxfprint_message(max, &ei, TYPE_FLOAT,rank,shape,1))
508         goto error1;
509    }
510    if (ip[2]==1){
511      sprintf(ei.mp, "delta="); while(*ei.mp) ei.mp++;
512      if (!_dxfprint_message(incr, &ei,TYPE_FLOAT,rank,shape,1))
513        goto error1;
514    }
515    if (ip[3]==1){
516      sprintf(ei.mp, "decimals="); while(*ei.mp) ei.mp++;
517      if (!_dxfprint_message(decimal, &ei, TYPE_INT,rank,shape,1))
518         goto error1;
519    }
520    if (ip[4]==1){
521      if (islist){
522         sprintf(ei.mp, "list="); while(*ei.mp) ei.mp++;
523         if (item==1){sprintf(ei.mp,"{"); while(*ei.mp) ei.mp++;}
524      }
525      else{ sprintf(ei.mp, "value="); while(*ei.mp) ei.mp++;}
526      if (!_dxfprint_message(val, &ei, TYPE_FLOAT,rank,shape,item))
527         goto error1;
528      if (islist && item==1){sprintf(ei.mp,"}"); while(*ei.mp) ei.mp++;}
529    }
530    if (in[7]){
531       if (method==ABSOLUTE) sprintf(ei.mp, "method=\"absolute\"");
532       else if(method==PERCENT) sprintf(ei.mp, "method=\"relative\"");
533       else sprintf(ei.mp, "method=\"rounded\"");
534       while(*ei.mp) ei.mp++;
535    }
536    if (!islist && in[9]){
537       if(start==START_MINIMUM) sprintf(ei.mp, "start=\"minimum\"");
538       else if(start==START_MIDPOINT) sprintf(ei.mp, "start=\"midpoint\"");
539       else sprintf(ei.mp, "start=\"maximum\"");
540       while(*ei.mp) ei.mp++;
541    }
542    if (ip[5]==1 && strlen(label)>0){
543       shape[0]=(int)strlen(label);
544      sprintf(ei.mp,"label="); while(*ei.mp) ei.mp++;
545      if (!_dxfprint_message(label, &ei,TYPE_STRING,1,shape,1))
546         goto error1;
547    }
548 
549    /* in DXMessage there is static buffer of MAX_MSGLEN so check length */
550    if (strlen(ei.msgbuf) > MAX_MSGLEN){
551       DXSetError(ERROR_DATA_INVALID,"#10920");
552       goto error1;
553    }
554 
555    if (strcmp(ei.msgbuf,""))
556    DXUIMessage(id,ei.msgbuf);
557 
558    /* create array for output object */
559    if (ip[4]==1){
560       if (item==0) out[0]=NULL;
561       else{
562          if (!setoutput(val,rank,item,dim,isint,out))
563             goto error;
564       }
565    }
566    else
567       out[0]=in[2];
568 
569    DXFree(min);
570    DXFree(max);
571    DXFree(incr);
572    DXFree(decimal);
573    DXFree(ei.msgbuf);
574    if (val) DXFree((Pointer)val);
575    return OK;
576 
577 error:
578 error1:
579    /* change cache of data object so min and max will be cached */
580    change1 = _dxfcheck_obj_cache(in[0],id,0,idobj);
581    DXFree(min);
582    DXFree(max);
583    DXFree(incr);
584    DXFree(decimal);
585    if (val) DXFree(val);
586    if (ei.msgbuf) DXFree(ei.msgbuf);
587    return ERROR;
588 
589 }
590 
591 static
vec_minmax(Object o,int dim,int * size,int rank,float * min,float * max)592 Error vec_minmax(Object o,int dim,int *size,int rank, float *min, float *max)
593 {
594    float *vec_f=NULL;
595    int *vec_i=NULL;
596    double *vec_d=NULL;
597    short *vec_s=NULL;
598    byte *vec_b=NULL;
599    uint *vec_ui=NULL;
600    ubyte *vec_ub=NULL;
601    ushort *vec_us=NULL;
602    int i,ig,j;
603    Array a;
604    float v;
605    Type type;
606    Category category;
607    Object oo;
608    Class class;
609    InvalidComponentHandle inv=NULL;
610 
611    /* determine class of object, if group recurse */
612    class = DXGetObjectClass(o);
613    switch (class){
614 
615    case CLASS_FIELD:
616    case CLASS_ARRAY:
617 
618      if (class!=CLASS_ARRAY){
619         a = (Array)DXGetComponentValue((Field)o,"data");
620         if(!a){
621            DXSetError(ERROR_BAD_PARAMETER,"#10250","object","data");
622            return ERROR;
623         }
624         /* is there invalid data with this field */
625         if (!IsInvalid(o,&inv))
626 	   return ERROR;
627      }
628      else
629         a = (Array)o;
630 
631      if (!DXGetArrayInfo(a,size,&type,&category,NULL,NULL))
632         return ERROR;
633      if (category != CATEGORY_REAL){
634         DXSetError(ERROR_BAD_TYPE,"#11150","data");
635         return ERROR;
636      }
637 
638      /* if class constant array return min, max */
639      if (DXQueryConstantArray(a,NULL,NULL)){
640 	if (!constant_minmax(a,type,dim,min,max))
641            return ERROR;
642         return OK;
643      }
644 
645 
646    /* if one-vector use statistics to get min and max */
647    if (dim==1){
648       if (!DXStatistics(o, "data", &min[0], &max[0], NULL, NULL))
649          return ERROR;
650       return OK;
651    }
652 
653    /* get pointer to data dependant on type */
654    switch (type){
655    case (TYPE_FLOAT):
656       vec_f = (float *)DXGetArrayData(a);
657       break;
658    case (TYPE_INT):
659       vec_i = (int *)DXGetArrayData(a);
660       break;
661    case (TYPE_DOUBLE):
662       vec_d = (double *)DXGetArrayData(a);
663       break;
664    case (TYPE_SHORT):
665       vec_s = (short *)DXGetArrayData(a);
666       break;
667    case (TYPE_BYTE):
668       vec_b = (byte *)DXGetArrayData(a);
669       break;
670    case (TYPE_UINT):
671       vec_ui = (uint *)DXGetArrayData(a);
672       break;
673    case (TYPE_UBYTE):
674       vec_ub = (ubyte *)DXGetArrayData(a);
675       break;
676    case (TYPE_USHORT):
677       vec_us = (ushort *)DXGetArrayData(a);
678       break;
679    default:
680       DXSetError(ERROR_BAD_TYPE,"#10600","data type");
681       return ERROR;
682    }
683 
684 
685    for (i=0; i<(*size); i++){
686       if (inv && (DXIsElementInvalidSequential(inv,i)))
687          continue;
688       for (j=0; j<dim; j++){
689          switch(type){
690          case (TYPE_FLOAT):
691             v = (float)vec_f[i*(dim) +j];
692             break;
693          case (TYPE_INT):
694             v = (float)vec_i[i*(dim) +j];
695             break;
696          case (TYPE_DOUBLE):
697             v = (float)vec_d[i*(dim) +j];
698             break;
699          case (TYPE_SHORT):
700 	    v = (float)vec_s[i*(dim) +j];
701             break;
702          case (TYPE_BYTE):
703             v = (float)vec_b[i*(dim) +j];
704             break;
705          case (TYPE_UINT):
706             v = (float)vec_ui[i*(dim) +j];
707             break;
708          case (TYPE_UBYTE):
709             v = (float)vec_ub[i*(dim) +j];
710             break;
711          case (TYPE_USHORT):
712             v = (float)vec_us[i*(dim) +j];
713             break;
714 
715          default:
716             DXSetError(ERROR_BAD_TYPE,"#10600","data type");
717                return ERROR;
718          }
719          min[j] = MIN(v, min[j]);
720          max[j] = MAX(v, max[j]);
721       }
722    }
723 
724    break;
725 
726    case CLASS_SCREEN:
727 
728    if (!DXGetScreenInfo((Screen)o, &oo, NULL,NULL))
729       return ERROR;
730    if (!vec_minmax(oo,dim,size,rank,min,max))
731       return ERROR;
732    break;
733 
734    case CLASS_XFORM:
735 
736    if (!DXGetXformInfo((Xform)o, &oo, NULL))
737       return ERROR;
738    if (!vec_minmax(oo,dim,size,rank,min,max))
739       return ERROR;
740    break;
741 
742    case CLASS_CLIPPED:
743 
744    if (!DXGetClippedInfo((Clipped)o, &oo, NULL))
745       return ERROR;
746    if (!vec_minmax(oo,dim,size,rank,min,max))
747       return ERROR;
748    break;
749 
750    case CLASS_GROUP:
751 
752    for (ig=0; (oo=DXGetEnumeratedMember((Group)o,ig,NULL)); ig++)
753       if (!vec_minmax(oo,dim,size,rank,min,max))
754          return ERROR;
755    break;
756 
757    default:
758       DXSetError(ERROR_BAD_TYPE,"#10190","object");
759       return ERROR;
760    }
761 
762 
763    return OK;
764 }
765 
766 static
constant_minmax(Array a,Type type,int dim,float * min,float * max)767 Error constant_minmax(Array a, Type type, int dim, float *min, float *max)
768 {
769    float *vec_f;
770    int *vec_i;
771    double *vec_d;
772    short *vec_s;
773    byte *vec_b;
774    uint *vec_ui;
775    ubyte *vec_ub;
776    ushort *vec_us;
777    int i;
778 
779         switch(type){
780            case (TYPE_FLOAT):
781            vec_f = (float *)DXAllocate(sizeof(float) *dim);
782               DXQueryConstantArray(a,NULL,vec_f);
783               for (i=0; i<dim; i++)
784                  min[i] = vec_f[i];
785 	      DXFree(vec_f);
786               break;
787            case (TYPE_INT):
788            vec_i = (int *)DXAllocate(sizeof(int) *dim);
789               DXQueryConstantArray(a,NULL,vec_i);
790               for (i=0; i<dim; i++)
791                  min[i] = vec_i[i];
792 	      DXFree(vec_i);
793               break;
794            case (TYPE_DOUBLE):
795            vec_d = (double *)DXAllocate(sizeof(double) *dim);
796               DXQueryConstantArray(a,NULL,vec_d);
797               for (i=0; i<dim; i++)
798                  min[i] = (double)vec_d[i];
799 	      DXFree(vec_d);
800               break;
801            case (TYPE_SHORT):
802            vec_s = (short *)DXAllocate(sizeof(short) *dim);
803               DXQueryConstantArray(a,NULL,vec_s);
804               for (i=0; i<dim; i++)
805                  min[i] = (double)vec_s[i];
806 	      DXFree(vec_s);
807               break;
808            case (TYPE_BYTE):
809            vec_b = (byte *)DXAllocate(sizeof(byte) *dim);
810               DXQueryConstantArray(a,NULL,vec_b);
811               for (i=0; i<dim; i++)
812                  min[i] = (double)vec_b[i];
813 	      DXFree(vec_b);
814               break;
815            case (TYPE_UINT):
816            vec_ui = (uint *)DXAllocate(sizeof(uint) *dim);
817               DXQueryConstantArray(a,NULL,vec_ui);
818               for (i=0; i<dim; i++)
819                  min[i] = (double)vec_ui[i];
820 	      DXFree(vec_ui);
821               break;
822            case (TYPE_USHORT):
823            vec_us = (ushort *)DXAllocate(sizeof(ushort) *dim);
824               DXQueryConstantArray(a,NULL,vec_us);
825               for (i=0; i<dim; i++)
826                  min[i] = (double)vec_us[i];
827 	      DXFree(vec_us);
828               break;
829            case (TYPE_UBYTE):
830            vec_ub = (ubyte *)DXAllocate(sizeof(ubyte) *dim);
831               DXQueryConstantArray(a,NULL,vec_ub);
832               for (i=0; i<dim; i++)
833                  min[i] = (double)vec_ub[i];
834 	      DXFree(vec_ub);
835               break;
836          default:
837             DXSetError(ERROR_BAD_TYPE,"#10600","data type");
838             return ERROR;
839 
840         }
841         DXWarning("constant min %g,%g,%g",min[0],min[1],min[2]);
842         for (i=0; i<dim; i++)
843            max[i] = min[i];
844 
845         return OK;
846 }
847 
848 static
vec_reset(float * min,float * max,int item,int dim,int offset,start_type start,float * value)849 Error vec_reset(float *min,float *max,int item,int dim,int offset, start_type start,float *value)
850 {
851    int i,j;
852 
853    if (item==1){
854       if (start==START_MINIMUM){
855           if (offset >= 0)
856               value[offset] = min[offset];
857           else {
858               for (j=0; j<dim; j++)
859                   value[j] = min[j];
860           }
861       }
862       else if (start==START_MIDPOINT) {
863 		  if (offset >= 0)
864 			  value[offset] = (max[offset] +min[offset])/2.0;
865 		  else{
866 			 for (j=0; j<dim; j++)
867 				value[j] = (max[j] +min[j])/2.0;
868 		  }
869       }
870       else {
871           if (offset >= 0)
872               value[offset] = max[offset];
873           else {
874               for (j=0; j<dim; j++)
875                   value[j] = max[j];
876           }
877       }
878       return OK;
879    }
880 
881    if (offset >= 0){
882       for (i=0; i<item; i++)
883             value[i*dim +offset] = i * ((max[offset]-min[offset])/(item-1))                  +min[offset];
884       return OK;
885    }
886    else{
887       for (i=0; i<item; i++){
888          for (j=0; j<dim; j++)
889             value[i*dim +j] = i * ((max[j]-min[j])/(item-1)) +min[j];
890       }
891       return OK;
892    }
893 }
894 
895 static
isthisint(float * val,int dim,int item)896 int isthisint(float *val,int dim,int item)
897 {
898    int i,j,notint=0;
899 
900    for (i=0; i<item; i++){
901      for (j=0; j<dim; j++){
902       if (val[i*dim +j] == (float)(int)val[i*dim +j])
903          ;
904       else{
905          notint=1;
906          break;
907       }
908      }
909      if (notint==1) break;
910    }
911    if (notint==1) return 0;
912    return 1;
913 }
914 
915 static
setoutput(float * val,int rank,int item,int dim,int isint,Object * out)916 Error setoutput(float *val,int rank,int item,int dim,int isint,Object *out)
917 {
918    int i;
919    int *ival;
920 
921    ival = NULL;
922    out[0] = NULL;
923    if (isint==1){
924       ival = DXAllocate(sizeof(int) * dim * item);
925       for (i=0; i<dim*item; i++)
926          ival[i]=val[i];
927       out[0] = (Object)DXNewArray(TYPE_INT, CATEGORY_REAL, rank,dim);
928       if (!out[0] || !DXAddArrayData((Array)out[0], 0, item, (Pointer)ival))
929          goto error;
930       DXFree(ival);
931    }
932    else{
933       out[0] = (Object)DXNewArray(TYPE_FLOAT, CATEGORY_REAL, rank,dim);
934       if (!out[0] || !DXAddArrayData((Array)out[0], 0, item, (Pointer)val))
935          goto error;
936    }
937    return OK;
938 
939 error:
940    if (ival) DXFree(ival);
941    if (out[0]) DXDelete((Object)out[0]);
942    out[0]=NULL;
943    return ERROR;
944 }
945 
946 static
IsInvalid(Object o,InvalidComponentHandle * ivh)947 Error IsInvalid(Object o, InvalidComponentHandle *ivh)
948 {
949    Array invalid;
950    char *attr;
951 
952    *ivh = NULL;
953    attr = DXGetString((String)DXGetComponentAttribute((Field)o,"data","dep"));
954    if (!strcmp(attr,"connections")){
955       invalid = (Array)DXGetComponentValue((Field)o,"invalid connections");
956       if (invalid){
957          *ivh = DXCreateInvalidComponentHandle((Object)o,NULL,"connections");
958          if (!*ivh)
959             return ERROR;
960       }
961    }
962    else{
963       invalid = (Array)DXGetComponentValue((Field)o,"invalid positions");
964       if (invalid){
965          *ivh = DXCreateInvalidComponentHandle((Object)o,NULL,"positions");
966          if (!*ivh)
967             return ERROR;
968       }
969    }
970    return OK;
971 }
972