/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include #include #include "interact.h" #define NUMBINS 20 extern Error _dxfnewvalue(float *,float ,float , float , float ,int ,int *); extern Field _dxfMakeRGBColorMap(Field); extern Object _dxfHistogram(Object o, int bins, float *min, float *max, int inout); extern Array DXScalarConvert(Array ); extern int _dxfRGBtoHSV(float, float, float, float *, float *, float *); extern Error _dxfcontrol_to_rgb(Object in0,Object in1,Object in2, Field *rgb); extern Error _dxfcontrol_to_o(Object in0,Field *op); extern Field _dxfcolorfield(float *, float *,int ,int); static Object gethistogram(Object ,int ,int ,float *,float *); static Error vect_scalar(Object ); static Error makescalar(Object); static Error opacity_to_o(Object opacity,Field *out); static Error print_map(Field f,char *component,char *name, char *id); static Error scale_output(float *min,float *max,Field *rgb,Field *op,int ip[]); static Error hsvo_to_rgb_and_op(Object in0,Object in1,Object in2,Object in3, Field *rgb,Field *opacity); static Error colormap_to_rgb(Object inmap,Field *outmap); static Error hsvo_to_cp_component(Field *f,float *pts,float *data,int num, int isvec); static Error getui_minmax(Object o,float *min, float *max); static int match_cpoints(Field inmap,Object defmap,int which); static Error hsv_to_rgbfield(Object inmap,Field *rgb); typedef struct map { float level; float value; } Map; typedef struct hsvo { Map *map; char *name; int count; int minmax; } HSVO; static Error array_to_float(Array a,float *data,Type type,int num); static Error addarray(Field *f,Map *map,int items,char *component); extern Field _dxfeditor_to_hsv(Array huemap,Array satmap,Array valmap); extern Field _dxfeditor_to_opacity(Array map); int m_Colormap(Object *in,Field *out) { struct einfo ei; int change1=0,change4,change5,change=0,changecmap,changeomap; float min,max,old_min=0,old_max=100,minmax[2]; float defmin,defmax; /*default min and max */ Object idobj,histogram,color=NULL,opacity=NULL; char *id, *label; int *histo_pts,nhist; int i,iprint[MAXPRINT],msglen=0,shape[1]; int no_input=0,outlier=1,old_version=0; int min_input=0,max_input=0,longmessage=0; char begin[] = "begin", end[] = "end"; Field rgb_output,op_output; Array histo_array; if (!in[5] && !in[6] && !in[7]){ no_input=1; } out[0] = NULL; out[1] = NULL; ei.msgbuf = NULL; histogram = NULL; rgb_output = NULL; op_output = NULL; histo_array = NULL; /* get id */ if (!DXExtractString(in[4],&id)){ DXSetError(ERROR_BAD_PARAMETER,"#10000","id"); goto error; } idobj=in[4]; /* initialize iprint */ for (i=0; i 0 || change4 > 0 || change5 > 0)){ change=1; if (in[5]){ if (!DXStatistics(in[5], "data", &min, &max, NULL, NULL)) return ERROR; min_input=1; max_input=1; iprint[0]=1; iprint[1]=1; } if (in[6]){ if (!DXExtractFloat(in[6], &min)){ DXSetError(ERROR_BAD_PARAMETER,"#10080","min"); goto error; } min_input=1; iprint[0]=1; } if (in[7]){ if (!DXExtractFloat(in[7], &max)){ DXSetError(ERROR_BAD_PARAMETER,"#10080","max"); goto error; } max_input=1; iprint[1]=1; } /* Print warning if max 0){ if (DXGetObjectClass(in[9])==CLASS_GROUP){ if (!(color = DXGetMember((Group)in[9],"colormap")) || !DXGetMember((Group)in[9],"opacitymap")){ DXSetError(ERROR_BAD_PARAMETER,"#10371","color","colormap", "or imported cm file"); goto error; } } else color = in[9]; if (DXGetObjectClass(color)==CLASS_GROUP){ DXSetError(ERROR_BAD_PARAMETER,"colormap can't be group"); goto error1; } if (_dxfIsColorMap(color)){ if (!colormap_to_rgb(color,&rgb_output)) goto error1; } /* if no rgb colorfield but just hue, sat, val positions */ /* treat like control points were input */ else if (DXGetComponentValue((Field)color,"hue positions") || DXGetComponentValue((Field)color,"sat positions") || DXGetComponentValue((Field)color,"val positions") ){ DXResetError(); if (!hsv_to_rgbfield(color,&rgb_output)) goto error1; } else goto error; /* if this is first time and default matches input use first 4 inputs */ if (changecmap == 2) { if (match_cpoints(rgb_output,in[12],1) && match_cpoints(rgb_output,in[13],2) && match_cpoints(rgb_output,in[14],3)){ DXDelete((Object)rgb_output); rgb_output=NULL; changecmap=0; if (!_dxfcontrol_to_rgb(in[0],in[1],in[2],&rgb_output)) goto error1; } } } else{ /* read data from the UI Colormap editor * control points (4 2-vector floats) DXVersion 2.1 and on * hsv triples for backward compatibility */ if (DXQueryParameter(in[0],TYPE_FLOAT,0,&i)){ if(!hsvo_to_rgb_and_op(in[0],in[1],in[2],in[3],&rgb_output,&op_output)) goto error1; old_version=1; } else{ if (!_dxfcontrol_to_rgb(in[0],in[1],in[2],&rgb_output)) goto error1; } } /* check for opacity map input */ changeomap = _dxfcheck_obj_cache(in[10],id,10,idobj); if (in[10] && changeomap > 0) if (DXGetObjectClass(in[10])==CLASS_GROUP){ if (!DXGetMember((Group)in[10],"colormap") || !(opacity = DXGetMember((Group)in[10],"opacitymap"))){ DXSetError(ERROR_BAD_PARAMETER,"#10371","opacity","opacitymap", "or imported cm file"); goto error; } } else opacity = in[10]; if (opacity){ if (DXGetObjectClass(opacity)==CLASS_GROUP){ DXSetError(ERROR_BAD_PARAMETER,"opacity map must be field"); goto error; } if (_dxfIsOpacityMap(opacity)){ if (!opacity_to_o(opacity,&op_output)) goto error1; } else goto error; /* if this is first time and default matches input use first 4 inputs */ if (changeomap == 2) { if (match_cpoints(op_output,in[15],4)){ DXDelete((Object)op_output); op_output=NULL; changeomap = 0; if (!_dxfcontrol_to_o(in[3],&op_output)) goto error1; } } } else{ if (!old_version){ if (!_dxfcontrol_to_o(in[3],&op_output)) goto error1; } } /* if min and max were not input then use UI min and max */ /* or if it is the first time executing this net */ if (!max_input || !min_input || change1 == 2){ if (!old_version){ if (!DXExtractParameter(in[11],TYPE_FLOAT,0,2,minmax)){ DXSetError(ERROR_INTERNAL,"minmax from UI wrong"); goto error; } } else{ if (!getui_minmax(in[0],&minmax[0],&minmax[1])) goto error; } if (change1 == 2){ /* if first time */ if (in[16]){ if (!DXExtractFloat(in[16], &defmin)){ DXSetError(ERROR_INTERNAL,"#10080","defmin"); goto error; } if (min == defmin){ /* defaults match use uimin*/ min = minmax[0]; iprint[0]=0; } } if (in[17]){ if (!DXExtractFloat(in[17], &defmax)){ DXSetError(ERROR_INTERNAL,"#10080","defmax"); goto error; } if (max == defmax){ /* defaults match use uimax*/ max = minmax[1]; iprint[1]=0; } } } else{ if (!min_input) min = minmax[0]; if (!max_input) max = minmax[1]; } } /* get label */ change5 = _dxfcheck_obj_cache(in[18],id,8,idobj); if (change5 > 0) iprint[5]=1; if (in[18]){ if (!DXExtractString(in[18], &label)){ DXSetError(ERROR_BAD_PARAMETER,"#10200","label"); goto error; } } else label=""; /* cache inputs (min,max,label) and return old min and max */ /* if (!_dxfinteract_float(id,idobj,&min,&max, NULL,NULL,label,0,0,&nhist,iprint)) return ERROR; */ /* scale the output according to the new min and max */ if (!scale_output(&min,&max,&rgb_output,&op_output,iprint)) goto error1; /* calculate histogram */ if (in[5] && nhist>1 && (change || iprint[6])){ if (in[6] || in[7]) outlier = 0; if (!(histogram = gethistogram(in[5],nhist,outlier,&min,&max))) goto error1; histo_array = (Array)DXGetComponentValue((Field)histogram,"data"); histo_pts = (int *)DXGetArrayData(histo_array); iprint[4]=1; } /* calculate the size of the first UI message */ if (iprint[4] == 1) msglen += (nhist*NUMBER_CHARS); for (i=0; i MAX_MSGLEN){ DXSetError(ERROR_INVALID_DATA,"#10920"); goto error1; } /* check if more the one line message */ if (changecmap > 0 || changeomap > 0 || (iprint[5]==1 && strlen(label)>0) || strcmp(ei.msgbuf,"")) longmessage=1; /* if colormap exists and has changed send control points and * data points in long message */ if (longmessage) DXUIMessage(id,begin); if (strcmp(ei.msgbuf,"")) DXUIMessage(id,ei.msgbuf); if (iprint[5]==1 && strlen(label)>0){ if (ei.msgbuf) DXFree((Pointer)ei.msgbuf); ei.msgbuf=NULL; ei.maxlen =(int)strlen(label); ei.atend = 0; ei.msgbuf = (char *)DXAllocateZero(ei.maxlen+SLOP); if (!ei.msgbuf) return ERROR; ei.mp = ei.msgbuf; sprintf(ei.mp, "title=%s",label); DXUIMessage(id,ei.msgbuf); } if (changecmap > 0 || changeomap > 0){ if (in[9] && changecmap > 0){ if (!print_map(rgb_output,"hue positions","huemap=",id)) goto error1; if (!print_map(rgb_output,"sat positions","satmap=",id)) goto error1; if (!print_map(rgb_output,"val positions","valmap=",id)) goto error1; } else if (!in[9] && changecmap > 0){ if (!print_map(NULL,"hue positions","huemap=",id)) goto error1; if (!print_map(NULL,"sat positions","satmap=",id)) goto error1; if (!print_map(NULL,"val positions","valmap=",id)) goto error1; } if (in[10] && changeomap > 0){ if (!print_map(op_output,"opacity positions","opmap=",id)) goto error1; } else if (!in[10] && changeomap > 0){ if (!print_map(NULL,"opacity positions","opmap=",id)) goto error1; } } if (longmessage) DXUIMessage(id,end); out[0] = (Field)rgb_output; out[1] = (Field)op_output; if (ei.msgbuf) DXFree((Pointer)ei.msgbuf); if (histogram) DXDelete((Object)histogram); return OK; error: error1: if (histogram) DXDelete((Object)histogram); if (ei.msgbuf) DXFree((Pointer)ei.msgbuf); if (rgb_output) DXDelete((Object)rgb_output); if (op_output) DXDelete((Object)op_output); change1 = _dxfcheck_obj_cache(in[6],id,0,idobj); changeomap = _dxfcheck_obj_cache(in[6],id,10,idobj); changecmap = _dxfcheck_obj_cache(in[6],id,9,idobj); return ERROR; } /* to handle backwards compatibility the UI inputs could be * hsv_triples,hsv_pts,op_data,op_pts * the output is rgb field with control points component * and opacity field with control points component */ static Error hsvo_to_rgb_and_op(Object in0,Object in1,Object in2,Object in3, Field *rgb,Field *opacity) { float *hsv_pts,*hsv_data,*op_pts,*op_data; int num_hsv,num_op; Field hsv; Array a,b; hsv_pts = NULL; hsv_data = NULL; op_pts = NULL; op_data = NULL; hsv = NULL; /* read in the arrays and create a HSV Field */ if (!DXQueryParameter(in0,TYPE_FLOAT,0,&num_hsv)){ DXSetError(ERROR_INTERNAL,"hsv points must be scalar"); goto error; } hsv = (Field)_dxfcolorfield(NULL,NULL,num_hsv,1); if (!hsv) goto error; a = (Array)DXGetComponentValue((Field)hsv,"positions"); b = (Array)DXGetComponentValue((Field)hsv, "data"); hsv_pts = (float *)DXGetArrayData(a); hsv_data = (float *)DXGetArrayData(b); if (!DXExtractParameter(in0,TYPE_FLOAT,0,num_hsv,hsv_pts)){ DXSetError(ERROR_INTERNAL,"hsv pts"); goto error; } if (!DXExtractParameter(in1,TYPE_FLOAT,3,num_hsv,hsv_data)){ DXSetError(ERROR_INTERNAL,"hsv_data"); goto error; } if (!DXQueryParameter(in2,TYPE_FLOAT,0,&num_op)){ DXSetError(ERROR_INTERNAL,"op points must be scalar"); goto error; } *opacity = (Field)_dxfcolorfield(NULL,NULL,num_op,0); if (!*opacity) goto error; a = (Array)DXGetComponentValue((Field)*opacity,"positions"); b = (Array)DXGetComponentValue((Field)*opacity, "data"); op_pts = (float *)DXGetArrayData(a); op_data = (float *)DXGetArrayData(b); if (!DXExtractParameter(in2,TYPE_FLOAT,0,num_op,op_pts)){ DXSetError(ERROR_INTERNAL,"op pts"); goto error; } if (!DXExtractParameter(in3,TYPE_FLOAT,0,num_op,op_data)){ DXSetError(ERROR_INTERNAL,"op_data"); goto error; } /* convert to an RGB Field */ *rgb = _dxfMakeRGBColorMap((Field)hsv); if (!*rgb) goto error; /* convert hsv data to control pt arrays */ /* add the control point components to the fields */ if (!hsvo_to_cp_component(rgb,hsv_pts,hsv_data,num_hsv,1)) goto error; if (!hsvo_to_cp_component(opacity,op_pts,op_data,num_op,0)) goto error; DXDelete((Object)hsv); return OK; error: if (hsv) DXDelete((Object)hsv); return NULL; } /* Convert control points to HSV space (editor_to_hsv) * and convert to RGB with control points */ extern Error _dxfcontrol_to_rgb(Object huemap,Object satmap,Object valmap, Field *rgb) { Field hsv; int num_hue,num_sat,num_val; int n,items; Map *map; Array a[3]; for (n=0; n<3; n++) a[n]=NULL; /* read the control point lists and create arrays */ if (huemap){ if (!DXQueryParameter((Object)huemap,TYPE_FLOAT,2,&items)){ DXSetError(ERROR_INTERNAL,"hue map must be 2-vector floats"); goto error; } a[0] = DXNewArray(TYPE_FLOAT,CATEGORY_REAL,1,2); if (!a[0]) return ERROR; if (!DXAddArrayData(a[0],0,items,NULL)) goto error; map = (Map *)DXGetArrayData(a[0]); if(!DXExtractParameter((Object)huemap,TYPE_FLOAT,2,items,(Pointer)map)){ DXSetError(ERROR_INTERNAL,"can't read hue control points"); goto error; } } if (satmap){ if (!DXQueryParameter((Object)satmap,TYPE_FLOAT,2,&items)){ DXSetError(ERROR_INTERNAL,"sat map must be 2-vector floats"); goto error; } a[1] = DXNewArray(TYPE_FLOAT,CATEGORY_REAL,1,2); if (!a[1]) return ERROR; if (!DXAddArrayData(a[1],0,items,NULL)) goto error; map = (Map *)DXGetArrayData(a[1]); if (!DXExtractParameter((Object)satmap,TYPE_FLOAT,2,items,(Pointer)map)){ DXSetError(ERROR_INTERNAL,"can't read sat control points"); goto error; } } if(valmap){ if (!DXQueryParameter((Object)valmap,TYPE_FLOAT,2,&items)){ DXSetError(ERROR_INTERNAL,"val map must be 2-vector floats"); goto error; } a[2] = DXNewArray(TYPE_FLOAT,CATEGORY_REAL,1,2); if (!a[2]) return ERROR; if (!DXAddArrayData(a[2],0,items,NULL)) goto error; map = (Map *)DXGetArrayData(a[2]); if (!DXExtractParameter((Object)valmap,TYPE_FLOAT,2,items,(Pointer)map)){ DXSetError(ERROR_INTERNAL,"can't read val control points"); goto error; } } hsv = (Field)_dxfeditor_to_hsv(a[0],a[1],a[2]); if(!hsv) goto error; *rgb = (Field)_dxfMakeRGBColorMap((Field)hsv); DXDelete((Object)hsv); if (!*rgb) return ERROR; /* add the control points */ if (!DXSetComponentValue(*rgb,"hue positions",(Object)a[0])) goto error; if (!DXSetComponentValue(*rgb,"sat positions",(Object)a[1])) goto error; if (!DXSetComponentValue(*rgb,"val positions",(Object)a[2])) goto error; for (n=0; n<3; n++) a[n]=NULL; if (!DXEndField(*rgb)) goto error; return OK; error: for(n=0; n<3; n++) if (a[n]) DXDelete((Object)a[n]); return ERROR; } /* convert opacity control points to opacity field */ extern Error _dxfcontrol_to_o(Object opmap,Field *opacity) { float *op_data,*op_pts; Map *op; int i,num_op; Array a,b,c=NULL; op = NULL; op_data = NULL; op_pts = NULL; if(opmap){ if (!DXQueryParameter(opmap,TYPE_FLOAT,2,&num_op)){ DXSetError(ERROR_INTERNAL,"op map must be 2-vector floats"); goto error; } c = DXNewArray(TYPE_FLOAT,CATEGORY_REAL,1,2); if (!c) return ERROR; if (!DXAddArrayData(c,0,num_op,NULL)) goto error; op = (Map *)DXGetArrayData(c); if (!DXExtractParameter(opmap,TYPE_FLOAT,2,num_op,(Pointer)op)){ DXSetError(ERROR_INTERNAL,"can't read op control points"); goto error; } } /* get the opacity field */ *opacity = (Field)_dxfeditor_to_opacity((Array)c); if (!*opacity) goto error; /* separate into positions and data and create a field */ /* *opacity = (Field)_dxfcolorfield(NULL,NULL,num_op,0); a = (Array)DXGetComponentValue((Field)*opacity,"positions"); b = (Array)DXGetComponentValue((Field)*opacity,"data"); op_pts = (float *)DXGetArrayData(a); op_data = (float *)DXGetArrayData(b); for (i=0; i MAX_MSGLEN){ DXSetError(ERROR_INVALID_DATA,"#10920"); goto error; } DXUIMessage(id,ei.msgbuf); DXFree(ei.msgbuf); return OK; error: if (ei.msgbuf) DXFree(ei.msgbuf); return ERROR; } /* for old version need to get the UI min and max from the points * input (the first and last were alway the min and max before) */ static Error getui_minmax(Object o,float *min, float *max) { float *pts; int num; pts = NULL; /* read the point lists */ if (!DXQueryParameter((Object)o,TYPE_FLOAT,0,&num)){ DXSetError(ERROR_INTERNAL,"pts scalar floats"); goto error; } pts = (float *)DXAllocate(sizeof(float) * num); if (!DXExtractParameter((Object)o,TYPE_FLOAT,0,num,(Pointer)pts)){ DXSetError(ERROR_INTERNAL,"can't read points"); goto error; } *min = pts[0]; *max = pts[num-1]; DXFree((Pointer)pts); return OK; error: if (pts) DXFree((Pointer)pts); return ERROR; } static Object gethistogram(Object o,int nbins,int outl,float *min,float *max) { int i, items,rank; Array a; int *p; Type t; Object histogram,newo; int *localPts; Class class,classg; /* Copy object so can change to scalar */ newo = DXCopy(o,COPY_STRUCTURE); /* make sure group is right type */ class = DXGetObjectClass((Object)newo); if (class==CLASS_GROUP){ classg = DXGetGroupClass((Group)newo); if (classg!=CLASS_MULTIGRID && classg!=CLASS_SERIES && classg!=CLASS_COMPOSITEFIELD){ DXSetError(ERROR_BAD_PARAMETER,"group must be multigrid,or series"); goto error; } } /* if data type is vector need to get magnitude */ if (!DXGetType(newo,NULL,NULL,&rank,NULL)){ DXSetError(ERROR_INTERNAL,"there is no type"); goto error; } if (rank>0){ if (!vect_scalar(newo)) goto error; } histogram = (Object)_dxfHistogram(newo,nbins,min,max,outl); /* if (!histogram) return ERROR; if ((class=DXGetObjectClass(histogram))==CLASS_FIELD){ a = (Array)DXGetComponentValue((Field)histogram,"data"); if (!DXGetArrayInfo(a,&items,&t, NULL,NULL,NULL)) return ERROR; p = (int *)DXGetArrayData(a); *pts = localPts = (int *)DXAllocate(sizeof(int) *items); for (i=0; i