/***********************************************************************/ /* 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/autocolor.m,v 5.3 93/01/25 14:50:45 gresh Exp Locker: gresh */ #include /*** MODULE: AutoColor SHORTDESCRIPTION: Adds color and opacity information to data, to prepare it for rendering. CATEGORY: Data Transformation INPUTS: data; scalar field; NULL; field to color opacity; scalar; data dependent; opacity intensity; scalar; data dependent; color intensity start; scalar; 0.6666; starting color (default blue) range; scalar; 0.6666; range of color (default blue -> red) saturation; scalar; 1.00; saturation min; scalar or scalar field; data dependent; minimum of data to map max; scalar or scalar field; data dependent; maximum of data to map delayed; flag; 0; delay application of color and opacity maps OUTPUTS: mapped; color field; NULL; color mapped input field colormap; field; NULL; rgb color map used FLAGS: BUGS: AUTHOR: dl gresh END: ***/ #include #include #include extern Group _dxfAutoColor(Object, float, float, float, float, float, float *, float *, Object *, int, RGBColor, RGBColor); static int _dxfIsFieldorGroup(Object ob); extern int _dxfFieldWithInformation(Object); extern Error _dxfHSVtoRGB(float, float, float, float *, float *, float *); int m_AutoColor(Object *in, Object *out) { Group g_in; Array onearray=NULL; float opacity, intensity, phase, range, saturation; float inputmin, inputmax, r, g, b; float *inputminp=(&inputmin), *inputmaxp=(&inputmax); int used_object, delayed, i, count, one=1; Object colormap; char *colorstr, newstring[21]; RGBColor colorvecmin, colorvecmax; RGBColor cv[2]; /* at this point it is assumed that the input group g_in is a composite field (i.e. that all of the subfields are of a uniform type). */ if(!(g_in = (Group)in[0])) { out[0] = NULL; /* missing first parameter */ DXSetError(ERROR_MISSING_DATA, "#10000", "data"); return ERROR; } if (!(_dxfFieldWithInformation((Object)in[0]))) { out[0] = in[0]; out[1] = (Object)DXNewField(); return OK; } if (!in[1]) opacity = -1.0; else if (!DXExtractFloat((Object)in[1],&opacity)) { /* bad opacity input; must be a float between 0 and 1 */ DXSetError(ERROR_BAD_PARAMETER,"#10110", "opacity", 0, 1); return ERROR; } else if ((opacity < 0.0)||(opacity > 1.0)) { /* bad opacity input; must be a float between 0 and 1 */ DXSetError(ERROR_BAD_PARAMETER,"#10110", "opacity", 0, 1); return ERROR; } if (!in[2]) intensity = -1.0; else if (!DXExtractFloat((Object)in[2],&intensity)) { /* bad intensity input; must be a positive float */ DXSetError(ERROR_BAD_PARAMETER,"#10100", "intensity"); return ERROR; } else if (intensity < 0.0) { /* bad intensity input; must be a positive float */ DXSetError(ERROR_BAD_PARAMETER,"#10100", "intensity"); return ERROR; } if (!in[3]) phase = 0.6666; else if (!DXExtractFloat((Object)in[3],&phase)) { /* bad phase, must be a float */ DXSetError(ERROR_BAD_PARAMETER,"#10080", "start"); return ERROR; } if (!in[4]) range = 0.6666; else if (!DXExtractFloat((Object)in[4],&range)) { /* bad range, must be a float */ DXSetError(ERROR_BAD_PARAMETER,"#10080","range"); return ERROR; } range = -range; if (!in[5]) saturation = 1.0; else if (!DXExtractFloat((Object)in[5],&saturation)) { /* bad saturation, must be a float between 0 and 1 */ DXSetError(ERROR_BAD_PARAMETER,"#10110","saturation", 0, 1); return ERROR; } else if ((saturation < 0.0)||(saturation > 1.0)) { /* bad saturation input; must be a float between 0 and 1 */ DXSetError(ERROR_BAD_PARAMETER,"#10110", "saturation", 0, 1); return ERROR; } /* if in[6] is an object, and in[7] is null, then we want to make inputmax be the max of the object, rather than the normal default */ used_object = 0; if (!in[6]) inputminp = NULL; else if (!DXExtractFloat((Object)in[6],inputminp)) { if (_dxfIsFieldorGroup((Object)in[6])) { /* get max and min */ if (!DXStatistics((Object)in[6],"data",inputminp,inputmaxp, NULL,NULL)) { /* min must be a field or a scalar value */ DXAddMessage("min parameter"); return ERROR; } else used_object++; } else { /* min must be a field or a scalar value */ DXSetError(ERROR_BAD_PARAMETER,"#10520","min"); return ERROR; } } if (!in[7]) { if (!used_object) inputmaxp = NULL; /* implicit else, max was set above */ } else if (!DXExtractFloat((Object)in[7],inputmaxp)) { if (_dxfIsFieldorGroup((Object)in[7])) { if (!DXStatistics((Object)in[7],"data",NULL,inputmaxp,NULL, NULL)) { /* max must be a field or a scalar value */ DXAddMessage("max parameter"); return ERROR; } } else { /* max must be a field or a scalar value */ DXSetError(ERROR_BAD_PARAMETER,"#10520", "max"); return ERROR; } } if (!in[8]) delayed = 0; else { if (!(DXExtractInteger(in[8],&delayed))) { DXSetError(ERROR_BAD_PARAMETER, "#10070", "delayed"); return ERROR; } if ((delayed != 0)&&(delayed != 1)) { DXSetError(ERROR_BAD_PARAMETER, "#10070", "delayed"); return ERROR; } } if (!in[9]) { colorvecmin = DXRGB(0.3, 0.3, 0.3); colorvecmax = DXRGB(0.3, 0.3, 0.3); } /* first try a string */ else if (DXExtractNthString(in[9], 0, &colorstr)) { /* is it a valid color name? */ if (!(DXColorNameToRGB(colorstr, &colorvecmin))) { /* if it's not a valid colorname, is it "min" or "max"? */ count = 0; i=0; while (i<20 && colorstr[i] != '\0') { for (i=0; i< 20; i++) { if (isalpha(colorstr[i])) { newstring[count]=tolower(colorstr[i]); count++; } else { if (colorstr[i] != ' ') { newstring[count] = colorstr[i]; count++; } } } } if (!strcmp(newstring, "colorofmin")) { DXResetError(); if (intensity != -1) _dxfHSVtoRGB(phase, saturation, intensity, &r, &g, &b); else _dxfHSVtoRGB(phase, saturation, 1.0, &r, &g, &b); colorvecmin = DXRGB(r,g,b); } else if (!strcmp(newstring,"colorofmax")) { DXResetError(); if (intensity != -1) _dxfHSVtoRGB(phase+range, saturation, intensity, &r, &g, &b); else _dxfHSVtoRGB(phase+range, saturation, 1.0, &r, &g, &b); colorvecmin = DXRGB(r,g,b); } else goto error; } /* start by setting max = min */ colorvecmax=colorvecmin; /* now look and see if there's a second string hanging around */ if (DXExtractNthString(in[9], 1, &colorstr)) { /* is it a valid color name? */ if (!(DXColorNameToRGB(colorstr, &colorvecmax))) { /* if it's not a valid colorname, is it "min" or "max"? */ count = 0; i=0; while (i<20 && colorstr[i] != '\0') { for (i=0; i< 20; i++) { if (isalpha(colorstr[i])) { newstring[count]=tolower(colorstr[i]); count++; } else { if (colorstr[i] != ' ') { newstring[count] = colorstr[i]; count++; } } } } if (!strcmp(newstring, "colorofmin")) { DXResetError(); if (intensity != -1) _dxfHSVtoRGB(phase, saturation, intensity, &r, &g, &b); else _dxfHSVtoRGB(phase, saturation, 1.0, &r, &g, &b); colorvecmax = DXRGB(r,g,b); } else if (!strcmp(newstring,"colorofmax")) { DXResetError(); if (intensity != -1) _dxfHSVtoRGB(phase+range, saturation, intensity, &r, &g, &b); else _dxfHSVtoRGB(phase+range, saturation, 1.0, &r, &g, &b); colorvecmax = DXRGB(r,g,b); } else goto error; } } } else if ((DXExtractParameter(in[9], TYPE_FLOAT, 3, 1, (Pointer)&colorvecmin))) { colorvecmax = colorvecmin; } else if ((DXExtractParameter(in[9], TYPE_FLOAT, 3, 2, (Pointer)&cv))) { colorvecmin = cv[0]; colorvecmax = cv[1]; } else { DXSetError(ERROR_BAD_PARAMETER, "outofrange must be a color string or pair of color strings, \"color of min\" or \"color of max\", or a 3-vector or pair of 3 vectors"); goto error; } out[0] = (Object)_dxfAutoColor((Object)g_in, opacity, intensity, phase, range, saturation, inputminp, inputmaxp, &colormap, delayed, colorvecmin, colorvecmax); if (out[0]) out[1] = (Object)colormap; /* for delayed colors, add the direct color map attribute */ if (delayed && out[0]) { 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; } if ((!out[0])||(!(out[1]))) return ERROR; else return OK; error: DXDelete((Object)onearray); return ERROR; } static int _dxfIsFieldorGroup(Object ob) { Class cl; if ( ((cl = DXGetObjectClass(ob)) == CLASS_FIELD) || (cl == CLASS_GROUP) ) return OK; else return ERROR; }