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