/***********************************************************************/ /* 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" */ /***********************************************************************/ /* * Header: /usr/people/gresh/code/svs/src/dxmods/RCS/color.m,v 5.2 93/02/09 09:18:31 gresh Exp Locker: gresh * */ #include /*** MODULE: Color SHORTDESCRIPTION: Colors a field CATEGORY: Data Transformation INPUTS: input; field; NULL; field to color color; field or vector value or string; NULL; DXRGB color opacity; field or scalar; data dependent; opacity component; string; "colors"; component to color delayed; flag; 0; delay applying map OUTPUTS: colored; color field; NULL; color mapped input field FLAGS: BUGS: AUTHOR: dl gresh END: ***/ #include #include #include #include #include #include extern int _dxfIsImportedColorMap(Object, int *, Object *, Object *); extern int _dxfIsColorMap (Object); extern int _dxfFieldWithInformation (Object); extern Error _dxfBoundingBoxDiagonal (Object, float *); extern Error DXColorNameToRGB (char *, RGBColor *); extern int _dxfIsOpacityMap (Object); extern int _dxfIsVolume (Object, int *); extern Error _dxfColorRecurseToIndividual (Object, Object, Object, char *, int, int, int, int, RGBColor, float, int); Error m_Color(Object *in, Object *out) { Object color, opacity; Array onearray=NULL; RGBColor colorvec; float opacityval, minopacity, maxopacity; float minmap, maxmap, mindata, maxdata; char component[30], *tmpcomponent, *colorstr; char newstring[30]; int setcolor, setopacity, colorfield, opacityfield, i, count, byteflag; int immediate, delayed, one=1; Group g_out; color = NULL; g_out = NULL; opacity = NULL; setcolor = 0; setopacity = 0; opacityfield = 0; colorfield = 0; colorvec.r = 0; colorvec.g = 0; colorvec.b = 0; opacityval = 0; out[0] = in[0]; /* check for required input */ if (!in[0]) { /* input must be specified */ DXSetError(ERROR_MISSING_DATA,"#10000", "input"); goto error; } if (! _dxfFieldWithInformation(in[0])) return OK; if (! _dxfByteField((Object)in[0], &byteflag)) goto error; /* see whether we need to call DXMap on the "color" component */ setcolor = 1; if (!in[1]) setcolor = 0; /* what have we got for the color map? First see if it's a string */ else if (DXExtractString((Object)in[1], &colorstr)) { /* convert from string to DXRGB */ if (!DXColorNameToRGB(colorstr, &colorvec)) goto error; colorfield = 0; } /* if it's not a string, is it a vector color? */ else if (DXExtractParameter((Object)in[1], TYPE_FLOAT,3,1,(Pointer)&colorvec)) { colorfield = 0; } /* else is it the special kind of group map put out when you import a .cm file */ else if (!(_dxfIsImportedColorMap(in[1], &colorfield, &color, NULL))) { if (_dxfIsColorMap(in[1])) { colorfield = 1; color = in[1]; /* check once to see if data is within the map */ /* only check if the data is not byte */ if (!byteflag) { if (!DXStatistics((Object)in[1], "positions", &minmap, &maxmap, NULL, NULL)) { goto error; } if (!DXStatistics((Object)in[0], "data", &mindata, &maxdata, NULL, NULL)) { goto error; } if ((minmap > mindata)||(maxmap < maxdata)) { DXWarning("color map does not fully encompass data"); } } } else goto error; } /* now see if we have to map opacity */ setopacity = 0; opacityfield = 0; if (in[2]) { /* is it a simple float number? */ if (DXExtractFloat((Object)in[2], &opacityval)) { opacityfield = 0; if ((opacityval < 0.0)||(opacityval > 1.0)) { /* opacity must be between 0 and 1 */ DXSetError(ERROR_BAD_PARAMETER,"#10110","opacity", 0, 1); goto error; } setopacity = 1; } /* else is it the special kind of group map put out when you import a .cm file */ else if (!_dxfIsImportedColorMap(in[2], &opacityfield, NULL, &opacity)) { /* or is it an opacity map? */ if (_dxfIsOpacityMap(in[2])){ if (!(DXStatistics((Object)in[2],"data", &minopacity,&maxopacity,NULL,NULL))) goto error; if (minopacity < 0.0) { /* opacity must be between 0 and 1 */ DXSetError(ERROR_BAD_PARAMETER,"#10110","opacity", 0, 1); goto error; } if (minopacity==maxopacity) { if (minopacity == 1.0) { setopacity = 0; opacityfield = 0; } else { setopacity = 1; opacityfield = 0; opacityval = minopacity; } } else { opacityfield = 1; opacity = (Object)in[2]; setopacity = 1; /* check once to see if data is within the map */ if (!byteflag) { if (!DXStatistics((Object)in[2], "positions", &minmap, &maxmap, NULL, NULL)) { goto error; } if (!DXStatistics((Object)in[0], "data", &mindata, &maxdata, NULL, NULL)) { goto error; } if ((minmap > mindata)||(maxmap < maxdata)) { DXWarning("opacity map does not fully encompass data"); } } } } else goto error; } } /* now see what component to operate on */ if (!in[3]) { strcpy(component,"colors"); } else { if (DXExtractString((Object)in[3], &tmpcomponent)) { count = 0; i = 0; while ( i<29 && tmpcomponent[i] != '\0') { if (isalpha(tmpcomponent[i])){ if (isupper(tmpcomponent[i])) newstring[count]= tolower(tmpcomponent[i]); else newstring[count]= tmpcomponent[i]; count++; } i++; } newstring[count]='\0'; tmpcomponent = newstring; if (strcmp(tmpcomponent,"colors") && strcmp(tmpcomponent,"frontcolors") && strcmp(tmpcomponent,"backcolors")) { /* bad component name */ DXSetError(ERROR_BAD_PARAMETER, "#10210", tmpcomponent, "component"); goto error; } if (!strcmp(tmpcomponent,"frontcolors")) strcpy(component,"front colors"); if (!strcmp(tmpcomponent,"backcolors")) strcpy(component,"back colors"); if (!strcmp(tmpcomponent,"colors")) strcpy(component,"colors"); } else { /* component must be a string */ DXSetError(ERROR_BAD_PARAMETER,"#10200","component"); goto error; } } if (!(in[4])) { delayed = 0; } else { if (!DXExtractInteger(in[4],&delayed)) { DXSetError(ERROR_BAD_PARAMETER, "#10070", "delayed"); goto error; } if ((delayed != 0) && (delayed != 1)) { DXSetError(ERROR_BAD_PARAMETER, "#10070", "delayed"); goto error; } } if (delayed == 0) immediate = 1; if (delayed == 1) immediate = 0; /* now we are ready to operate on the structure */ if ((setcolor)||(setopacity)) { if (!(g_out = (Group)DXCopy(in[0], COPY_STRUCTURE))) { /* input must be a group or a field */ DXAddMessage("#10190","input"); goto error; } if (!DXCreateTaskGroup()) goto error; if (! _dxfColorRecurseToIndividual((Object)g_out, color, opacity, component, setcolor, setopacity, colorfield, opacityfield, colorvec, opacityval, immediate)) goto error; if (!DXExecuteTaskGroup()) goto error; out[0] = (Object)g_out; } /* for delayed colors, add the direct color map attribute */ if (delayed) { onearray = DXNewArray(TYPE_INT,CATEGORY_REAL, 0); if (!DXAddArrayData(onearray, 0, 1, &one)) goto error; if (!DXSetAttribute(out[0], "direct color map", onearray)) goto error; onearray = NULL; } return OK; error: DXDelete((Object)g_out); DXDelete((Object)onearray); out[0]= NULL; return ERROR; } int _dxfIsColorMap(Object ob) { Class cl; Object dp, pp; float *pos; Field part; int count; if (!(cl = DXGetObjectClass(ob))) { return ERROR; } if ( !(cl == CLASS_FIELD) && !(cl == CLASS_GROUP)) { DXSetError(ERROR_BAD_PARAMETER,"#10570","color"); return ERROR; } if (cl == CLASS_FIELD) { /* should have data and positions */ if ((!(dp=DXGetComponentValue((Field)ob,"data")))|| (!(pp=DXGetComponentValue((Field)ob,"positions")))) { DXSetError(ERROR_BAD_PARAMETER, "#10250", "color map", "data or positions"); return ERROR; } /* for a color map, should have shape 3 */ if (!DXTypeCheck((Array)dp, TYPE_FLOAT, CATEGORY_REAL, 1, 3)) { if (!DXQueryArrayConvert((Array)dp, TYPE_FLOAT, CATEGORY_REAL, 1, 3)) { DXSetError(ERROR_BAD_PARAMETER, "#10331","colormap data"); return ERROR; } } /* positions should be 1D */ if (!((DXTypeCheck((Array)pp, TYPE_FLOAT, CATEGORY_REAL, 1, 1)) || (DXTypeCheck((Array)pp, TYPE_FLOAT, CATEGORY_REAL, 0)))) { DXSetError(ERROR_BAD_PARAMETER,"#11130","color", "color"); return ERROR; } /* max should be greater than min */ pos = (float *)DXGetArrayData((Array)pp); if (!DXGetArrayInfo((Array)dp,&count,NULL,NULL,NULL,NULL)) return ERROR; if (pos[count-1] < pos[0]) { DXSetError(ERROR_BAD_PARAMETER, "#11220", "color map min", "color map max"); return ERROR; } } else { int i; for (i = 0; NULL != (part = DXGetPart(ob, i)); i++) if (! DXEmptyField(part)) break; if (part == NULL) { DXSetError(ERROR_BAD_PARAMETER, "#11819","color map"); return ERROR; } if ((!(dp=DXGetComponentValue((Field)part,"data")))|| (!(pp=DXGetComponentValue((Field)part,"positions")))) { DXSetError(ERROR_BAD_PARAMETER, "#10250", "color map", "data or positions"); return ERROR; } /* for a color map, should have shape 3 */ if (!DXTypeCheck((Array)dp, TYPE_FLOAT, CATEGORY_REAL, 1, 3)) { DXSetError(ERROR_BAD_PARAMETER, "#10331", "color map data component"); return ERROR; } /* positions should be 1D */ if (!((DXTypeCheck((Array)pp, TYPE_FLOAT, CATEGORY_REAL, 1, 1)) || (DXTypeCheck((Array)pp, TYPE_FLOAT, CATEGORY_REAL, 0)))) { DXSetError(ERROR_BAD_PARAMETER,"#11130","color","color"); return ERROR; } } return OK; } extern int _dxfIsOpacityMap(Object ob) { Class cl; Object dp, pp; Field part; float *pos; int count; if (!(cl = DXGetObjectClass(ob))) { return ERROR; } if (!(cl == CLASS_FIELD) && !(cl == CLASS_GROUP)) { DXSetError(ERROR_BAD_PARAMETER,"#10190","opacity map"); return ERROR; } if (cl == CLASS_FIELD) { /* should have data and positions */ if ((!(dp=DXGetComponentValue((Field)ob,"data")))|| (!(pp=DXGetComponentValue((Field)ob,"positions")))) { DXSetError(ERROR_BAD_PARAMETER, "#10250", "opacity map", "data or positions"); return ERROR; } /* for an opacity map, should have shape 1 */ if (!((DXTypeCheck((Array)dp, TYPE_FLOAT, CATEGORY_REAL, 1, 1)) || (DXTypeCheck((Array)dp, TYPE_FLOAT, CATEGORY_REAL, 0)))) if (!DXQueryArrayConvert((Array)dp, TYPE_FLOAT, CATEGORY_REAL, 1, 1)) { DXSetError(ERROR_BAD_PARAMETER,"#10332","opacity map"); return ERROR; } /* the positions should have shape 1 */ if (!((DXTypeCheck((Array)pp, TYPE_FLOAT, CATEGORY_REAL, 1, 1)) || (DXTypeCheck((Array)pp, TYPE_FLOAT, CATEGORY_REAL, 0)))) { DXSetError(ERROR_BAD_PARAMETER,"#11130","opacity","opacity"); return ERROR; } /* max should be greater than min */ pos = (float *)DXGetArrayData((Array)pp); if (!DXGetArrayInfo((Array)dp,&count,NULL,NULL,NULL,NULL)) return ERROR; if (pos[count-1] < pos[0]) { DXSetError(ERROR_BAD_PARAMETER, "#11220","opacity map min", "opacity map max"); return ERROR; } } else { int i; for (i = 0; NULL != (part = DXGetPart(ob, i)); i++) if (! DXEmptyField(part)) break; if (part == NULL) { DXSetError(ERROR_BAD_PARAMETER,"#11819","opacity map"); return ERROR; } if ((!(dp=DXGetComponentValue((Field)part,"data")))|| (!(pp=DXGetComponentValue((Field)part,"positions")))) { DXSetError(ERROR_BAD_PARAMETER, "#10250", "opacity map", "data or positions"); return ERROR; } /* for an opacity map, should have shape 1 */ if (!((DXTypeCheck((Array)dp, TYPE_FLOAT, CATEGORY_REAL, 1, 1)) || (DXTypeCheck((Array)dp, TYPE_FLOAT, CATEGORY_REAL, 0)))) { DXSetError(ERROR_BAD_PARAMETER, "#10332", "opacity map data component"); return ERROR; } /* the positions should have shape 1 */ if (!((DXTypeCheck((Array)pp, TYPE_FLOAT, CATEGORY_REAL, 1, 1)) || (DXTypeCheck((Array)pp, TYPE_FLOAT, CATEGORY_REAL, 0)))) { DXSetError(ERROR_BAD_PARAMETER, "#11130","opacity","opacity"); return ERROR; } } return OK; } extern int _dxfIsImportedColorMap(Object obj, int *isfield, Object *cmap, Object *omap) { Class class; Object member1=NULL, member2=NULL; int returnval; class = DXGetObjectClass(obj); if (class != CLASS_GROUP) return 0; member1 = DXGetMember((Group)obj,"colormap"); member2 = DXGetMember((Group)obj,"opacitymap"); if (member1 && member2) returnval = 1; else returnval = 0; if (cmap) { if (member1) { if (isfield) *isfield = 1; *cmap = member1; } } if (omap) { if (member2) { if (isfield) *isfield = 1; *omap = member2; } } return returnval; }