/*ScianVisObjects.c May 28, 1991 Eric Pepke Visualization objects in SciAn*/ #include "Scian.h" #include "ScianTypes.h" #include "ScianArrays.h" #include "ScianWindows.h" #include "ScianTextBoxes.h" #include "ScianButtons.h" #include "ScianTitleBoxes.h" #include "ScianObjWindows.h" #include "ScianIcons.h" #include "ScianColors.h" #include "ScianControls.h" #include "ScianLists.h" #include "ScianSpaces.h" #include "ScianLights.h" #include "ScianSliders.h" #include "ScianIDs.h" #include "ScianVisWindows.h" #include "ScianDatasets.h" #include "ScianPictures.h" #include "ScianDialogs.h" #include "ScianEvents.h" #include "ScianScripts.h" #include "ScianErrors.h" #include "ScianComplexControls.h" #include "ScianMethods.h" #include "ScianStyle.h" #include "ScianVisObjects.h" #include "ScianVisIso.h" #include "ScianVisContours.h" #include "ScianVisTraces.h" #include "ScianVisPoints.h" #include "ScianVisSticks.h" #include "ScianVisNumbers.h" #include "ScianFilters.h" #include "ScianDraw.h" #include "ScianObjFunctions.h" #include "ScianTemplates.h" #include "ScianTemplateHelper.h" #include "ScianSymbols.h" #include "ScianGeometry.h" #include "ScianScales.h" #include "ScianFontSystem.h" #include "ScianSnap.h" #include "ScianFixedClasses.h" #include "ScianVisStreams.h" #define AXISFACTOR 0.15 /*Factor of MAXSIZE to move axis name*/ #define MAJORTICSIZE 0.05 /*Size of major tics*/ #define LABELFACTOR 2.0 /*Offset of label*/ #define MINORTICFACTOR 0.6 /*Size of minor tics*/ #define BOUNDSEXPFACTOR 0.05 /*Factor to expand bounds for big bounds*/ ObjPtr visClass; /*Class for all visualization objects*/ ObjPtr visBounded; /*Class for all bounded vis objects*/ ObjPtr visAxes; /*Class for all vis objects that can draw axes*/ ObjPtr visWalls; /*Class for all vis objects that have walls*/ ObjPtr visSurface; /*Class for all objects w/surface*/ ObjPtr visDeformed; /*Class for all objects w/deformed surface*/ ObjPtr visColored; /*Class for all objects colored*/ ObjPtr visGeometryClass; /*Class for all objects with geometry*/ ObjPtr geoPictureClass; /*Class for geometry picture*/ ObjPtr visIcon; /*Icon for vis object*/ ObjPtr visLines; /*Class for all objects w/lines*/ ObjPtr visDots; /*Class for all objects w/dots*/ ObjPtr visSized; /*Class for sizable object*/ Bool drawSolid = false; /*True iff we want to draw solid*/ real globalFactor, globalOffset, globalFixed; ObjPtr globalDeformObject; extern ObjPtr perspecControlClass; /*Perspective control*/ extern real spaceTime; ObjPtr allVisObjClasses; /*Outline box values*/ #define OB_NONE 0 #define OB_LINES 1 #define OB_FRAME 2 #define OB_GIRDERS 3 #define OB_CYLINDERS 4 /*Mapping from data to visualization techniques*/ typedef struct { long dataInfo; /*Info bits of the data*/ int topDim; /*Topological dimension of the data iff HAS_FORM, -1 for don't care*/ int spatialDim; /*Spacial dimension of the data iff HAS_FORM, -1 for don't care*/ int nComponents; /*N components of the data, -1 for don't care.*/ ObjPtr visClass; } VisMapping; #define MAXNVISMAPPINGS 200 /*Maximum number of visualization maps*/ int nVisMappings = 0; /*Actual number of visualization maps*/ VisMapping visMapping[MAXNVISMAPPINGS]; /*Serial number generator for visualization types*/ typedef struct { char *name; int regSerial; int tempSerial; } VisSerial; #define MAXNVISSERIALS 100 int nVisSerials = 0; VisSerial visSerials[MAXNVISSERIALS]; /*Internal prototypes*/ #ifdef HAVE_PROTOTYPES static Bool GetTicParams(ObjPtr object, real lowTic[3], int nTics[3], real ticSpace[3], int initMinor[3], int majorEvery[3]); #endif static float material[30]; /*Random material*/ void SetupDeformation(object) ObjPtr object; /*Sets up to do deformation based on object*/ { ObjPtr var; /*Get factor and offset*/ var = GetVar(object, DEFFACTOR); if (var) { globalFactor = GetReal(var); } else { globalFactor = 1.0; } var = GetVar(object, DEFOFFSET); if (var) { globalOffset = GetReal(var); } else { globalOffset = 0.0; } globalDeformObject = GetVar(object, DEFORMOBJ); /*Make it deformed or not according to DEFORMSWITCH and DEFORMOBJ*/ MakeVar(object, DEFORMSWITCH); if (!GetPredicate(object, DEFORMSWITCH)) { globalDeformObject = NULLOBJ; } if (globalDeformObject) { SetCurField(DEFORMFIELD, globalDeformObject); SetCurForm(DEFORMFORM, globalDeformObject); } var = GetVar(object, DEFCONSTANT); if (var) { globalFixed = GetReal(var); } else { globalFixed = 0.0; } } int FindVisSerial(name) char *name; /*Finds a vis serial, returns it or -1*/ { int retVal; for (retVal = 0; retVal < nVisSerials; ++retVal) { char *s1, *s2; /*See if the name maps onto the first part of the object name*/ s1 = visSerials[retVal] . name; s2 = name; while (*s1) { if (toupper(*s1) != toupper(*s2)) break; ++s1; ++s2; } if (!(*s1)) { return retVal; } } return -1; } void DefineVisMapping(dataInfo, topDim, spatialDim, nComponents, visClass) long dataInfo; int topDim, spatialDim, nComponents; ObjPtr visClass; /*Defines a mapping from a dataset class to a visualization class. The first such mapping for a certain dataClass defines the preferred one.*/ { ObjPtr var; visMapping[nVisMappings] . dataInfo = dataInfo; visMapping[nVisMappings] . topDim = topDim; visMapping[nVisMappings] . spatialDim = spatialDim; visMapping[nVisMappings] . nComponents = nComponents; visMapping[nVisMappings] . visClass = visClass; ++nVisMappings; if (WhichListIndex(allVisObjClasses, visClass) < 0) { PostfixList(allVisObjClasses, visClass); } /*See if it needs a new serial record*/ var = GetVar(visClass, NAME); if (var) { if (FindVisSerial(GetString(var)) < 0) { /*Need a new one*/ visSerials[nVisSerials] . name = Alloc(strlen(GetString(var)) + 1); strcpy(visSerials[nVisSerials] . name, GetString(var)); visSerials[nVisSerials] . regSerial = 0; visSerials[nVisSerials] . tempSerial = 0; ++nVisSerials; } } } static ObjPtr MakeVisName(vis) ObjPtr vis; /*Makes the name of a visualization object*/ { Bool templatep; int visSerial; ObjPtr var; char *name; templatep = GetPredicate(vis, TEMPLATEP); var = GetVar(vis, NAME); if (var) { name = GetString(var); } else { name = "Visualization"; } visSerial = FindVisSerial(name); if (visSerial >= 0) { if (templatep) { sprintf(tempStr, "%s Template %d", visSerials[visSerial] . name, ++(visSerials[visSerial] . tempSerial)); } else { sprintf(tempStr, "%s %d", visSerials[visSerial] . name, ++(visSerials[visSerial] . regSerial)); } SetVar(vis, NAME, NewString(tempStr)); } return ObjTrue; } #ifdef HAVE_PROTOTYPES ObjPtr GetAllVis(ObjPtr dataset, Bool justOne, ObjPtr class) #else ObjPtr GetAllVis(dataset, justOne, class) ObjPtr dataset; Bool justOne; ObjPtr class; #endif /*Returns a list of all visualizations that can visualize dataset, or NULLOBJ if justOne, returns the first it finds. If class is not null, only returns visualizations belonging to that class*/ { int k; long flags; int topDim, spatialDim, nComponents; ObjPtr var; ObjPtr lastVis = 0; ObjPtr list = NULLOBJ; ObjPtr thisVis; /*Always apply some filters*/ dataset = MainFilters(dataset); flags = GetDatasetInfo(dataset); flags &= ~DS_TIMEDEPENDENT; spatialDim = GetSpatialDim(dataset); topDim = GetTopDim(dataset); if (flags & DS_VECTOR) { MakeVar(dataset, NCOMPONENTS); var = GetIntVar("GetPrefVis", dataset, NCOMPONENTS); if (!var) { return NULLOBJ; } nComponents = GetInt(var); } /*Check all the possible visualization techniques on the raw dataset*/ for (k = 0; k < nVisMappings; ++k) { if ((visMapping[k] . dataInfo & ~DS_TIMEDEPENDENT) != flags) { continue; } if (visMapping[k] . topDim >= 0 && visMapping[k] . topDim != topDim) { continue; } if (flags & DS_HASFORM) { if (visMapping[k] . spatialDim >= 0 && visMapping[k] . spatialDim != spatialDim) { continue; } } if (flags & DS_VECTOR) { if (visMapping[k] . nComponents >= 0 && visMapping[k] . nComponents != nComponents) { continue; } } if (visMapping[k] . visClass == lastVis) { continue; } if (class && (visMapping[k] . visClass != class)) { continue; } lastVis = visMapping[k] . visClass; if (!list) { list = NewList(); } thisVis = NewVis(dataset, visMapping[k] . visClass); if (thisVis) { PostfixList(list, thisVis); if (justOne) { return list; } } } lastVis = 0; return list; } ObjPtr GetPrefVis(dataSet) ObjPtr dataSet; /*Gets the preferred visualization for dataSet*/ { ObjPtr prefVis, list; if (prefVis = GetVar(dataSet, PREFVIS)) { return NewVis(MainFilters(dataSet), prefVis); } if (list = GetAllVis(dataSet, true, NULLOBJ)) { ThingListPtr listOf; listOf = LISTOF(list); if (listOf) { return listOf -> thing; } } return NULLOBJ; } ObjPtr NewVis(dataset, visClass) ObjPtr dataset, visClass; /*Visializes dataset as a visualization object of class visClass. If visClass is NULLOBJ, picks the preferred visualization type.*/ { ObjPtr retVal; FuncTyp method; if (!visClass) { visClass = GetPrefVis(dataset); } retVal = NewObject(visClass, 0); if (!retVal) { return NULLOBJ; } SetVar(retVal, REPOBJ, dataset); /* just in case vis obj is stupid */ SetVar(retVal, MAINDATASET, dataset); return retVal; } ObjPtr DropInMainDatasetCorral(corral, object, x, y) ObjPtr corral, object; int x, y; /*Drops an icon in a main dataset corral*/ { WarnUser(CW_CANNOTDROPINMAIN); return ObjTrue; } static ObjPtr DeleteVisObject(object) ObjPtr object; /*Deletes a vis object from the current window.*/ { ObjPtr deleteObject; if (!selWinInfo || !object) return ObjFalse; deleteObject = ObjectWhichRepresents(selWinInfo, object); Select(object, false); if (deleteObject) { ObjPtr space; FuncTyp method; ObjPtr contentsList; ObjPtr parent, newList, clock; space = FindSpace(selWinInfo); if (space) { contentsList = GetListVar("DeleteVisObject", space, CONTENTS); if (contentsList) { SaveVarSnapshotForUndo(space, CONTENTS); newList = RemoveFromList(contentsList, object); SetVar(newList, PARENT, GetVar(contentsList, PARENT)); SetVar(space, CONTENTS, newList); } MakeVar(space, CLOCK); clock = GetVar(space, CLOCK); if (clock) { ReinitController(clock); } } object = deleteObject; contentsList = GetVar(object, PARENT); if (!contentsList || !IsList(contentsList)) { contentsList = GetVar(contentsList, CONTENTS); } if (contentsList && IsList(contentsList)) { parent = GetVar(contentsList, PARENT); if (parent) { SaveVarSnapshotForUndo(parent, CONTENTS); newList = RemoveFromList(contentsList, object); SetVar(newList, PARENT, parent); SetVar(parent, CONTENTS, newList); } else { ReportError("DeleteObject", "No parent"); DeleteFromList(contentsList, object); } return ObjTrue; } else { ReportError("DeleteObject","Internal error: cannot find contents list"); } } return ObjFalse; } ObjPtr NewVisIcon(visObject) ObjPtr visObject; /*Creates a new visualization icon for visObject*/ { ObjPtr name, defaultIcon, mainDataset; ObjPtr retVal; MakeVar(visObject, DEFAULTICON); defaultIcon = GetObjectVar("NewVisIcon", visObject, DEFAULTICON); if (!defaultIcon) { return NULLOBJ; } retVal = NewObject(defaultIcon, 0); if (!retVal) { return NULLOBJ; } SetVar(retVal, REPOBJ, visObject); MakeVar(visObject, NAME); name = GetVar(visObject, NAME); SetVar(retVal, NAME, name); mainDataset = GetObjectVar("NewVisIcon", visObject, MAINDATASET); if (mainDataset) { name = GetLongName(mainDataset); SetVar(visObject, FORMAT, name); } SetVar(retVal, ICONLOC, NULLOBJ); return retVal; } static MakeMethod MakeFormBounds(object) ObjPtr object; /*Make bounds for an form-based object*/ { ObjPtr repObj, var; real bounds[6]; repObj = GetVar(object, MAINDATASET); if (!repObj) repObj = GetObjectVar("FormBounds", object, REPOBJ); if (repObj) { ObjPtr formObj; formObj = GetVar(repObj, DATAFORM); if (formObj) { long info; info = GetDatasetInfo(repObj); { ObjPtr curBoundsArray; curBoundsArray = GetArrayVar("FormBounds", formObj, BOUNDS); if (!curBoundsArray) { return ObjFalse; } if (RANK(curBoundsArray) != 1) { ReportError("FormBounds", "Malformed BOUNDS\n"); return ObjFalse; } if (DIMS(curBoundsArray)[0] >= 6) { Array2CArray(bounds, curBoundsArray); } else if (DIMS(curBoundsArray)[0] == 4) { Array2CArray(bounds, curBoundsArray); bounds[4] = bounds[5] = 0.0; } else { return ObjFalse; } } } else { return ObjFalse; } var = NewRealArray(1, 6L); CArray2Array(var, bounds); SetVar(object, BOUNDS, var); return ObjTrue; } else { return ObjFalse; } } static ObjPtr PrefixColoredDatasets(list, visObject) ObjPtr list, visObject; /*Prefixes the datasets in visObject to list*/ { ObjPtr colorObj; if (colorObj = GetVar(visObject, COLOROBJ)) { PrefixList(list, colorObj); } return ObjTrue; } static MakeMethod MakeGeoPictureBounds(object) ObjPtr object; /*Makes bounds for a geopicture*/ { ObjPtr geometry, repObj, objBounds; real *boundsPtr; real bounds[6]; ObjPtr var; repObj = GetObjectVar("GeoPictureBounds", object, REPOBJ); if (!repObj) { return ObjFalse; } SetCurField(FIELD5, repObj); geometry = curFields[FIELD5] . objectInfo; if (IsPicture(geometry)) { GetPictureBounds(geometry, bounds); geometry = GetVar(repObj, ETERNALPART); if (geometry) { real newBounds[6]; GetPictureBounds(geometry, newBounds); bounds[0] = MIN(bounds[0], newBounds[0]); bounds[1] = MAX(bounds[1], newBounds[1]); bounds[2] = MIN(bounds[2], newBounds[2]); bounds[3] = MAX(bounds[3], newBounds[3]); bounds[4] = MIN(bounds[4], newBounds[4]); bounds[5] = MAX(bounds[5], newBounds[5]); } objBounds = NewRealArray(1, (long) 6); CArray2Array(objBounds, bounds); SetVar(object, BOUNDS, objBounds); } else if (IsGeometry(geometry)) { MakeFormBounds(object); } else if (geometry) { var = GetVar(geometry, CLASSID); if (var && GetInt(var) == CLASS_TIMEDOBJ) { long k; ObjPtr *elements; real newBounds[6]; var = GetVar(geometry, TIMEDATA); bounds[0] = bounds[2] = bounds[4] = plusInf; bounds[1] = bounds[3] = bounds[5] = minusInf; if (var && IsObjArray(var)) { elements = ELEMENTS(var); for (k = 0; k < DIMS(var)[0]; ++k) { GetPictureBounds(elements[k], newBounds); bounds[0] = MIN(bounds[0], newBounds[0]); bounds[1] = MAX(bounds[1], newBounds[1]); bounds[2] = MIN(bounds[2], newBounds[2]); bounds[3] = MAX(bounds[3], newBounds[3]); bounds[4] = MIN(bounds[4], newBounds[4]); bounds[5] = MAX(bounds[5], newBounds[5]); } } else { ReportError("MakeGeoPictureBounds", "Time error"); } geometry = GetVar(repObj, ETERNALPART); if (geometry) { GetPictureBounds(geometry, newBounds); bounds[0] = MIN(bounds[0], newBounds[0]); bounds[1] = MAX(bounds[1], newBounds[1]); bounds[2] = MIN(bounds[2], newBounds[2]); bounds[3] = MAX(bounds[3], newBounds[3]); bounds[4] = MIN(bounds[4], newBounds[4]); bounds[5] = MAX(bounds[5], newBounds[5]); } } objBounds = NewRealArray(1, (long) 6); CArray2Array(objBounds, bounds); SetVar(object, BOUNDS, objBounds); } return ObjTrue; } static ObjPtr ChangeReflection(object) ObjPtr object; /*Changed value for a reflection quality control*/ { real shininess, specularity; ObjPtr val; ObjPtr repObj; repObj = GetObjectVar("ChangeReflection", object, REPOBJ); if (!repObj) { return ObjFalse; } if (!GetXYControlValue(object, &shininess, &specularity)) { return ObjFalse; } SetVar(repObj, SHINVAL, NewReal(shininess)); SetVar(repObj, SPECVAL, NewReal(specularity)); ImInvalid(repObj); SetVar(object, APPEARANCE, ObjTrue); return ObjTrue; } static MakeMethod MakeReflectionAppearance(object) ObjPtr object; /*Makes the appearance of a reflection quality control*/ { real shininess, specularity; ObjPtr val; ObjPtr repObj; ObjPtr var; real *elements; FuncTyp method; repObj = GetObjectVar("MakeReflectionAppearance", object, REPOBJ); if (!repObj) { return ObjFalse; } var = GetRealVar("MakeReflectionAppearance", repObj, SHINVAL); if (!var) { return ObjFalse; } shininess = GetReal(var); var = GetRealVar("MakeReflectionAppearance", repObj, SPECVAL); if (!var) { return ObjFalse; } specularity = GetReal(var); val = NewRealArray(1, 2L); elements = ELEMENTS(val); elements[0] = shininess; elements[1] = specularity; method = GetMethod(object, CHANGEDVALUE); SetMethod(object, CHANGEDVALUE, (FuncTyp) 0); SetValue(object, val); SetMethod(object, CHANGEDVALUE, method); SetVar(object, APPEARANCE, ObjTrue); return ObjTrue; } static ObjPtr ShowVisControls(object, windowName) ObjPtr object; char *windowName; /*Makes a new control window to control visualization object*/ { WinInfoPtr controlWindow; ObjPtr var; ObjPtr panel; ObjPtr controlField; ObjPtr contents, windowContents; ObjPtr curObj; ObjPtr firstButton = NULLOBJ; int left, right, bottom, top, width; WinInfoPtr dialogExists; Bool abortp = false; dialogExists = DialogExists((WinInfoPtr) object, NewString("Controls")); controlWindow = GetDialog((WinInfoPtr) object, NewString("Controls"), windowName, CWINWIDTH, CWINHEIGHT, CWINWIDTH, CWINHEIGHT, WINFIXEDSIZE + WINUI); if (!dialogExists) { SetVar((ObjPtr) controlWindow, REPOBJ, object); /*Add in help string*/ SetVar((ObjPtr) controlWindow, HELPSTRING, NewString("This window shows controls for a visualization object. \ At the right is an icon corral showing a series of icons. Each icon represents a \ set of attributes of the visualization object. On the left are the controls for \ the selected set of attributes. \ Use Help In Context and click on the various controls to find out what they do. \ Click on a different icon to choose a different set of attributes.")); /*Add in a panel*/ panel = NewPanel(greyPanelClass, 0, CWINWIDTH, 0, CWINHEIGHT); if (!panel) { return ObjFalse; } contents = GetVar((ObjPtr) controlWindow, CONTENTS); windowContents = contents; PrefixList(contents, panel); SetVar(panel, PARENT, (ObjPtr) controlWindow); contents = GetVar(panel, CONTENTS); /*Add in a control field*/ controlField = NewControlField(CWINWIDTH - CORRALBORDER - CWINCORRALWIDTH, CWINWIDTH - CORRALBORDER, CORRALBORDER, CWINHEIGHT - CORRALBORDER, "Visualization Object Attributes", OBJECTSFROMTOP | BARRIGHT); SetVar(controlField, HELPSTRING, NewString("This icon button group shows sets of attributes of the visualization \ object that can be modified. The left side of the panel shows controls for the \ attribute given by the selected icon button. To show another set of \ attributes, press another button.")); SetVar(controlField, PARENT, panel); PrefixList(contents, controlField); contents = GetVar(controlField, CONTENTS); /*Fill the control field up with buttons*/ curObj = object; top = -MAJORBORDER; width = CWINCCWIDTH; while (curObj) { ObjPtr icon; icon = Get1Var(curObj, CONTROLICON); if (icon) { ObjPtr button; ObjPtr panelContents; FuncTyp method; int whichIcon; char *name; if (firstButton && abortp) break; var = GetIntVar("ShowVisControls", icon, WHICHICON); if (var) { whichIcon = GetInt(var); } else { whichIcon = ICONQUESTION; } MakeVar(icon, NAME); var = GetStringVar("ShowVisControls", icon, NAME); if (var) { name = GetString(var); } else { name = "Unknown"; } button = NewIconLabeledButton(0, width, top - CWINICONBUTHEIGHT, top, whichIcon, UIYELLOW, name, BS_PITTED); SetMethod(button, ICONEXTRADRAW, GetMethod(icon, ICONEXTRADRAW)); SetVar(button, REPOBJ, object); SetMethod(button, CHANGEDVALUE, ChangeControlPanelButton); SetVar(button, PANEL, panel); /*Make a new panel contents just for this button*/ panelContents = NewList(); SetVar(panelContents, TYPESTRING, NewString("control panel")); sprintf(tempStr, "%s panel", name); SetVar(panelContents, NAME, NewString(tempStr)); if (var = GetVar(icon, PANELHELP)) { ObjPtr iconButton; SetVar(panelContents, HELPSTRING, var); } PrefixList(panelContents, controlField); SetVar(panelContents, PARENT, panel); SetVar(button, PANELCONTENTS, panelContents); SetVar(button, PARENT, panelContents); /*Give the button a chance to add controls*/ method = Get1Method(curObj, ADDCONTROLS); if (method) { SetVar(button, CONTROLSADDED, ObjFalse); SetMethod(button, ADDCONTROLS, method); } else { SetVar(button, CONTROLSADDED, ObjTrue); } PrefixList(contents, button); SetVar(button, PARENT, controlField); top -= CWINICONBUTHEIGHT + MINORBORDER; /*Add VR controls*/ method = Get1Method(curObj, ADDVRCONTROLS); if (method) { (*method)(object, windowContents); } if (!firstButton) { ObjPtr mainDataset; firstButton = button; /*Give the MAINDATASET a chance to set controls*/ mainDataset = GetVar(object, MAINDATASET); while (mainDataset) { icon = GetVar(mainDataset, CONTROLICON); if (icon) { ObjPtr panelContents; FuncTyp method; var = GetIntVar("ShowVisControls", icon, WHICHICON); if (var) { whichIcon = GetInt(var); } else { whichIcon = ICONQUESTION; } MakeVar(icon, NAME); var = GetStringVar("ShowVisControls", icon, NAME); if (var) { name = GetString(var); } else { name = "Unknown"; } button = NewIconLabeledButton(0, width, top - CWINICONBUTHEIGHT, top, whichIcon, UIYELLOW, name, BS_PITTED); SetMethod(button, ICONEXTRADRAW, GetMethod(icon, ICONEXTRADRAW)); SetMethod(button, CHANGEDVALUE, ChangeControlPanelButton); SetVar(button, PANEL, panel); /*Make a new panel contents just for this button*/ panelContents = NewList(); SetVar(panelContents, TYPESTRING, NewString("control panel")); SetVar(panelContents, NAME, NewString(name)); if (var = GetVar(icon, PANELHELP)) { ObjPtr iconButton; SetVar(panelContents, HELPSTRING, var); } PrefixList(panelContents, controlField); SetVar(panelContents, PARENT, panel); SetVar(button, PANELCONTENTS, panelContents); SetVar(button, PARENT, panelContents); SetVar(button, REPOBJ, mainDataset); /*Give the button a chance to add controls*/ method = GetMethod(mainDataset, ADDCONTROLS); if (method) { SetVar(button, CONTROLSADDED, ObjFalse); SetMethod(button, ADDCONTROLS, method); } else { SetVar(button, CONTROLSADDED, ObjTrue); } PrefixList(contents, button); SetVar(button, PARENT, controlField); top -= CWINICONBUTHEIGHT + MINORBORDER; } mainDataset = GetVar(mainDataset, MAINDATASET); } } } if (GetPredicate(curObj, ABORTCONTROLS)) abortp = true; curObj = ClassOf(curObj); } /*Adjust the scroll bars*/ RecalcScroll(controlField); if (firstButton) { SetValue(firstButton, NewInt(1)); SetVar(controlField, BUTTON, firstButton); } } return (ObjPtr) controlWindow; } static char *wallNames[6] = { "-X Wall", "+X Wall", "-Y Wall", "+Y Wall", "-Z Wall (Floor)", "+Z Wall (Ceiling)" }; #ifdef HAVE_PROTOTYPES void AppendSpaces(char *s, int nSpaces) #else void AppendSpaces(s, nSpaces) char *s; int nSpaces; #endif /*Appends nSpaces spaces after s*/ { while (*s) ++s; while (nSpaces--) { *s++ = ' '; } *s = '\0'; } static ObjPtr AddAxesControls(object, panelContents) ObjPtr object, panelContents; /*Adds controls for a visualization object with axes*/ { ObjPtr titleBox, checkBox, textBox, var; ObjPtr colorWheel, slider; int curFlag; int left, right, bottom, top, mid, width, i, j, whichWall, k, f, h; int l, r, b, t; int titleWidth, buttonWidth, axisGroupWidth, rightWidth; char buttonName[40]; width = CWINWIDTH - CORRALBORDER - CWINCORRALWIDTH; top = CWINHEIGHT - MINORBORDER; rightWidth = (width - 2 * MINORBORDER - SBFUNCTIONNAMEWIDTH); /*Axis name edit boxes*/ MakeVar(object, XNAME); MakeVar(object, YNAME); MakeVar(object, ZNAME); left = MINORBORDER; right = left + SBFUNCTIONNAMEWIDTH; bottom = top - EDITBOXHEIGHT; mid = (bottom + top) / 2; textBox = NewTextBox(left, right, mid - TEXTBOXHEIGHT / 2 + EDITBOXDOWN, mid + TEXTBOXHEIGHT / 2 + EDITBOXDOWN, 0, "Axis Name Text", "Axis Name:"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); left = right; for (k = 0; k < 3; ++k) { /*Make the axis edit box*/ left = 2 * MINORBORDER + SBFUNCTIONNAMEWIDTH + k * rightWidth / 3; right = left + rightWidth / 3 - MINORBORDER; var = GetStringVar("AddAxesControls", object, k == 2 ? ZNAME : (k ? YNAME : XNAME)); if (var) { strcpy(tempStr, GetString(var)); } else { strcpy(tempStr, k == 2 ? "Z" : (k ? "Y" : "X")); } textBox = NewTextBox(left, right, mid - EDITBOXHEIGHT / 2, mid + EDITBOXHEIGHT / 2, EDITABLE + WITH_PIT + ONE_LINE, k == 2 ? "Z Axis Name" : (k ? "Y Axis Name" : "X Axis Name"), tempStr); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, RIGHTALIGN); switch (k) { case 0: AssocDirectControlWithVar(textBox, object, XNAME); break; case 1: AssocDirectControlWithVar(textBox, object, YNAME); break; case 2: AssocDirectControlWithVar(textBox, object, ZNAME); break; } SetVar(textBox, HELPSTRING, NewString("This text box contains the name of the \ indicated axis.")); } top = bottom - SBFUNCTIONSPACING; /*Axis name check boxes*/ left = MINORBORDER; right = left + SBFUNCTIONNAMEWIDTH; bottom = top - CHECKBOXHEIGHT; textBox = NewTextBox(left, right, top - TEXTBOXHEIGHT + EDITBOXDOWN, top + EDITBOXDOWN, 0, "Show Names Text", "Show Name:"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); /*Draw name check boxes*/ bottom = top - CHECKBOXHEIGHT; curFlag = 1; for (k = 0; k < 3; ++k) { left = 2 * MINORBORDER + SBFUNCTIONNAMEWIDTH + k * rightWidth / 3; right = left + rightWidth / 3 - MINORBORDER; checkBox = NewCheckBox(left, right, bottom, top, k == 0 ? "Centered" : k == 1 ? "Centered " : "Centered ", 0); if (!checkBox) { return ObjFalse; } PrefixList(panelContents, checkBox); SetVar(checkBox, PARENT, panelContents); sprintf(tempStr, "If this box is checked, the name of this axis will be shown at the center of the axis."); SetVar(checkBox, HELPSTRING, NewString(tempStr)); AssocFlagControlWithVar(checkBox, object, DRAWNAMES, curFlag); curFlag *= 2; } top = bottom - CHECKBOXSPACING; left = MINORBORDER; right = left + SBFUNCTIONNAMEWIDTH; bottom = top - EDITBOXHEIGHT; mid = (bottom + top) / 2; textBox = NewTextBox(left, right, mid - TEXTBOXHEIGHT / 2 + EDITBOXDOWN, mid + TEXTBOXHEIGHT / 2 + EDITBOXDOWN, 0, "Major Step Text", "Major Step:"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); left = right; for (k = 0; k < 3; ++k) { /*Make the major step edit box*/ left = 2 * MINORBORDER + SBFUNCTIONNAMEWIDTH + k * rightWidth / 3; right = left + rightWidth / 3 - MINORBORDER; textBox = NewTextBox(left, right, mid - EDITBOXHEIGHT / 2, mid + EDITBOXHEIGHT / 2, EDITABLE + WITH_PIT + ONE_LINE, k == 2 ? "Z Major Step" : (k ? "Y Major Step" : "X Major Step"), ""); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, RIGHTALIGN); AssocIndexedTextRealControlWithVar(textBox, object, AXISMAJORSTEP, k, 0, plusInf, TR_NE_BOTTOM | TR_NE_TOP); SetVar(textBox, HELPSTRING, NewString("This text box contains a number \ which gives the step size for major tic marks along the indicated dimension. \ The major steps are calculated relative to the origin.")); } top = bottom - SBFUNCTIONSPACING; left = MINORBORDER; right = left + SBFUNCTIONNAMEWIDTH; bottom = top - EDITBOXHEIGHT; mid = (bottom + top) / 2; textBox = NewTextBox(left, right, mid - TEXTBOXHEIGHT / 2 + EDITBOXDOWN, mid + TEXTBOXHEIGHT / 2 + EDITBOXDOWN, 0, "Divisions Text", "Divisions:"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); left = right; for (k = 0; k < 3; ++k) { /*Make the major step edit box*/ left = 2 * MINORBORDER + SBFUNCTIONNAMEWIDTH + k * rightWidth / 3; right = left + rightWidth / 3 - MINORBORDER; textBox = NewTextBox(left, right, mid - EDITBOXHEIGHT / 2, mid + EDITBOXHEIGHT / 2, EDITABLE + WITH_PIT + ONE_LINE, k == 2 ? "Z Divisions" : (k ? "Y Divisions" : "X Divisions"), ""); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, RIGHTALIGN); AssocIndexedTextRealControlWithVar(textBox, object, AXISDIVISIONS, k, 1, plusInf, TR_INT_ONLY | TR_NE_TOP); SetVar(textBox, HELPSTRING, NewString("This text box contains a number \ which gives the number of minor divisions within each major step. For example, if the major step \ is 1.0, and the number of divisions is 10, there will be a minor tic every 0.1 units.")); } top = bottom - SBFUNCTIONSPACING; /*Tic length controls*/ left = MINORBORDER; right = left + SBFUNCTIONNAMEWIDTH; bottom = top - EDITBOXHEIGHT; mid = (bottom + top) / 2; textBox = NewTextBox(left, right, mid - TEXTBOXHEIGHT / 2 + EDITBOXDOWN, mid + TEXTBOXHEIGHT / 2 + EDITBOXDOWN, 0, "Tic Length Text", "Tic Length:"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); left = right; for (k = 0; k < 3; ++k) { /*Make the tic length box*/ left = 2 * MINORBORDER + SBFUNCTIONNAMEWIDTH + k * rightWidth / 3; right = left + rightWidth / 3 - MINORBORDER; textBox = NewTextBox(left, right, mid - EDITBOXHEIGHT / 2, mid + EDITBOXHEIGHT / 2, EDITABLE + WITH_PIT + ONE_LINE, k == 2 ? "Z Tic Length" : (k ? "Y Tic Length" : "X Tic Length"), ""); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, RIGHTALIGN); AssocIndexedTextRealControlWithVar(textBox, object, TICLENGTH, k, 0.0, plusInf, 0); SetVar(textBox, HELPSTRING, NewString("This text box contains a number \ which gives the length of tic marks in the indicated dimension. The number \ is in field coordinates.")); } top = bottom - SBFUNCTIONSPACING; /*Major tic mark check boxes*/ left = MINORBORDER; right = left + SBFUNCTIONNAMEWIDTH; bottom = top - CHECKBOXHEIGHT; textBox = NewTextBox(left, right, top - TEXTBOXHEIGHT + EDITBOXDOWN, top + EDITBOXDOWN, 0, "Tic Marks Text", "Show Tics:"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); curFlag = BBXMAJOR; for (k = 0; k < 3; ++k) { left = 2 * MINORBORDER + SBFUNCTIONNAMEWIDTH + k * rightWidth / 3; right = left + rightWidth / 3 - MINORBORDER; checkBox = NewCheckBox(left, right, bottom, top, k == 0 ? "Major" : k == 1 ? "Major " : "Major ", 0); if (!checkBox) { return ObjFalse; } PrefixList(panelContents, checkBox); SetVar(checkBox, PARENT, panelContents); sprintf(tempStr, "If this box is checked, major tic marks will be shown along the %c axis.", k == 0 ? 'X' : k == 1 ? 'Y' : 'Z'); SetVar(checkBox, HELPSTRING, NewString(tempStr)); sprintf(tempStr, "If this box is checked, minor tic marks will be shown along the %c axis.", k == 0 ? 'X' : k == 1 ? 'Y' : 'Z'); SetVar(checkBox, HELPSTRING, NewString(tempStr)); AssocFlagControlWithVar(checkBox, object, BBFLAGS, curFlag); curFlag *= 4; } top = bottom - SBFUNCTIONSPACING; /*Minor tic mark check boxes*/ bottom = top - CHECKBOXHEIGHT; curFlag = BBXMINOR; for (k = 0; k < 3; ++k) { left = 2 * MINORBORDER + SBFUNCTIONNAMEWIDTH + k * rightWidth / 3; right = left + rightWidth / 3 - MINORBORDER; checkBox = NewCheckBox(left, right, bottom, top, k == 0 ? "Minor" : k == 1 ? "Minor " : "Minor ", 0); if (!checkBox) { return ObjFalse; } PrefixList(panelContents, checkBox); SetVar(checkBox, PARENT, panelContents); sprintf(tempStr, "If this box is checked, minor tic marks will be shown along the %c axis.", k == 0 ? 'X' : k == 1 ? 'Y' : 'Z'); SetVar(checkBox, HELPSTRING, NewString(tempStr)); AssocFlagControlWithVar(checkBox, object, BBFLAGS, curFlag); curFlag *= 4; } top = bottom - CHECKBOXSPACING; return ObjTrue; } static ObjPtr AddWallsControls(object, panelContents) ObjPtr object, panelContents; /*Adds controls for a visualization object with walls*/ { ObjPtr titleBox, checkBox, textBox; ObjPtr colorWheel, slider; int left, right, bottom, top, width, i, j, whichWall, k, f, h; int l, r, b, t; int titleWidth, buttonWidth; char buttonName[40]; width = CWINWIDTH - CORRALBORDER - CWINCORRALWIDTH; left = MINORBORDER; right = width - MINORBORDER; top = CWINHEIGHT - MINORBORDER; bottom = MINORBORDER; buttonWidth = (width - 6 * MINORBORDER) / 4; titleWidth = buttonWidth; titleWidth += 21; buttonWidth -= 7; for (i = 0; i < 3; ++i) { for (j = 0; j < 2; ++j) { k = j + i * 2; f = 1 << k; l = left; r = l + titleWidth; t = top - k * (CHECKBOXHEIGHT + CHECKBOXSPACING); b = t - CHECKBOXHEIGHT; sprintf(buttonName, "%s:", wallNames[k]); textBox = NewTextBox(l, r, b - 4, t - 4, PLAIN, buttonName, buttonName); PrefixList(panelContents, textBox); SetVar(panelContents, PARENT, textBox); l = r + MINORBORDER; r = l + buttonWidth; strcpy(buttonName, "Wall"); AppendSpaces(buttonName, k); checkBox = NewCheckBox(l, r, b, t, buttonName, false); PrefixList(panelContents, checkBox); SetVar(checkBox, PARENT, panelContents); AssocFlagControlWithVar(checkBox, object, WALLPANELFLAGS, f); sprintf(tempStr, "When this check box is on, the %s wall is visible. \ The Wall Panel, Wall Lines, and Draw control groups at the bottom of the \ window control how visible walls are drawn.", wallNames[k]); SetVar(checkBox, HELPSTRING, NewString(tempStr)); l = r + MINORBORDER; r = l + buttonWidth; strcpy(buttonName, "Shadow"); AppendSpaces(buttonName, k); checkBox = NewCheckBox(l, r, b, t, buttonName, false); PrefixList(panelContents, checkBox); SetVar(checkBox, PARENT, panelContents); AssocFlagControlWithVar(checkBox, object, WALLSHADOWFLAGS, f); sprintf(tempStr, "When this check box is on, a black shadown of the \ visualization is shown on the %s wall.", wallNames[k]); SetVar(checkBox, HELPSTRING, NewString(tempStr)); l = r + MINORBORDER; r = l + buttonWidth; strcpy(buttonName, "Mirror"); AppendSpaces(buttonName, k); checkBox = NewCheckBox(l, r, b, t, buttonName, false); PrefixList(panelContents, checkBox); SetVar(checkBox, PARENT, panelContents); AssocFlagControlWithVar(checkBox, object, WALLMIRRORFLAGS, f); sprintf(tempStr, "When this check box is on, the %s wall acts as a mirror \ for the visualization object. It's not quite like a real mirror, as the presence of the \ reflection does not depend in any way whether the angle of view included the mirror. Also, \ facing mirrors do not produce a barbershop effect. This feature is useful when only one-half \ or one-quarter of a problem domain has been computed and you want to display the rest \ automatically.", wallNames[k]); SetVar(checkBox, HELPSTRING, NewString(tempStr)); } } t = top - 6 * (CHECKBOXHEIGHT + CHECKBOXSPACING) - MINORBORDER; /*Make the wall panel control group*/ titleBox = NewTitleBox(left, left + 3 * MINORBORDER + COLORWHEELWIDTH + SLIDERWIDTH, t - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT - TITLEBOXTOP - 2 * MINORBORDER, t, "Wall Panels"); PrefixList(panelContents, titleBox); SetVar(titleBox, PARENT, panelContents); l = left + MINORBORDER; r = l + COLORWHEELWIDTH; t -= TITLEBOXTOP + MINORBORDER; b = t - COLORWHEELWIDTH; /*Make the color wheel and its text box*/ colorWheel = NewColorWheel(l, r, b, t, "Panel Color Wheel"); SetVar(colorWheel, PARENT, panelContents); PrefixList(panelContents, colorWheel); AssocColorControlWithVar(colorWheel, object, WALLPANELCOLOR); SetVar(colorWheel, HELPSTRING, NewString("This color wheel controls the \ hue and saturation of the color used to draw the panels of visible walls. \ The final color is a combination of this hue and saturation and the value, or brightness, \ given by the Value slider.")); textBox = NewTextBox(l, r, b - TEXTBOXSEP - TEXTBOXHEIGHT, b - TEXTBOXSEP, PLAIN, "Panel Color Text", "Color"); SetVar(textBox, PARENT, panelContents); PrefixList(panelContents, textBox); SetTextAlign(textBox, CENTERALIGN); l = r + MINORBORDER; r = l + SLIDERWIDTH; /*Make the brightness slider*/ slider = NewSlider(l, r, b, t, PLAIN, "Panel Color Value"); SetVar(slider, PARENT, panelContents); PrefixList(panelContents, slider); SetSliderRange(slider, 1.0, 0.0, 0.0); AssocBrightnessControlWithVar(slider, object, WALLPANELCOLOR); SetVar(slider, HELPSTRING, NewString("This slider controls the \ value, or brightness, of the color used to draw panels of visible walls. \ The final color is a combination of this value and the hue and saturation \ given by the Color color wheel.")); textBox = NewTextBox(l - MINORBORDER, r + MINORBORDER, b - TEXTBOXSEP - TEXTBOXHEIGHT, b - TEXTBOXSEP, PLAIN, "{ame; Value Text", "Value"); SetVar(textBox, PARENT, panelContents); PrefixList(panelContents, textBox); SetTextAlign(textBox, CENTERALIGN); l = r + MINORBORDER; l += MINORBORDER; r = right; t = top - 6 * (CHECKBOXHEIGHT + CHECKBOXSPACING) - MINORBORDER; /*Make the wall lines control group*/ titleBox = NewTitleBox(l, l + 3 * MINORBORDER + COLORWHEELWIDTH + SLIDERWIDTH, t - COLORWHEELWIDTH - TEXTBOXSEP - TEXTBOXHEIGHT - TITLEBOXTOP - 2 * MINORBORDER, t, "Wall Lines"); PrefixList(panelContents, titleBox); SetVar(titleBox, PARENT, panelContents); l += MINORBORDER; r -= MINORBORDER; t -= TITLEBOXTOP + MINORBORDER; b = t - COLORWHEELWIDTH; r = l + COLORWHEELWIDTH; /*Make the color wheel and its text box*/ colorWheel = NewColorWheel(l, r, b, t, "Panel Lines Color Wheel"); SetVar(colorWheel, PARENT, panelContents); PrefixList(panelContents, colorWheel); AssocColorControlWithVar(colorWheel, object, WALLLINESCOLOR); SetVar(colorWheel, HELPSTRING, NewString("This color wheel controls the \ hue and saturation of the color used to draw lines on visible walls. \ The final color is a combination of this hue and saturation and the value, or brightness, \ given by the Value slider.")); textBox = NewTextBox(l, r, b - TEXTBOXSEP - TEXTBOXHEIGHT, b - TEXTBOXSEP, PLAIN, "Wall Lines Color Text", "Color"); SetVar(textBox, PARENT, panelContents); PrefixList(panelContents, textBox); SetTextAlign(textBox, CENTERALIGN); l = r + MINORBORDER; r = l + SLIDERWIDTH; /*Make the brightness slider*/ slider = NewSlider(l, r, b, t, PLAIN, "Wall Lines Color Value"); SetVar(slider, PARENT, panelContents); PrefixList(panelContents, slider); SetSliderRange(slider, 1.0, 0.0, 0.0); AssocBrightnessControlWithVar(slider, object, WALLLINESCOLOR); SetVar(slider, HELPSTRING, NewString("This slider controls the \ value, or brightness, of the color used to draw lines on visible walls. \ The final color is a combination of this value and the hue and saturation \ given by the Color color wheel.")); textBox = NewTextBox(l - MINORBORDER, r + MINORBORDER, b - TEXTBOXSEP - TEXTBOXHEIGHT, b - TEXTBOXSEP, PLAIN, "Wall Lines Value Text", "Value"); SetVar(textBox, PARENT, panelContents); PrefixList(panelContents, textBox); SetTextAlign(textBox, CENTERALIGN); /*Put in the draw checkBoxs at the right*/ l = r + 2 * MINORBORDER; r = right; t = t + MINORBORDER + TITLEBOXTOP; b = b - MINORBORDER - TEXTBOXHEIGHT - TEXTBOXSEP; titleBox = NewTitleBox(l, r, b, t, "Draw"); SetVar(titleBox, PARENT, panelContents); PrefixList(panelContents, titleBox); l += MINORBORDER; t -= TITLEBOXTOP + MINORBORDER; r -= MINORBORDER; b = t - CHECKBOXHEIGHT; checkBox = NewCheckBox(l, r, b, t, "Outline", GetPredicate(object, DRAWOUTLINE)); SetVar(checkBox, PARENT, panelContents); PrefixList(panelContents, checkBox); AssocDirectControlWithVar(checkBox, object, DRAWOUTLINE); SetVar(checkBox, HELPSTRING, NewString("This check box controls the drawing of the outline of visible walls. \ When it is on, an outline is drawn around every one of the visible walls. \ When it is off, the outline is not drawn. The color is \ given by the Wall Lines controls, and other parameters of the lines such as width and \ antialiasing are set in the Lines control panel. Unlike the wall panel, the outline \ is visible even when viewed from the outside.")); t = b - CHECKBOXSPACING; b = t - CHECKBOXHEIGHT; checkBox = NewCheckBox(l, r, b, t, "Grid", GetPredicate(object, DRAWGRID)); SetVar(checkBox, PARENT, panelContents); PrefixList(panelContents, checkBox); AssocDirectControlWithVar(checkBox, object, DRAWGRID); SetVar(checkBox, HELPSTRING, NewString("This check box controls the drawing of a grid on visible walls. \ When it is on, a grid is drawn on every one of the visible walls. \ The spacing of the grid is given on the major tic marks as defined in \ the Axes control panel. When the check box is off, the grid is not drawn. The color is \ given by the Wall Lines controls, and other parameters of the lines such as width and \ antialiasing are set in the Lines control panel. Unlike the wall panel, the grid \ is visible even when viewed from the outside.")); t = b - CHECKBOXSPACING; b = t - CHECKBOXHEIGHT; checkBox = NewCheckBox(l, r, b, t, "Panel ", GetPredicate(object, DRAWBACKGROUND)); SetVar(checkBox, PARENT, panelContents); PrefixList(panelContents, checkBox); AssocDirectControlWithVar(checkBox, object, DRAWBACKGROUND); SetVar(checkBox, HELPSTRING, NewString("This check box controls the drawing of panels on visible walls. \ When it is on, a solid, shaded panel is drawn for every one of the visible walls. \ When it is off, the background is not drawn. Panels, \ like shadows, are only visible when viewed from the inside. The color of \ the panel is given by the Wall Panels color wheel and value slider.")); t = b - CHECKBOXSPACING; b = t - CHECKBOXHEIGHT; return ObjTrue; } static ObjPtr AddBoundedControls(object, panelContents) ObjPtr object, panelContents; /*Adds controls for a visualization object with a bounding box*/ { int width; int left, top, right, mid, bottom, rightWidth; ObjPtr checkBox, titleBox, textBox, button, radio; ObjPtr flagsObj, var; int flags; int curFlag; int i, j, k; int tbh; real bounds[6]; width = CWINWIDTH - 2 * CORRALBORDER - CWINCORRALWIDTH; left = MINORBORDER; top = CWINHEIGHT - MAJORBORDER; flagsObj = GetVar(object, BBFLAGS); if (flagsObj) { flags = GetInt(flagsObj); } else { flags = 0; } GetBounds(object, bounds); /*Make control group, from top to bottom*/ top = CWINHEIGHT - MINORBORDER; rightWidth = (width - MINORBORDER - SBFUNCTIONNAMEWIDTH); /*Axis name edit boxes*/ MakeVar(object, XNAME); MakeVar(object, YNAME); MakeVar(object, ZNAME); left = MINORBORDER; right = left + SBFUNCTIONNAMEWIDTH; bottom = top - EDITBOXHEIGHT; mid = (bottom + top) / 2; textBox = NewTextBox(left, right, mid - TEXTBOXHEIGHT / 2 + EDITBOXDOWN, mid + TEXTBOXHEIGHT / 2 + EDITBOXDOWN, 0, "Axis Name Text", "Axis Name:"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); left = right; for (k = 0; k < 3; ++k) { /*Make the axis edit box*/ left = 2 * MINORBORDER + SBFUNCTIONNAMEWIDTH + k * rightWidth / 3; right = left + rightWidth / 3 - MINORBORDER; var = GetStringVar("AddBoundedControls", object, k == 2 ? ZNAME : (k ? YNAME : XNAME)); if (var) { strcpy(tempStr, GetString(var)); } else { strcpy(tempStr, k == 2 ? "Z" : (k ? "Y" : "X")); } textBox = NewTextBox(left, right, mid - EDITBOXHEIGHT / 2, mid + EDITBOXHEIGHT / 2, EDITABLE + WITH_PIT + ONE_LINE, k == 2 ? "Z Axis Name" : (k ? "Y Axis Name" : "X Axis Name"), tempStr); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, RIGHTALIGN); switch (k) { case 0: AssocDirectControlWithVar(textBox, object, XNAME); break; case 1: AssocDirectControlWithVar(textBox, object, YNAME); break; case 2: AssocDirectControlWithVar(textBox, object, ZNAME); break; } SetVar(textBox, HELPSTRING, NewString("This text box contains the name of the \ indicated axis. This is the name displayed when Axis Names box is checked.")); } top = bottom - SBFUNCTIONSPACING; /*Min edit boxes*/ left = MINORBORDER; right = left + SBFUNCTIONNAMEWIDTH; bottom =top - EDITBOXHEIGHT; mid = (bottom + top) / 2; textBox = NewTextBox(left, right, mid - TEXTBOXHEIGHT / 2 + EDITBOXDOWN, mid + TEXTBOXHEIGHT / 2 + EDITBOXDOWN, 0, "Minimum Text", "Minimum:"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); left = right; for (k = 0; k < 3; ++k) { /*Make the minimum edit box*/ left = 2 * MINORBORDER + SBFUNCTIONNAMEWIDTH + k * rightWidth / 3; right = left + rightWidth / 3 - MINORBORDER; PrintNumber(tempStr, bounds[k * 2]); textBox = NewTextBox(left, right, mid - EDITBOXHEIGHT / 2, mid + EDITBOXHEIGHT / 2, EDITABLE + WITH_PIT + ONE_LINE, k == 2 ? "Z Minimum" : (k ? "Y Minimum" : "X Minimum"), tempStr); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, RIGHTALIGN); AssocIndexedTextRealControlWithVar(textBox, object, BOUNDS, k * 2, minusInf, plusInf, TR_NE_BOTTOM | TR_NE_TOP); SetVar(textBox, HELPSTRING, NewString("This text box contains a number \ which gives the minimum value of the bounds in the indicated dimension. Change \ this number to change the bounds. The number must not be greater than the \ maximum.")); } top = bottom - SBFUNCTIONSPACING; /*Max edit boxes*/ left = MINORBORDER; right = left + SBFUNCTIONNAMEWIDTH; bottom = top - EDITBOXHEIGHT; mid = (bottom + top) / 2; textBox = NewTextBox(left, right, mid - TEXTBOXHEIGHT / 2 + EDITBOXDOWN, mid + TEXTBOXHEIGHT / 2 + EDITBOXDOWN, 0, "Maximum Text", "Maximum:"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); left = right; for (k = 0; k < 3; ++k) { /*Make the maximum edit box*/ left = 2 * MINORBORDER + SBFUNCTIONNAMEWIDTH + k * rightWidth / 3; right = left + rightWidth / 3 - MINORBORDER; PrintNumber(tempStr, bounds[k * 2 + 1]); textBox = NewTextBox(left, right, mid - EDITBOXHEIGHT / 2, mid + EDITBOXHEIGHT / 2, EDITABLE + WITH_PIT + ONE_LINE, k == 2 ? "Z Maximum" : (k ? "Y Maximum" : "X Maximum"), tempStr); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, RIGHTALIGN); AssocIndexedTextRealControlWithVar(textBox, object, BOUNDS, k * 2 + 1, minusInf, plusInf, TR_NE_BOTTOM | TR_NE_TOP); SetVar(textBox, HELPSTRING, NewString("This text box contains a number \ which gives the maximum value of the bounds in the indicated dimension. Change \ this number to change the bounds. The number must not be less than the \ minimum.")); } top = bottom - SBFUNCTIONSPACING; /*Axis scaling edit boxes*/ left = MINORBORDER; right = left + SBFUNCTIONNAMEWIDTH; bottom = top - EDITBOXHEIGHT; mid = (bottom + top) / 2; textBox = NewTextBox(left, right, mid - TEXTBOXHEIGHT / 2 + EDITBOXDOWN, mid + TEXTBOXHEIGHT / 2 + EDITBOXDOWN, 0, "Axis Scaling Text", "Scaling:"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); left = right; for (k = 0; k < 3; ++k) { /*Make the axis edit box*/ left = 2 * MINORBORDER + SBFUNCTIONNAMEWIDTH + k * rightWidth / 3; right = left + rightWidth / 3 - MINORBORDER; var = GetRealVar("AddBoundedControls", object, k == 2 ? ZSCALE : (k ? YSCALE : XSCALE)); if (var) { PrintNumber(tempStr, GetReal(var)); } else { strcpy(tempStr, "1"); } textBox = NewTextBox(left, right, mid - EDITBOXHEIGHT / 2, mid + EDITBOXHEIGHT / 2, EDITABLE + WITH_PIT + ONE_LINE, k == 2 ? "Z Axis Scaling" : (k ? "Y Axis Scaling" : "X Axis Scaling"), tempStr); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, RIGHTALIGN); switch (k) { case 0: AssocTextRealControlWithVar(textBox, object, XSCALE, minusInf, plusInf, TR_NE_BOTTOM | TR_NE_TOP); break; case 1: AssocTextRealControlWithVar(textBox, object, YSCALE, minusInf, plusInf, TR_NE_BOTTOM | TR_NE_TOP); break; case 2: AssocTextRealControlWithVar(textBox, object, ZSCALE, minusInf, plusInf, TR_NE_BOTTOM | TR_NE_TOP); break; } SetVar(textBox, HELPSTRING, NewString("This text box contains the scaling \ of the selected axis. Normally, all three axes are scaled at 1, indicating that \ all three axes have the same units. However, sometimes it is useful to use different \ scales.\n\nFor example, say you have a mesh of terrain. The X and Y coordinates are \ in kilometers, but the Z coordinate is in meters. To make the visualization appear \ accurately, you might make the X and Y scaling 1000 while keeping the Z scaling at 1.")); } top = bottom - SBFUNCTIONSPACING; /*Make bounding box controls at bottom*/ left = MINORBORDER; bottom = MINORBORDER; top = bottom + COLORWHEELWIDTH + 2 * MINORBORDER + TITLEBOXTOP + TEXTBOXHEIGHT + TEXTBOXSEP; right = left + 400; titleBox = TemplateTitleBox(BoundsTemplate, "Outline Box"); PrefixList(panelContents, titleBox); SetVar(titleBox, PARENT, panelContents); /*Make the outline box radio button*/ radio = NewRadioButtonGroup("Draw Outline"); SetVar(radio, HELPSTRING, NewString("This radio button group controls whether an \ outline box is drawn around the bounds and how it is drawn.")); PrefixList(panelContents, radio); SetVar(radio, PARENT, panelContents); top -= TITLEBOXTOP + MINORBORDER; left += MINORBORDER; button = TemplateRadioButton(BoundsTemplate, "None"); AddRadioButton(radio, button); SetVar(button, HELPSTRING, NewString("If this button is on, no outline box will be \ drawn around the bounds.")); top -= CHECKBOXHEIGHT + CHECKBOXSPACING; button = TemplateRadioButton(BoundsTemplate, "Lines"); AddRadioButton(radio, button); SetVar(button, HELPSTRING, NewString("If this button is on, an outline will \ be drawn as solid lines. The color of the lines is given by the Color and Value \ controls. Other attributes of the line, such as the line width, are given \ in the Lines control panel.")); top -= CHECKBOXHEIGHT + CHECKBOXSPACING; button = TemplateRadioButton(BoundsTemplate, "Frame"); AddRadioButton(radio, button); SetVar(button, HELPSTRING, NewString("If this button is on, an outline will \ be drawn as a solid frame. The frame looks as if it is made out of rectangular panels \ with rectangular holes. \ The color of the frame is given by the Color and Value \ controls. The thickness of the frame is given by the Thickness text box.")); top -= CHECKBOXHEIGHT + CHECKBOXSPACING; button = TemplateRadioButton(BoundsTemplate, "Girders"); AddRadioButton(radio, button); SetVar(button, HELPSTRING, NewString("If this button is on, an outline will \ be drawn as solid girders. The color of the girders is given by the Color and Value \ controls. The thickness of the girders is given by the Thickness text box.")); top -= CHECKBOXHEIGHT + CHECKBOXSPACING; button = TemplateRadioButton(BoundsTemplate, "Cylinders"); AddRadioButton(radio, button); SetVar(button, HELPSTRING, NewString("If this button is on, an outline will \ be drawn as solid cylinders. The color of the girders is given by the Color and Value \ controls. The thickness of the cylinders is given by the Thickness text box.")); top -= CHECKBOXHEIGHT + CHECKBOXSPACING; AssocDirectControlWithVar(radio, object, BOUNDSBOX); return ObjTrue; } static ObjPtr DropInColorCorral(corral, object, x, y) ObjPtr corral, object; int x, y; /*Drops an icon in a field corral*/ { ObjPtr visObj; ObjPtr fieldObj; ObjPtr icon; ObjPtr name; ObjPtr defaultIcon; ObjPtr contents; ObjPtr button; long info; /*Find the visualization object*/ visObj = GetObjectVar("DropInColorCorral", corral, REPOBJ); if (!visObj) { return ObjFalse; } /*Get the field object*/ fieldObj = GetObjectVar("DropInColorCorral", object, REPOBJ); if (!fieldObj) { return ObjFalse; } if (!IsDataset(fieldObj)) { fieldObj = GetVar(fieldObj, MAINDATASET); } if (!IsDataset(fieldObj)) { WarnUser(CW_CANNOTDROPNONDATASET); return ObjFalse; } info = GetDatasetInfo(fieldObj); if ((info & DS_HASGEOMETRY) && (fieldObj != GetVar(visObj, MAINDATASET))) { WarnUser(CW_NOGEOMETRYERROR); return ObjFalse; } /*Create an icon for it*/ MakeVar(fieldObj, NAME); name = GetStringVar("DropInColorCorral", fieldObj, NAME); if (!name) { return ObjFalse; } MakeVar(fieldObj, DEFAULTICON); defaultIcon = GetVar(fieldObj, DEFAULTICON); if (defaultIcon) { ObjPtr locArray; real loc[2]; icon = NewObject(defaultIcon, 0); SetVar(icon, NAME, name); loc[0] = x; loc[1] = y; locArray = NewRealArray(1, 2L); CArray2Array(locArray, loc); SetVar(icon, ICONLOC, locArray); } else { icon = NewIcon(x, y, ICONQUESTION, GetString(name)); } /*Make the icon point to the field*/ SetVar(icon, REPOBJ, fieldObj); /*Make it the only icon in the corral*/ contents = NewList(); PrefixList(contents, icon); SetVar(corral, CONTENTS, contents); SetVar(contents, PARENT, corral); SetVar(icon, PARENT, corral); RecalcScroll(corral); /*Make this object the colored object*/ SetVar(visObj, COLOROBJ, fieldObj); /*Activate the show palette button*/ button = GetObjectVar("DropInColorCorral", corral, BUTTON); if (button) { ActivateButton(button, true); } ImInvalid(visObj); ImInvalid(corral); return ObjTrue; } static ObjPtr DropInDeformCorral(corral, object, x, y) ObjPtr corral, object; int x, y; /*Drops an icon in a deformation corral*/ { ObjPtr visObj; ObjPtr fieldObj; ObjPtr icon; ObjPtr name; ObjPtr defaultIcon; ObjPtr contents; ObjPtr button; long info; /*Find the visualization object*/ visObj = GetObjectVar("DropInDeformCorral", corral, REPOBJ); if (!visObj) { return ObjFalse; } /*Get the field object*/ fieldObj = GetObjectVar("DropInDeformCorral", object, REPOBJ); if (!fieldObj) { return ObjFalse; } if (!IsDataset(fieldObj)) { fieldObj = GetVar(fieldObj, MAINDATASET); } if (!IsDataset(fieldObj)) { WarnUser(CW_CANNOTDROPNONDATASET); return ObjFalse; } info = GetDatasetInfo(fieldObj); if ((info & DS_HASGEOMETRY)) { WarnUser(CW_NOGEOMETRYERROR); return ObjFalse; } /*Create an icon for it*/ MakeVar(fieldObj, NAME); name = GetStringVar("DropInDeformCorral", fieldObj, NAME); if (!name) { return ObjFalse; } MakeVar(fieldObj, DEFAULTICON); defaultIcon = GetVar(fieldObj, DEFAULTICON); if (defaultIcon) { ObjPtr locArray; real loc[2]; icon = NewObject(defaultIcon, 0); SetVar(icon, NAME, name); loc[0] = x; loc[1] = y; locArray = NewRealArray(1, 2L); CArray2Array(locArray, loc); SetVar(icon, ICONLOC, locArray); } else { icon = NewIcon(x, y, ICONQUESTION, GetString(name)); } /*Make the icon point to the field*/ SetVar(icon, REPOBJ, fieldObj); /*Make it the only icon in the corral*/ contents = NewList(); PrefixList(contents, icon); SetVar(corral, CONTENTS, contents); SetVar(contents, PARENT, corral); SetVar(icon, PARENT, corral); RecalcScroll(corral); /*Make this object the deformed object*/ SetVar(visObj, DEFORMOBJ, fieldObj); ImInvalid(visObj); ImInvalid(corral); return ObjTrue; } static ObjPtr AddColoredControls(object, panelContents) ObjPtr object, panelContents; /*Adds controls appropriate to a colored object to panelContents*/ { ObjPtr control, button, checkBox, corral, sw, textBox, slider, icon, radioGroup; ObjPtr colorObj, titleBox, win; ObjPtr var; int width, left, right, top, cellHeight, m1, m2; ObjPtr parent; /*Get the parent*/ parent = GetObjectVar("AddColoredControls", panelContents, PARENT); width = CWINWIDTH - 2 * CORRALBORDER - CWINCORRALWIDTH; left = MAJORBORDER; cellHeight = MAX(COLORWHEELWIDTH, ONECORRALHEIGHT) - 10; /*Precalculate the midlines for convenience*/ m1 = CWINHEIGHT - MAJORBORDER - cellHeight / 2; m1 += MINORBORDER; m2 = m1 - cellHeight - MAJORBORDER - TEXTBOXHEIGHT - TEXTBOXSEP; /*Create the color source corral*/ corral = NewIconCorral(NULLOBJ, left, left + ONECORRALWIDTH, m2 - ONECORRALHEIGHT / 2, m2 + ONECORRALHEIGHT / 2, 0); SetVar(corral, SINGLECORRAL, ObjTrue); SetVar(corral, TOPDOWN, ObjTrue); SetVar(corral, NAME, NewString("Color Field")); PrefixList(panelContents, corral); SetVar(corral, HELPSTRING, NewString("This corral shows the dataset that is used to give \ the visualization object its color, according to the position of the color switch. \ To replace it with another dataset, drag the icon of the other \ dataset into this corral.")); SetVar(corral, PARENT, panelContents); SetVar(corral, REPOBJ, object); SetMethod(corral, DROPINCONTENTS, DropInColorCorral); /*Create the color source text box*/ textBox = NewTextBox(left, left + ONECORRALWIDTH, m2 - ONECORRALHEIGHT / 2 - TEXTBOXSEP - TEXTBOXHEIGHT, m2 - ONECORRALHEIGHT / 2 - TEXTBOXSEP, 0, "Color Field Text", "Color Field"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, CENTERALIGN); /*Create the show palette button*/ win = parent; while (win && !IsWindow(win)) { win = GetVar(win, PARENT); } button = NewFunctionButton((WinInfoPtr) win, left, left + ONECORRALWIDTH, m2 - ONECORRALHEIGHT / 2 - TEXTBOXSEP - TEXTBOXHEIGHT - MINORBORDER - BUTTONHEIGHT, m2 - ONECORRALHEIGHT / 2 - TEXTBOXSEP - TEXTBOXHEIGHT - MINORBORDER, OF_EDIT_PALETTE); PrefixList(panelContents, button); SetVar(button, PARENT, panelContents); SetVar(corral, BUTTON, button); SetVar(button, REPOBJ, corral); SetVar(button, HELPSTRING, NewString("This button shows the palette of the field in the color \ corral. First select the icon in the color corral and then press this button. \ A new window will appear showing the palette controls.")); left += ONECORRALWIDTH + MINORBORDER; colorObj = GetVar(object, COLOROBJ); if (colorObj) { ObjPtr name, defaultIcon; /*Drop icon in corral, if need be*/ MakeVar(colorObj, NAME); name = GetVar(colorObj, NAME); MakeVar(colorObj, DEFAULTICON); defaultIcon = GetVar(colorObj, DEFAULTICON); if (defaultIcon) { icon = NewObject(defaultIcon, 0); SetVar(icon, NAME, name); } else { icon = NewIcon(0, 0, ICONQUESTION, GetString(name)); } SetVar(icon, REPOBJ, colorObj); SetVar(icon, ICONLOC, NULLOBJ); DropIconInCorral(corral, icon); } else { ActivateButton(button, false); } /*Create the color control*/ control = NewColorWheel(left - COLORWHEELWIDTH - MINORBORDER, left - MINORBORDER, m1 - COLORWHEELWIDTH / 2, m1 + COLORWHEELWIDTH / 2, "Fixed Color"); PrefixList(panelContents, control); SetVar(control, PARENT, panelContents); SetVar(control, REPOBJ, object); SetVar(control, HELPSTRING, NewString("This color wheel controls the base color of a \ visualization object. If the window is in full color mode and the object is light shaded, the \ final color of the object also depends on the lighting.")); var = GetFixedArrayVar("AddColoredControls", object, BASECOLOR, 1, 3L); if (!var) { real *baseColor; var = NewRealArray(1, 3L); baseColor = ELEMENTS(var); baseColor[0] = 1.0; baseColor[1] = 1.0; baseColor[2] = 1.0; SetVar(object, BASECOLOR, var); } AssocColorControlWithVar(control, object, BASECOLOR); /*Create the text box*/ textBox = NewTextBox(left - COLORWHEELWIDTH - MINORBORDER - 30, left - MINORBORDER + 30, m1 - cellHeight / 2 - TEXTBOXSEP - TEXTBOXHEIGHT, m1 - cellHeight / 2 - TEXTBOXSEP, 0, "Fixed Color Text", "Fixed Color"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, CENTERALIGN); /*Create the choice switch*/ MakeVar(object, COLORS); sw = NewSwitch(left, left + SWITCHWIDTH, m2 - cellHeight / 2 - (MAJORBORDER + TEXTBOXHEIGHT + TEXTBOXSEP) / 2, m1 + cellHeight / 2 + (MAJORBORDER + TEXTBOXHEIGHT + TEXTBOXSEP) / 2, 2, 0, GetVar(object, COLORS) ? 1 : 0, "Color Switch"); PrefixList(panelContents, sw); SetVar(sw, PARENT, panelContents); SetVar(sw, REPOBJ, object); SetVar(sw, HELPSTRING, NewString("This switch controls whether the color for the visualization object comes from a \ fixed color or from a field. The color is passed through a brightness control \ to produce the base color for the object.\n")); /*Link it to color wheel*/ SetVar(control, OTHERSWITCH, sw); /*Set change method*/ AssocDirectControlWithVar(sw, object, COLORS); left += SWITCHWIDTH + MINORBORDER; /*Create the brightness slider*/ var = GetRealVar("AddColoredControls", object, BRIGHTNESS); if (!var) { SetVar(object, BRIGHTNESS, NewReal(1.0)); } slider = NewSlider(left, left + SLIDERWIDTH, m1 - cellHeight / 2, m1 + cellHeight / 2, PLAIN, "Brightness"); if (!slider) { return ObjFalse; } PrefixList(panelContents, slider); SetVar(slider, PARENT, panelContents); SetVar(slider, HELPSTRING, NewString("This slider controls the brightness of \ a visualization object. Move the indicator up to make the object brighter or down \ to make it dimmer. If the object is lit, the eventual brightness will also depend \ on the lighting.")); SetSliderRange(slider, 1.0, 0.0, 0.0); AssocDirectControlWithVar(slider, object, BRIGHTNESS); /*Create the brightness text box*/ textBox = NewTextBox(left - MAJORBORDER - MINORBORDER, left + SLIDERWIDTH + MAJORBORDER + MINORBORDER, m1 - cellHeight / 2 - TEXTBOXSEP - TEXTBOXHEIGHT, m1 - cellHeight / 2 - TEXTBOXSEP, 0, "Brightness Text", "Brightness"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, CENTERALIGN); left += SLIDERWIDTH + MAJORBORDER; /*Create the unit switch*/ sw = NewSwitch(left, left + SSWITCHWIDTH, m1 - cellHeight / 2, m1 + cellHeight / 2, 1, 0, 0, "Unit Switch"); PrefixList(panelContents, sw); SetVar(sw, PARENT, panelContents); SetVar(sw, HELPSTRING, NewString("This switch shows that the color that has passed through \ the brightness control is used to produce the base color of the object.\n")); left += SSWITCHWIDTH + MINORBORDER; /*Create the color icon*/ icon = NewIcon(left + MINORBORDER + ICONSIZE / 2, m1, ICONCOLOR, "Base Color"); PrefixList(panelContents, icon); SetVar(icon, PARENT, panelContents); SetMethod(icon, PRESS, (FuncTyp) 0); left = width - MAJORBORDER - TRANSPARENTWIDTH; /*Create the translucent check box*/ checkBox = NewCheckBox(left, width, MAJORBORDER + CHECKBOXSPACING + CHECKBOXHEIGHT, MAJORBORDER + CHECKBOXSPACING + 2 * CHECKBOXHEIGHT, "Translucent", GetPredicate(object, ISTRANSLUCENT)); if (!checkBox) { return ObjFalse; } PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("If this box is checked, the visualization object will be drawn using screen door translucency.")); SetVar(checkBox, PARENT, parent); if (!GetVar(object, ISTRANSLUCENT)) { SetVar(object, ISTRANSLUCENT, ObjFalse); } AssocDirectControlWithVar(checkBox, object, ISTRANSLUCENT); /*Create the transparent check box*/ checkBox = NewCheckBox(left, width, MAJORBORDER + 2 * CHECKBOXSPACING + 2 * CHECKBOXHEIGHT, MAJORBORDER + 2 * CHECKBOXSPACING + 3 * CHECKBOXHEIGHT, "Transparent", GetPredicate(object, ISTRANSPARENT)); if (!checkBox) { return ObjFalse; } PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("If this box is checked, the visualization object will be drawn using alpha transparency. \ It may be useful to turn down the brightness of the object when using this feature. Transparency \ only works on hardware that supports blending transparency. If you don't \ have this hardware, try translucency instead.")); SetVar(checkBox, PARENT, parent); if (!GetVar(object, ISTRANSPARENT)) { SetVar(object, ISTRANSPARENT, ObjFalse); } AssocDirectControlWithVar(checkBox, object, ISTRANSPARENT); #ifdef GRAPHICS if (!hasTransparency) ActivateButton(checkBox, false); #endif /*Create the alternate translucent check box*/ checkBox = NewCheckBox(left, width, MAJORBORDER, MAJORBORDER + CHECKBOXHEIGHT, "Alternate Translucent", GetPredicate(object, ALTTRANSLUCENT)); if (!checkBox) { return ObjFalse; } PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("If this box is checked, the visualization object will be drawn using screen door translucency. \ It uses an alternate pattern different from regular translucency. Two translucent objects \ with the same form of translucency will obscure each other, but two with different forms \ will not.")); SetVar(checkBox, PARENT, parent); if (!GetVar(object, ALTTRANSLUCENT)) { SetVar(object, ALTTRANSLUCENT, ObjFalse); } AssocDirectControlWithVar(checkBox, object, ALTTRANSLUCENT); /*Create radio button group for color shading*/ right = width - MAJORBORDER; top = MAJORBORDER + CHECKBOXHEIGHT * 5 + CHECKBOXSPACING * 3 + MAJORBORDER + MINORBORDER; radioGroup = NewRadioButtonGroup("Color Shading Radio"); SetVar(radioGroup, HELPSTRING, NewString("These radio buttons allow you to change the way a visualization \ object is shaded with color. This interacts in interesting ways with the light shading. \ Experiment with different combinations.")); /*Title box around it*/ titleBox = NewTitleBox(left - MINORBORDER, right + MINORBORDER, top - 2 * CHECKBOXHEIGHT - CHECKBOXSPACING - MINORBORDER, top + CHECKBOXSPACING + TITLEBOXTOP + MINORBORDER, "Color Shading"); PrefixList(panelContents, titleBox); SetVar(titleBox, PARENT, panelContents); checkBox = NewRadioButton(left, right, top - CHECKBOXHEIGHT, top, "Flat"); SetVar(checkBox, HELPSTRING, NewString("This button specifies that the visualization object will \ be flatly shaded with color. This only has a visual effect when the object \ is color shaded by another field. It may be faster than smooth shading on \ some systems. The combination of flat light and flat color shading may be even faster.")); AddRadioButton(radioGroup, checkBox); top -= CHECKBOXHEIGHT + CHECKBOXSPACING; checkBox = NewRadioButton(left, right, top - CHECKBOXHEIGHT, top, "Smooth"); SetVar(checkBox, HELPSTRING, NewString("This button specifies that the visualization object will \ be smoothly shaded with color. This only has a visual effect when the object \ is color shaded with another field. It may be slower than flat shading on \ some systems.")); AddRadioButton(radioGroup, checkBox); top -= CHECKBOXHEIGHT + CHECKBOXSPACING; /*Add the radio button group*/ PrefixList(panelContents, radioGroup); SetVar(radioGroup, PARENT, panelContents); /*Set its value based on color shading*/ SetValue(radioGroup, NewInt(GetPredicate(object, COLORSHADING) ? 1 : 0)); /*Associate it with the variable*/ AssocDirectControlWithVar(radioGroup, object, COLORSHADING); return ObjTrue; } static ObjPtr AddDeformedControls(object, panelContents) ObjPtr object, panelContents; /*Adds controls appropriate to a deformed object to panelContents*/ { ObjPtr control, button, checkBox, corral, sw, textBox, slider, icon, radioGroup; ObjPtr deformObj, titleBox; ObjPtr var; int width, left, right, top, bottom, cellHeight, m1, m2; real baseColor[3]; real hs[2], dummy; ObjPtr parent; /*Get the parent*/ parent = GetObjectVar("AddDeformedControls", panelContents, PARENT); width = CWINWIDTH - 2 * CORRALBORDER - CWINCORRALWIDTH; left = MAJORBORDER; cellHeight = ONECORRALHEIGHT; /*Precalculate the midlines for convenience*/ m1 = CWINHEIGHT - MAJORBORDER - cellHeight / 2; m1 += MINORBORDER; m2 = m1 - cellHeight - MAJORBORDER - TEXTBOXHEIGHT - TEXTBOXSEP; /*Create the deform source corral*/ corral = NewIconCorral(NULLOBJ, left, left + ONECORRALWIDTH, m2 - ONECORRALHEIGHT / 2, m2 + ONECORRALHEIGHT / 2, 0); SetVar(corral, SINGLECORRAL, ObjTrue); SetVar(corral, TOPDOWN, ObjTrue); SetVar(corral, NAME, NewString("Deform Field")); PrefixList(panelContents, corral); SetVar(corral, HELPSTRING, NewString("This corral shows the dataset that is used to \ deform the visualization object. \ To replace it with another dataset, drag the icon of the other \ dataset into this corral.")); SetVar(corral, PARENT, panelContents); SetVar(corral, REPOBJ, object); SetMethod(corral, DROPINCONTENTS, DropInDeformCorral); /*Create the deform source text box*/ textBox = NewTextBox(left, left + ONECORRALWIDTH, m2 - ONECORRALHEIGHT / 2 - TEXTBOXSEP - TEXTBOXHEIGHT, m2 - ONECORRALHEIGHT / 2 - TEXTBOXSEP, 0, "Deform Field Text", "Deform Field"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, CENTERALIGN); left += ONECORRALWIDTH + MINORBORDER; deformObj = GetVar(object, DEFORMOBJ); if (deformObj) { ObjPtr name, defaultIcon; /*Drop icon in corral, if need be*/ MakeVar(deformObj, NAME); name = GetVar(deformObj, NAME); MakeVar(deformObj, DEFAULTICON); defaultIcon = GetVar(deformObj, DEFAULTICON); if (defaultIcon) { icon = NewObject(defaultIcon, 0); SetVar(icon, NAME, name); } else { icon = NewIcon(0, 0, ICONQUESTION, GetString(name)); } SetVar(icon, REPOBJ, deformObj); SetVar(icon, ICONLOC, NULLOBJ); DropIconInCorral(corral, icon); } /*Create the constant deformation control*/ var = GetRealVar("AddDeformedControls", object, DEFCONSTANT); if (!var) { SetVar(object, DEFCONSTANT, NewReal(0.0)); } textBox = NewTextBox(MAJORBORDER, left - MINORBORDER, m1 - EDITBOXHEIGHT / 2, m1 + EDITBOXHEIGHT / 2, EDITABLE + WITH_PIT + ONE_LINE, "Fixed Deformation", ""); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); AssocTextRealControlWithVar(textBox, object, DEFCONSTANT, minusInf, plusInf, TR_NE_BOTTOM | TR_NE_TOP); SetVar(textBox, HELPSTRING, NewString("This text box gives a constant \ deformation when it is selected by the switch.")); SetVar(textBox, WHICHVAR, NewSymbol(DEFCONSTANT)); SetTextAlign(textBox, RIGHTALIGN); /*Create the text box*/ textBox = NewTextBox(MAJORBORDER - 20, left - MINORBORDER + 20, m1 - EDITBOXHEIGHT / 2 - TEXTBOXSEP - 2 * TEXTBOXHEIGHT, m1 - EDITBOXHEIGHT / 2 - TEXTBOXSEP, 0, "Fixed Deformation Text", "Fixed\nDeformation"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, CENTERALIGN); SetVar(textBox, REPOBJ, object); /*Create the choice switch*/ MakeVar(object, DEFORMSWITCH); var = GetIntVar("AddDeformedControls", object, DEFORMSWITCH); sw = NewSwitch(left, left + SWITCHWIDTH, m2 - cellHeight / 2 - (MAJORBORDER + TEXTBOXHEIGHT + TEXTBOXSEP) / 2, m1 + cellHeight / 2 + (MAJORBORDER + TEXTBOXHEIGHT + TEXTBOXSEP) / 2, 2, 0, var ? GetInt(var) : 0, "Deform Switch"); PrefixList(panelContents, sw); SetVar(sw, PARENT, panelContents); SetVar(sw, REPOBJ, object); SetVar(sw, HELPSTRING, NewString("This switch controls whether the \ deformation of the visualization object comes from a \ field or from a fixed deformation.")); AssocDirectControlWithVar(sw, object, DEFORMSWITCH); left += SWITCHWIDTH + MINORBORDER; /*Create the * text box*/ right = left + MINORBORDER; textBox = TemplateTextBox(VisDeformTemplate, "Splat", 0, "*"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextFont(textBox, "Courier-Bold"); SetTextSize(textBox, 18); left = right + MINORBORDER; /*Create the deformation factor*/ var = GetRealVar("AddDeformedControls", object, DEFFACTOR); if (!var) { SetVar(object, DEFFACTOR, NewReal(0.0)); } right = left + DEFORMEDITWIDTH; textBox = TemplateTextBox(VisDeformTemplate, "Deformation Factor", EDITABLE + WITH_PIT + ONE_LINE, ""); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); AssocTextRealControlWithVar(textBox, object, DEFFACTOR, minusInf, plusInf, TR_NE_BOTTOM | TR_NE_TOP); SetVar(textBox, HELPSTRING, NewString("This text box gives a multiplier \ for the deformation provided by the switch.")); SetTextAlign(textBox, RIGHTALIGN); /*Create the text box*/ textBox = TemplateTextBox(VisDeformTemplate, "Factor Text", 0, "Factor"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, CENTERALIGN); SetVar(textBox, REPOBJ, object); left = right + MINORBORDER; /*Create the + text box*/ right = left + MINORBORDER; textBox = TemplateTextBox(VisDeformTemplate, "Plus", 0, "+"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextFont(textBox, "Courier-Bold"); SetTextSize(textBox, 18); left = right + MINORBORDER; /*Create the deformation offset*/ var = GetRealVar("AddDeformedControls", object, DEFOFFSET); if (!var) { SetVar(object, DEFOFFSET, NewReal(0.0)); } right = left + DEFORMEDITWIDTH; textBox = TemplateTextBox(VisDeformTemplate, "Deformation Offset", EDITABLE + WITH_PIT + ONE_LINE, tempStr); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); AssocTextRealControlWithVar(textBox, object, DEFOFFSET, minusInf, plusInf, TR_NE_BOTTOM | TR_NE_TOP); SetVar(textBox, HELPSTRING, NewString("This text box gives an offset \ for the deformation provided by the switch, multiplied by the multiplier.")); SetVar(textBox, WHICHVAR, NewSymbol(DEFOFFSET)); SetTextAlign(textBox, RIGHTALIGN); /*Create the text box*/ textBox = TemplateTextBox(VisDeformTemplate, "Offset Text", 0, "Offset"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, CENTERALIGN); SetVar(textBox, REPOBJ, object); left = right + MINORBORDER; /*Create the Invert Surface check box*/ left = MAJORBORDER; bottom = MAJORBORDER; top = bottom + CHECKBOXHEIGHT; button = NewCheckBox(left, right, bottom, top, "Invert Surface", GetPredicate(object, REVERSESENSE)); PrefixList(panelContents, button); SetVar(button, PARENT, panelContents); AssocDirectControlWithVar(button, object, REVERSESENSE); return ObjTrue; } static ObjPtr AddSurfaceControls(object, panelContents) ObjPtr object, panelContents; /*Adds controls appropriate to a surface object to panelContents*/ { ObjPtr textBox, name, repObj, control, icon, checkBox, radioGroup, titleBox; ObjPtr var; ObjPtr panel; int width; real initValue; real shininess, specularity; int left, top, right, bottom, mid; ObjPtr contents; ObjPtr parent; ObjPtr scale; /*Get the parent*/ parent = GetObjectVar("AddColoredControls", panelContents, PARENT); width = CWINWIDTH - 2 * CORRALBORDER - CWINCORRALWIDTH; var = GetVar(object, SHINVAL); if (var && IsReal(var)) { shininess = initValue = GetReal(var); } else { shininess = initValue = 80.0; } var = GetVar(object, SPECVAL); if (var && IsReal(var)) { specularity = initValue = GetReal(var); } else { specularity = initValue = 0.2; } /*Create the highlights control*/ top = CWINHEIGHT - MINORBORDER; left = MINORBORDER; bottom = MINORBORDER; control = NewXYControl(left + ICONSIZE / 2 + ICONXYSEP, left + ICONSIZE / 2 + ICONXYSEP + XYCONTROLWIDTH, top - ICONSIZE / 2 - ICONXYSEP - XYCONTROLWIDTH, top - ICONSIZE / 2 - ICONXYSEP,"Highlights"); if (!control) return ObjFalse; PrefixList(panelContents, control); SetVar(control, PARENT, panelContents); SetXYControlLimits(control, 5.0, 128.0, 0.0, 1.0); SetXYControlValue(control, shininess, specularity); SetMethod(control, CHANGEDVALUE, ChangeReflection); DeclareIndirectDependency(control, APPEARANCE, REPOBJ, SHINVAL); DeclareIndirectDependency(control, APPEARANCE, REPOBJ, SPECVAL); SetMethod(control, APPEARANCE, MakeReflectionAppearance); SetVar(control, HELPSTRING, NewString("This control changes the specular highlights \ of a visualization object. Move the indicator up to make the highlights brighter and down \ to make them dimmer. Move it right to make the highlights sharper and left \ to make them dimmer. The icons at the four corners of the control give a rough \ idea of the effect. The effect on real visualization objects, however, is often quite \ subtle.")); SetVar(control, REPOBJ, object); /*Create associated icons*/ icon = NewIcon(left + ICONSIZE / 2, top - XYCONTROLWIDTH - ICONSIZE / 2 - 2 * ICONXYSEP + ICONSHADOW, ICONDIMDIF, (char *) 0); if (!icon) return ObjFalse; PrefixList(panelContents, icon); SetVar(icon, PARENT, panelContents); SetMethod(icon, PRESS, (FuncTyp) 0); icon = NewIcon(left + ICONSIZE / 2, top - ICONSIZE / 2, ICONBRTDIF, (char *) 0); if (!icon) return ObjFalse; PrefixList(panelContents, icon); SetVar(icon, PARENT, panelContents); SetMethod(icon, PRESS, (FuncTyp) 0); icon = NewIcon(left + XYCONTROLWIDTH + ICONSIZE / 2 + 2 * ICONXYSEP, top - XYCONTROLWIDTH - ICONSIZE / 2 - 2 * ICONXYSEP + ICONSHADOW, ICONDIMTIGHT, (char *) 0); if (!icon) return ObjFalse; PrefixList(panelContents, icon); SetVar(icon, PARENT, panelContents); SetMethod(icon, PRESS, (FuncTyp) 0); icon = NewIcon(left + XYCONTROLWIDTH + ICONSIZE / 2 + 2 * ICONXYSEP, top - ICONSIZE / 2, ICONBRTTIGHT, (char *) 0); if (!icon) return ObjFalse; PrefixList(panelContents, icon); SetVar(icon, PARENT, panelContents); SetMethod(icon, PRESS, (FuncTyp) 0); /*Create the highlights text box*/ textBox = NewTextBox(left, left + 2 * ICONXYSEP + XYCONTROLWIDTH + ICONSIZE, top - XYCONTROLWIDTH - ICONSIZE - ICONXYSEP - TEXTBOXHEIGHT, top - XYCONTROLWIDTH - ICONSIZE - ICONXYSEP, 0, "Highlights Text", "Highlights"); if (!textBox) return ObjFalse; PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, CENTERALIGN); mid = left + ICONXYSEP + (XYCONTROLWIDTH + ICONSIZE) / 2; /*Create the highlight color control*/ control = NewColorWheel(mid - COLORWHEELWIDTH / 2, mid + COLORWHEELWIDTH / 2, bottom + TEXTBOXHEIGHT + TEXTBOXSEP, bottom + TEXTBOXHEIGHT + TEXTBOXSEP + COLORWHEELWIDTH, "Highlight Color"); PrefixList(panelContents, control); SetVar(control, PARENT, panelContents); SetVar(control, HELPSTRING, NewString("This color wheel controls the color of the specular highlights \ on a visualization object. The effects are usually quite subtle and are most useful on objects with \ a fixed base color.")); var = GetVar(object, HIGHLIGHTCOLOR); if (!var) { real *highlightColor; var = NewRealArray(1, 3L); highlightColor[0] = 1.0; highlightColor[1] = 1.0; highlightColor[2] = 1.0; SetVar(object, HIGHLIGHTCOLOR, var); } AssocColorControlWithVar(control, object, HIGHLIGHTCOLOR); /*Create the text box*/ textBox = NewTextBox(left, 2 * mid - left, bottom, bottom + TEXTBOXHEIGHT, 0, "Highlight Color Text", "Highlight Color"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, CENTERALIGN); left = width - MAJORBORDER - TRANSPARENTWIDTH; bottom = MAJORBORDER; /*Create the transparent check box*/ checkBox = NewCheckBox(left, width, bottom, bottom + CHECKBOXHEIGHT, "Transparent", GetPredicate(object, ISTRANSPARENT)); if (!checkBox) { return ObjFalse; } PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("If this box is checked, the visualization object will be drawn using alpha transparency. \ It may be useful to turn down the brightness of the object when using this feature. Transparency \ only works on hardware that supports blending transparency. If you don't \ have this hardware, try translucency instead.")); SetVar(checkBox, PARENT, parent); if (!GetVar(object, ISTRANSPARENT)) { SetVar(object, ISTRANSPARENT, ObjFalse); } AssocDirectControlWithVar(checkBox, object, ISTRANSPARENT); #ifdef GRAPHICS if (!hasTransparency) ActivateButton(checkBox, false); #endif bottom += CHECKBOXHEIGHT + MINORBORDER; /*Create the translucent check box, or use the existing one*/ checkBox = NewCheckBox(left, width, bottom, bottom + CHECKBOXHEIGHT, "Translucent", GetPredicate(object, ISTRANSLUCENT)); if (!checkBox) { return ObjFalse; } PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("If this box is checked, the visualization object will be drawn using screen door translucency.")); SetVar(checkBox, PARENT, parent); if (!GetVar(object, ISTRANSLUCENT)) { SetVar(object, ISTRANSLUCENT, ObjFalse); } AssocDirectControlWithVar(checkBox, object, ISTRANSLUCENT); bottom += CHECKBOXHEIGHT + MINORBORDER; /*Create the two-sided check box*/ checkBox = NewCheckBox(left, width, bottom, bottom + CHECKBOXHEIGHT, "2-Sided Lighting", GetPredicate(object, TWOSIDEDSURFACE)); if (!checkBox) { return ObjFalse; } PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("If this box is checked, the visualization object will be drawn \ with lighting on both sided of the surface.")); SetVar(checkBox, PARENT, parent); if (!GetVar(object, TWOSIDEDSURFACE)) SetVar(object, TWOSIDEDSURFACE, NewInt(0)); AssocDirectControlWithVar(checkBox, object, TWOSIDEDSURFACE); bottom += CHECKBOXHEIGHT + MINORBORDER; /*Create radio button group for light shading*/ right = width - MAJORBORDER; top = bottom + CHECKBOXHEIGHT * 3 + CHECKBOXSPACING + MINORBORDER; radioGroup = NewRadioButtonGroup("Light Shading Radio"); SetVar(radioGroup, HELPSTRING, NewString("These radio buttons allow you to change the way a visualization \ object is shaded with the light sources. Light shading will only work in windows set to \ full color mode. This control interacts in interesting ways with the color shading. \ Experiment with different combinations.")); /*Title box around it*/ titleBox = NewTitleBox(left - MINORBORDER, right + MINORBORDER, bottom, top + TITLEBOXTOP + MINORBORDER, "Light Shading"); PrefixList(panelContents, titleBox); SetVar(titleBox, PARENT, panelContents); checkBox = NewRadioButton(left, right, top - CHECKBOXHEIGHT, top, "None"); SetVar(checkBox, HELPSTRING, NewString("This button specifies that the visualization object will \ not be shaded with light at all. This will produce a silhouette effect when the \ color is fixed and will produce an intensely colored surface with no \ lighting cues when the color is from a field.")); AddRadioButton(radioGroup, checkBox); top -= CHECKBOXHEIGHT + CHECKBOXSPACING; checkBox = NewRadioButton(left, right, top - CHECKBOXHEIGHT, top, "Flat"); SetVar(checkBox, HELPSTRING, NewString("This button specifies that the visualization object will \ be flatly shaded with light. This may be faster on some systems than smooth light \ shading. The combination of flat light and flat color shading may be even faster.")); AddRadioButton(radioGroup, checkBox); top -= CHECKBOXHEIGHT + CHECKBOXSPACING; checkBox = NewRadioButton(left, right, top - CHECKBOXHEIGHT, top, "Smooth"); SetVar(checkBox, HELPSTRING, NewString("This button specifies that the visualization object will \ be smoothly shaded with light. This may be slower on some systems than flat light \ shading.")); AddRadioButton(radioGroup, checkBox); top -= CHECKBOXHEIGHT + CHECKBOXSPACING; /*Add the radio button group*/ PrefixList(panelContents, radioGroup); SetVar(radioGroup, PARENT, panelContents); /*Set its value based on color shading*/ var = GetVar(object, LIGHTSHADING); if (!var) { SetVar(object, LIGHTSHADING, NewInt(0)); } AssocDirectControlWithVar(radioGroup, object, LIGHTSHADING); /*Add checkboxes for draw surface and draw wire frame*/ top = CWINHEIGHT - MAJORBORDER; right = width - MAJORBORDER; left = right - SCDRAWBOXLENGTH; checkBox = NewCheckBox(left, right, top - CHECKBOXHEIGHT, top, "Draw Surface", GetPredicate(object, DRAWSURFACE)); SetVar(checkBox, PARENT, panelContents); PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("When this box is checked, the surface of the visualization will \ be drawn. When it is not checked, the surface will not be drawn.")); if (!GetVar(object, DRAWSURFACE)) SetVar(object, DRAWSURFACE, NewInt(0)); AssocDirectControlWithVar(checkBox, object, DRAWSURFACE); top -= CHECKBOXHEIGHT + CHECKBOXSPACING; #ifdef GRAPHOBJ checkBox = NewCheckBox(left, right, top - CHECKBOXHEIGHT, top, "Cache Graphics", GetPredicate(object, CACHEGRAPHICS)); SetVar(checkBox, PARENT, panelContents); PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("When this box is checked, the graphics of the visualization \ object will be cached in a graphical object. This will speed up drawing during interaction \ but will use a lot of memory.")); if (!GetVar(object, CACHEGRAPHICS)) SetVar(object, CACHEGRAPHICS, NewInt(0)); AssocDirectControlWithVar(checkBox, object, CACHEGRAPHICS); top -= CHECKBOXHEIGHT + CHECKBOXSPACING; #endif return ObjTrue; } static ObjPtr AddLineControls(object, panelContents) ObjPtr object, panelContents; /*Adds controls appropriate to a line object to panelContents*/ { ObjPtr checkBox, textBox, slider, scale; ObjPtr var; /*Add checkbox for draw wire frame*/ checkBox = TemplateCheckBox(VisWireFrameTemplate, "Draw Lines", GetPredicate(object, DRAWWIREFRAME)); SetVar(checkBox, PARENT, panelContents); PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("When this box is checked, a wire frame representation of the visualization will \ be drawn. When it is not checked, the wire frame will not be drawn.")); if (!GetVar(object, DRAWWIREFRAME)) SetVar(object, DRAWWIREFRAME, NewInt(0)); AssocDirectControlWithVar(checkBox, object, DRAWWIREFRAME); checkBox = TemplateCheckBox(VisWireFrameTemplate, "Depth Cueing", GetPredicate(object, DEPTHCUELINES)); SetVar(checkBox, PARENT, panelContents); PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("When this box is checked, the wire frame will be drawn with depth \ cueing, which makes closer parts of the object appear brighter. You may need to \ adjust the near and far clipping planes in the Observer controls to bring out the full \ range of brightness. When it is not checked, the wire frame will be drawn without depth cueing.")); if (!GetVar(object, DEPTHCUELINES)) SetVar(object, DEPTHCUELINES, NewInt(0)); AssocDirectControlWithVar(checkBox, object, DEPTHCUELINES); if (!hasDepthCue) { ActivateButton(checkBox, false); } checkBox = TemplateCheckBox(VisWireFrameTemplate, "Antialiasing", GetPredicate(object, ANTIALIASLINES)); SetVar(checkBox, PARENT, panelContents); PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("When this box is checked, the wire frame will be drawn antialiased. \ This will make the lines appear smoother, while sacrificing some speed. \ When it is not checked, the wire frame will be drawn without antialiasing.\n\ \n\ Antialiasing only works if your computer supports it and the renderer is in \ full color mode. Some models of workstation cannot display antialised lines of \ width greater than one. Antialiasing may interact with other objects in the scene. \ In general, it is good in scenes where there are few or no surfaces. Experiment \ to find out if antialiasing is good for your data.")); if (!GetVar(object, ANTIALIASLINES)) SetVar(object, ANTIALIASLINES, NewInt(0)); AssocDirectControlWithVar(checkBox, object, ANTIALIASLINES); if (!hasAntialiasedLines) { ActivateButton(checkBox, false); } scale = TemplateScale(VisWireFrameTemplate, "Width Scale", SO_TOP, false); SetScaleStepPixels(scale, 10); PrefixList(panelContents, scale); SetVar(scale, PARENT, panelContents); /*Make the line width slider*/ slider = TemplateSlider(VisWireFrameTemplate, "Width Slider", SCALE); PrefixList(panelContents, slider); SetVar(slider, PARENT, panelContents); LinkScale(scale, slider); var = GetVar(object, LINEWIDTH); SetSliderRange(slider, 10.0, 1.0, 1.0); AssocDirectControlWithVar(slider, object, LINEWIDTH); if (!var) SetVar(object, LINEWIDTH, NewReal(1.0)); SetVar(slider, HELPSTRING, NewString("This slider controls the width of \ the wire frame of the visualization object in screen pixels.")); /*Make a legend*/ textBox = TemplateTextBox(VisWireFrameTemplate, "Line Width Legend", 0, "Line Width"); SetVar(textBox, PARENT, panelContents); PrefixList(panelContents, textBox); SetTextAlign(textBox, RIGHTALIGN); SetVar(textBox, HELPSTRING, NewString("This text boxc controls the width of \ the wire frame of the visualization object in screen pixels.")); /*Make a slider readout*/ textBox = TemplateTextBox(VisWireFrameTemplate, "Width Slider Readout", EDITABLE + WITH_PIT + ONE_LINE, ""); SetVar(textBox, REPOBJ, object); SetVar(textBox, PARENT, panelContents); PrefixList(panelContents, textBox); SetTextAlign(textBox, RIGHTALIGN); SliderReadout(slider, textBox); /*And "pixels"*/ textBox = TemplateTextBox(VisWireFrameTemplate, "Pixels Legend", 0, "Pixels"); SetVar(textBox, PARENT, panelContents); PrefixList(panelContents, textBox); return ObjTrue; } static ObjPtr AddDotsControls(object, panelContents) ObjPtr object, panelContents; /*Adds controls appropriate to a dots object to panelContents*/ { ObjPtr checkBox, textBox, slider; ObjPtr var; /*Add checkbox for draw wire frame*/ checkBox = TemplateCheckBox(VisDotsTemplate, "Draw Dots", GetPredicate(object, DRAWDOTS)); SetVar(checkBox, PARENT, panelContents); PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("When this box is checked, a dots representation of the visualization will \ be drawn. When it is not checked, the dots will not be drawn.")); if (!GetVar(object, DRAWDOTS)) SetVar(object, DRAWDOTS, NewInt(0)); AssocDirectControlWithVar(checkBox, object, DRAWDOTS); checkBox = TemplateCheckBox(VisDotsTemplate, "Depth Cueing", GetPredicate(object, DEPTHCUEDOTS)); SetVar(checkBox, PARENT, panelContents); PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("When this box is checked, the dots will be drawn with depth \ cueing, which makes closer parts of the object appear brighter. You may need to \ adjust the near and far clipping planes in the Observer controls to bring out the full \ range of brightness. When it is not checked, the dots will be drawn without depth cueing.")); if (!GetVar(object, DEPTHCUEDOTS)) SetVar(object, DEPTHCUEDOTS, NewInt(0)); AssocDirectControlWithVar(checkBox, object, DEPTHCUEDOTS); if (!hasDepthCue) { ActivateButton(checkBox, false); } checkBox = TemplateCheckBox(VisDotsTemplate, "Antialiasing", GetPredicate(object, ANTIALIASDOTS)); SetVar(checkBox, PARENT, panelContents); PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("When this box is checked, the dots will be drawn antialiased. \ This will make the dots appear smoother, while sacrificing some speed. \ When it is not checked, the dots will be drawn without antialiasing.\n\ \n\ Antialiasing only works if your computer supports it and the renderer is in \ full color mode. Some models of workstation cannot display antialised dots of \ soze greater than one. Antialiasing may interact with other objects in the scene. \ In general, it is good in scenes where there are few or no surfaces. Experiment \ to find out if antialiasing is good for your data.")); if (!GetVar(object, ANTIALIASDOTS)) SetVar(object, ANTIALIASDOTS, NewInt(0)); AssocDirectControlWithVar(checkBox, object, ANTIALIASDOTS); if (!hasAntialiasedPoints) { ActivateButton(checkBox, false); } checkBox = TemplateCheckBox(VisDotsTemplate, "Bigger Dots", GetPredicate(object, BIGGERDOTS)); SetVar(checkBox, PARENT, panelContents); PrefixList(panelContents, checkBox); SetVar(checkBox, HELPSTRING, NewString("When this box is checked, the dots will be drawn a little larger. \ On some systems, bigger dots cannot be antialiased")); if (!GetVar(object, BIGGERDOTS)) SetVar(object, BIGGERDOTS, NewInt(0)); AssocDirectControlWithVar(checkBox, object, BIGGERDOTS); return ObjTrue; } Bool GetBounds(object, bounds) ObjPtr object; real bounds[6]; /*Gets the bounds of an object*/ { int k; real *meat; real temp; ObjPtr boundsArray; MakeVar(object, BOUNDS); boundsArray = GetVar(object, BOUNDS); if (boundsArray) { meat = ELEMENTS(boundsArray); for (k = 0; k < 6; ++k) { bounds[k] = meat[k]; } if (bounds[0] > bounds[1]) { temp = bounds[0]; bounds[0] = bounds[1]; bounds[1] = temp; } if (bounds[2] > bounds[3]) { temp = bounds[2]; bounds[2] = bounds[3]; bounds[3] = temp; } if (bounds[4] > bounds[5]) { temp = bounds[4]; bounds[4] = bounds[5]; bounds[5] = temp; } return true; } else { return false; } } static Bool GetTicParams(object, lowTic, nTics, ticSpace, initMinor, majorEvery) ObjPtr object; real lowTic[3]; int nTics[3]; real ticSpace[3]; int initMinor[3]; int majorEvery[3]; /*Returns tic parameters for object object into lowTic[d] = Value of lowest tic mark for dim d nTics[d] = Number of total tics for dim d ticSpace[d] = Spacing between tic marks initMinor[d] = Number of minor tics to start for dim d majorEvery[d] = A major tic every majorEvery[d] + 1 tics */ { ObjPtr formObj; real bounds[6]; int k; ObjPtr repObj; /*Get the bounds*/ if (!GetBounds(object, bounds)) { return false; } repObj = GetVar(object, MAINDATASET); if (!repObj) repObj = GetObjectVar("GetTicParams", object, REPOBJ); if (!repObj) { return false; } /*See if the object has a data form*/ formObj = GetVar(repObj, DATAFORM); if (formObj) { ObjPtr dimsArray; real dims[3]; /*Make major tics go around grid points*/ dimsArray = GetFixedArrayVar("GetTicParams", formObj, DIMENSIONS, 1, 3L); if (!dimsArray) { return false; } Array2CArray(dims, dimsArray); for (k = 0; k < 3; ++k) { lowTic[k] = bounds[k + k]; nTics[k] = (int) (dims[k] + 4.0 * (dims[k] - 1)); ticSpace[k] = (bounds[k + k + 1] - bounds[k + k]) / (dims[k] - 1.0) / 5; initMinor[k] = 0; majorEvery[k] = 4; } return true; } else { /*Guess tic marks*/ return false; } } static ObjPtr DrawBounded(object) ObjPtr object; /*Draw stuff around a bounded object*/ { #ifdef GRAPHICS ObjPtr flagsObj; int flags; real bounds[6], scaledBounds[6]; real maxSize = 0; ObjPtr dataset; ObjPtr var; Bool drawEditBox; int outlineBox; dataset = GetVar(object, MAINDATASET); if (!dataset) dataset = GetObjectVar("DrawBounded", object, REPOBJ); if (!dataset) { return ObjFalse; } flagsObj = GetVar(object, BBFLAGS); if (flagsObj) { flags = GetInt(flagsObj); } else { flags = 0; } if (GetBounds(object, bounds)) { if (bounds[1] - bounds[0] > maxSize) maxSize = bounds[1] - bounds[0]; if (bounds[3] - bounds[2] > maxSize) maxSize = bounds[3] - bounds[2]; if (bounds[5] - bounds[4] > maxSize) maxSize = bounds[5] - bounds[4]; scaledBounds[0] = bounds[0]; scaledBounds[1] = bounds[1]; scaledBounds[2] = bounds[2]; scaledBounds[3] = bounds[3]; scaledBounds[4] = bounds[4]; scaledBounds[5] = bounds[5]; } else { return NULLOBJ; } var = GetVar(object, BOUNDSBOX); if (var) { outlineBox = GetInt(var); } else { outlineBox = 0; } if (DQ_OUTLINE >= minDrawingQuality && DQ_OUTLINE <= maxDrawingQuality) { /*Draw the outline*/ /*See if we need to draw the edit box*/ drawEditBox = false; #if 0 if (IsSelected(object)) { var = GetVar(curSpace, EDITTOOL); if (var) { if (GetInt(var) == ST_3DFINGER) { drawEditBox = true; } } } #endif if (outlineBox == OB_LINES) { /*Lines*/ Bool antiAlias = false; var = GetVar(object, LINEWIDTH); if (var) { int width; width = GetReal(var); if (width < 1) width = 1; SetLineWidth(width); } SetUIColor(UIWHITE); /*Draw bottom square*/ qualityDrawnSoFar = MAX(qualityDrawnSoFar, DQ_OUTLINE); DrawSpaceLine(scaledBounds[0], scaledBounds[2], scaledBounds[4], scaledBounds[1], scaledBounds[2], scaledBounds[4]); DrawSpaceLine(scaledBounds[1], scaledBounds[2], scaledBounds[4], scaledBounds[1], scaledBounds[3], scaledBounds[4]); DrawSpaceLine(scaledBounds[1], scaledBounds[3], scaledBounds[4], scaledBounds[0], scaledBounds[3], scaledBounds[4]); DrawSpaceLine(scaledBounds[0], scaledBounds[3], scaledBounds[4], scaledBounds[0], scaledBounds[2], scaledBounds[4]); /*Draw top square*/ DrawSpaceLine(scaledBounds[0], scaledBounds[2], scaledBounds[5], scaledBounds[1], scaledBounds[2], scaledBounds[5]); DrawSpaceLine(scaledBounds[1], scaledBounds[2], scaledBounds[5], scaledBounds[1], scaledBounds[3], scaledBounds[5]); DrawSpaceLine(scaledBounds[1], scaledBounds[3], scaledBounds[5], scaledBounds[0], scaledBounds[3], scaledBounds[5]); DrawSpaceLine(scaledBounds[0], scaledBounds[3], scaledBounds[5], scaledBounds[0], scaledBounds[2], scaledBounds[5]); /*Draw remaining sides*/ DrawSpaceLine(scaledBounds[0], scaledBounds[2], scaledBounds[4], scaledBounds[0], scaledBounds[2], scaledBounds[5]); DrawSpaceLine(scaledBounds[1], scaledBounds[2], scaledBounds[4], scaledBounds[1], scaledBounds[2], scaledBounds[5]); DrawSpaceLine(scaledBounds[1], scaledBounds[3], scaledBounds[4], scaledBounds[1], scaledBounds[3], scaledBounds[5]); DrawSpaceLine(scaledBounds[0], scaledBounds[3], scaledBounds[4], scaledBounds[0], scaledBounds[3], scaledBounds[5]); if (hasAntialiasedLines && rgbp && GetPredicate(object, ANTIALIASLINES)) { linesmooth(SML_ON); blendfunction(BF_SA, BF_MSA); subpixel(TRUE); antiAlias = true; } SetLineWidth(1); if (antiAlias) { linesmooth(SML_OFF); blendfunction(BF_ONE, BF_ZERO); subpixel(FALSE); } } if (drawEditBox) { SetLineWidth(2); SetUIColor(UIWHITE); /*Draw bottom square*/ qualityDrawnSoFar = MAX(qualityDrawnSoFar, DQ_OUTLINE); DrawSpaceLine(scaledBounds[0], scaledBounds[2], scaledBounds[4], scaledBounds[1], scaledBounds[2], scaledBounds[4]); DrawSpaceLine(scaledBounds[1], scaledBounds[2], scaledBounds[4], scaledBounds[1], scaledBounds[3], scaledBounds[4]); DrawSpaceLine(scaledBounds[1], scaledBounds[3], scaledBounds[4], scaledBounds[0], scaledBounds[3], scaledBounds[4]); DrawSpaceLine(scaledBounds[0], scaledBounds[3], scaledBounds[4], scaledBounds[0], scaledBounds[2], scaledBounds[4]); /*Draw top square*/ DrawSpaceLine(scaledBounds[0], scaledBounds[2], scaledBounds[5], scaledBounds[1], scaledBounds[2], scaledBounds[5]); DrawSpaceLine(scaledBounds[1], scaledBounds[2], scaledBounds[5], scaledBounds[1], scaledBounds[3], scaledBounds[5]); DrawSpaceLine(scaledBounds[1], scaledBounds[3], scaledBounds[5], scaledBounds[0], scaledBounds[3], scaledBounds[5]); DrawSpaceLine(scaledBounds[0], scaledBounds[3], scaledBounds[5], scaledBounds[0], scaledBounds[2], scaledBounds[5]); /*Draw remaining sides*/ DrawSpaceLine(scaledBounds[0], scaledBounds[2], scaledBounds[4], scaledBounds[0], scaledBounds[2], scaledBounds[5]); DrawSpaceLine(scaledBounds[1], scaledBounds[2], scaledBounds[4], scaledBounds[1], scaledBounds[2], scaledBounds[5]); DrawSpaceLine(scaledBounds[1], scaledBounds[3], scaledBounds[4], scaledBounds[1], scaledBounds[3], scaledBounds[5]); DrawSpaceLine(scaledBounds[0], scaledBounds[3], scaledBounds[4], scaledBounds[0], scaledBounds[3], scaledBounds[5]); SetLineWidth(1); } else if (maxDrawingQuality == DQ_OUTLINE && qualityDrawnSoFar <= DQ_MIN) { /*Do the outline anyway*/ SetUIColor(UIRED); /*Draw bottom square*/ qualityDrawnSoFar = MAX(qualityDrawnSoFar, DQ_OUTLINE); DrawSpaceLine(scaledBounds[0], scaledBounds[2], scaledBounds[4], scaledBounds[1], scaledBounds[2], scaledBounds[4]); DrawSpaceLine(scaledBounds[1], scaledBounds[2], scaledBounds[4], scaledBounds[1], scaledBounds[3], scaledBounds[4]); DrawSpaceLine(scaledBounds[1], scaledBounds[3], scaledBounds[4], scaledBounds[0], scaledBounds[3], scaledBounds[4]); DrawSpaceLine(scaledBounds[0], scaledBounds[3], scaledBounds[4], scaledBounds[0], scaledBounds[2], scaledBounds[4]); /*Draw top square*/ DrawSpaceLine(scaledBounds[0], scaledBounds[2], scaledBounds[5], scaledBounds[1], scaledBounds[2], scaledBounds[5]); DrawSpaceLine(scaledBounds[1], scaledBounds[2], scaledBounds[5], scaledBounds[1], scaledBounds[3], scaledBounds[5]); DrawSpaceLine(scaledBounds[1], scaledBounds[3], scaledBounds[5], scaledBounds[0], scaledBounds[3], scaledBounds[5]); DrawSpaceLine(scaledBounds[0], scaledBounds[3], scaledBounds[5], scaledBounds[0], scaledBounds[2], scaledBounds[5]); /*Draw remaining sides*/ DrawSpaceLine(scaledBounds[0], scaledBounds[2], scaledBounds[4], scaledBounds[0], scaledBounds[2], scaledBounds[5]); DrawSpaceLine(scaledBounds[1], scaledBounds[2], scaledBounds[4], scaledBounds[1], scaledBounds[2], scaledBounds[5]); DrawSpaceLine(scaledBounds[1], scaledBounds[3], scaledBounds[4], scaledBounds[1], scaledBounds[3], scaledBounds[5]); DrawSpaceLine(scaledBounds[0], scaledBounds[3], scaledBounds[4], scaledBounds[0], scaledBounds[3], scaledBounds[5]); } if (flags & (BBXMAJOR | BBXMINOR | BBYMAJOR | BBYMINOR | BBZMAJOR | BBZMINOR)) { /*Draw the tic marks*/ ObjPtr var; real majorStep[3], nDivisions[3], ticLength[3]; double maxSize; maxSize = bounds[1] - bounds[0]; maxSize = MAX(bounds[3] - bounds[2], maxSize); maxSize = MAX(bounds[5] - bounds[4], maxSize); var = GetVar(object, LINEWIDTH); if (var) { int width; width = GetReal(var); if (width < 1) width = 1; SetLineWidth(width); } MakeVar(object, AXISMAJORSTEP); var = GetFixedArrayVar("DrawBounded", object, AXISMAJORSTEP, 1, 3L); if (var) { Array2CArray(majorStep, var); } else { majorStep[0] = majorStep[1] = majorStep[2] = 1.0; } MakeVar(object, AXISDIVISIONS); var = GetFixedArrayVar("DrawBounded", object, AXISDIVISIONS, 1, 3L); if (var) { Array2CArray(nDivisions, var); } else { nDivisions[0] = nDivisions[1] = nDivisions[2] = 1.0; } MakeVar(object, TICLENGTH); var = GetFixedArrayVar("DrawBounded", object, TICLENGTH, 1, 3L); if (var) { Array2CArray(ticLength, var); } else { ticLength[0] = ticLength[1] = ticLength[2] = 10.0; } SetUIFont(UIBOLDLARGEFONT); if ((flags & (BBXMAJOR | BBXMINOR)) && (bounds[1] > bounds[0])) { double majorWidth; int nTics; long temp; double minorWidth, curValue; int k; /*Do the x axis*/ majorWidth = majorStep[0]; minorWidth = majorWidth / nDivisions[0]; nTics = nDivisions[0]; temp = bounds[0] / majorWidth; curValue = temp * majorWidth; while (curValue > bounds[0]) { curValue -= majorWidth; } k = 0; while (curValue < bounds[0]) { ++k; if (k >= nTics) k = 0; curValue += minorWidth; } /*Now actually draw them*/ if (ABS(curValue) < maxSize * 1.0E-6) curValue = 0.0; while (curValue <= bounds[1] + maxSize * 1.0E-6) { int strOff; if (k == 0 && (flags & BBXMAJOR)) { /*Major tic*/ SetUIColor(UIGRAY50); DrawSpaceLine(curValue, bounds[2], bounds[4], curValue, bounds[2] - ticLength[0], bounds[4]); PrintNumber(tempStr, (real) curValue); DrawSpaceString(curValue, bounds[2] - ticLength[0] * LABELFACTOR, bounds[4], tempStr); } else if (flags & BBXMINOR) { /*Minor tic*/ SetUIColor(UIGRAY50); DrawSpaceLine(curValue, bounds[2], bounds[4], curValue, bounds[2] - ticLength[0] * MINORTICFACTOR, bounds[4]); } curValue += minorWidth; if (ABS(curValue) < maxSize * 1.0E-6) curValue = 0.0; ++k; if (k >= nTics) k = 0; } } if ((flags & (BBYMAJOR | BBYMINOR)) && (bounds[3] > bounds[2])) { double majorWidth; int nTics; long temp; double minorWidth, curValue; int k; /*Do the y axis*/ majorWidth = majorStep[1]; minorWidth = majorWidth / nDivisions[1]; nTics = nDivisions[1]; temp = bounds[2] / majorWidth; curValue = temp * majorWidth; while (curValue > bounds[2]) { curValue -= majorWidth; } k = 0; while (curValue < bounds[2]) { ++k; if (k >= nTics) k = 0; curValue += minorWidth; } /*Now actually draw them*/ if (ABS(curValue) < maxSize * 1.0E-6) curValue = 0.0; while (curValue <= bounds[3] + maxSize * 1.0E-6) { int strOff; if (k == 0 && (flags & BBYMAJOR)) { /*Major tic*/ SetUIColor(UIGRAY50); DrawSpaceLine(bounds[0], curValue, bounds[4], bounds[0] - ticLength[1], curValue, bounds[4]); sprintf(tempStr, "%lg", curValue); DrawSpaceString(bounds[0] - ticLength[1] * LABELFACTOR, curValue, bounds[4], tempStr); } else if (flags & BBYMINOR) { /*Minor tic*/ SetUIColor(UIGRAY50); DrawSpaceLine(bounds[0], curValue, bounds[4], bounds[0] - ticLength[1] * MINORTICFACTOR, curValue, bounds[4]); } curValue += minorWidth; if (ABS(curValue) < maxSize * 1.0E-6) curValue = 0.0; ++k; if (k >= nTics) k = 0; } } if ((flags & (BBZMAJOR | BBZMINOR)) && (bounds[5] > bounds[4])) { double majorWidth; int nTics; long temp; double minorWidth, curValue; int k; /*Do the z axis*/ majorWidth = majorStep[2]; minorWidth = majorWidth / nDivisions[2]; nTics = nDivisions[2]; temp = bounds[4] / majorWidth; curValue = temp * majorWidth; while (curValue > bounds[4]) { curValue -= majorWidth; } k = 0; while (curValue < bounds[4]) { ++k; if (k >= nTics) k = 0; curValue += minorWidth; } /*Now actually draw them*/ if (ABS(curValue) < maxSize * 1.0E-6) curValue = 0.0; while (curValue <= bounds[5] + maxSize * 1.0E-6) { int strOff; if (k == 0 && (flags & BBZMAJOR)) { /*Major tic*/ SetUIColor(UIGRAY50); DrawSpaceLine(bounds[0], bounds[2], curValue, bounds[0] - ticLength[2], bounds[2] - ticLength[2], curValue); PrintNumber(tempStr, (real) curValue); DrawSpaceString(bounds[0] - ticLength[2] * LABELFACTOR, bounds[2] - ticLength[2] * LABELFACTOR, curValue, tempStr); } else if (flags & BBZMINOR) { /*Minor tic*/ SetUIColor(UIGRAY50); DrawSpaceLine(bounds[0], bounds[2], curValue, bounds[0] - ticLength[2] * MINORTICFACTOR, bounds[2] - ticLength[2] * MINORTICFACTOR, curValue); } curValue += minorWidth; if (ABS(curValue) < maxSize * 1.0E-6) curValue = 0.0; ++k; if (k >= nTics) k = 0; } } SetLineWidth(1); } var = GetIntVar("DrawBounded", object, DRAWNAMES); if (var) { flags = GetInt(var); } else { flags = 0; } if (flags) { /*Draw the names of the axes*/ SetUIColor(UIGRAY50); SetUIFont(UIBOLDLARGEFONT); if (flags & 1) { /*X axis*/ MakeVar(object, XNAME); var = GetStringVar("DrawBounded", object, XNAME); DrawSpaceString((scaledBounds[1] + scaledBounds[0]) / 2.0, scaledBounds[2] - maxSize * AXISFACTOR, scaledBounds[4], var ? GetString(var) : "X"); } if (flags & 2) { /*Y axis*/ MakeVar(object, YNAME); var = GetStringVar("DrawBounded", object, YNAME); DrawSpaceString(scaledBounds[0] - maxSize * AXISFACTOR, (scaledBounds[3] + scaledBounds[2]) / 2.0, scaledBounds[4], var ? GetString(var) : "Y"); } if (flags & 4) { /*Z axis*/ MakeVar(object, ZNAME); var = GetStringVar("DrawBounded", object, ZNAME); DrawSpaceString(scaledBounds[0] - maxSize * AXISFACTOR, scaledBounds[2] - maxSize * AXISFACTOR, (scaledBounds[5] + scaledBounds[4]) / 2.0, var ? GetString(var) : "Z"); } } } if (DQ_FULL >= minDrawingQuality && DQ_FULL <= maxDrawingQuality && outlineBox > OB_LINES) { /*Draw the solid frame*/ real frameWidth; /*KLUDGE change later*/ frameWidth = (bounds[1] - bounds[0]) * 0.05; if (rgbp) { real *elements; int matIndex; #if 0 var = GetVar(object, WALLPANELCOLOR); if (var) { elements = ELEMENTS(var); } else #endif { elements = 0; } matIndex = 0; material[matIndex++] = DIFFUSE; material[matIndex++] = elements ? elements[0] : 0.5; material[matIndex++] = elements ? elements[1] : 0.5; material[matIndex++] = elements ? elements[2] : 0.5; material[matIndex++] = LMNULL; lmdef(DEFMATERIAL, VISMATERIAL, matIndex, material); lmbind(MATERIAL, VISMATERIAL); lmcolor(LMC_DIFFUSE); } OptimizeColor(); if (outlineBox == OB_FRAME) { backface(TRUE); if (!rgbp) SetUIColor(UIGRAY62); /*-x*/ FrameWideSpaceRect( bounds[0], bounds[3], bounds[4], bounds[0], bounds[3], bounds[5], bounds[0], bounds[2], bounds[5], bounds[0], bounds[2], bounds[4], rgbp ? 1.0 : 0.0, 0.0, 0.0, frameWidth); FrameWideSpaceRect( bounds[0], bounds[2], bounds[4], bounds[0], bounds[2], bounds[5], bounds[0], bounds[3], bounds[5], bounds[0], bounds[3], bounds[4], rgbp ? -1.0 : 0.0, 0.0, 0.0, frameWidth); /*+x*/ FrameWideSpaceRect( bounds[1], bounds[2], bounds[4], bounds[1], bounds[2], bounds[5], bounds[1], bounds[3], bounds[5], bounds[1], bounds[3], bounds[4], rgbp ? -1.0 : 0.0, 0.0, 0.0, frameWidth); FrameWideSpaceRect( bounds[1], bounds[3], bounds[4], bounds[1], bounds[3], bounds[5], bounds[1], bounds[2], bounds[5], bounds[1], bounds[2], bounds[4], rgbp ? 1.0 : 0.0, 0.0, 0.0, frameWidth); if (!rgbp) SetUIColor(UIGRAY25); /*-y*/ FrameWideSpaceRect( bounds[1], bounds[2], bounds[4], bounds[0], bounds[2], bounds[4], bounds[0], bounds[2], bounds[5], bounds[1], bounds[2], bounds[5], 0.0, rgbp ? 1.0 : 0.0, 0.0, frameWidth); FrameWideSpaceRect( bounds[1], bounds[2], bounds[5], bounds[0], bounds[2], bounds[5], bounds[0], bounds[2], bounds[4], bounds[1], bounds[2], bounds[4], 0.0, rgbp ? -1.0 : 0.0, 0.0, frameWidth); /*+y*/ FrameWideSpaceRect( bounds[1], bounds[3], bounds[4], bounds[1], bounds[3], bounds[5], bounds[0], bounds[3], bounds[5], bounds[0], bounds[3], bounds[4], 0.0, rgbp ? -1.0 : 0.0, 0.0, frameWidth); FrameWideSpaceRect( bounds[0], bounds[3], bounds[4], bounds[0], bounds[3], bounds[5], bounds[1], bounds[3], bounds[5], bounds[1], bounds[3], bounds[4], 0.0, rgbp ? 1.0 : 0.0, 0.0, frameWidth); if (!rgbp) SetUIColor(UIGRAY12); /*floor*/ FrameWideSpaceRect( bounds[0], bounds[2], bounds[4], bounds[1], bounds[2], bounds[4], bounds[1], bounds[3], bounds[4], bounds[0], bounds[3], bounds[4], 0.0, 0.0, rgbp ? 1.0 : 0.0, frameWidth); FrameWideSpaceRect( bounds[0], bounds[2], bounds[4], bounds[0], bounds[3], bounds[4], bounds[1], bounds[3], bounds[4], bounds[1], bounds[2], bounds[4], 0.0, 0.0, rgbp ? -1.0 : 0.0, frameWidth); /*ceiling*/ FrameWideSpaceRect( bounds[0], bounds[2], bounds[5], bounds[0], bounds[3], bounds[5], bounds[1], bounds[3], bounds[5], bounds[1], bounds[2], bounds[5], 0.0, 0.0, rgbp ? -1.0 : 0.0, frameWidth); FrameWideSpaceRect( bounds[1], bounds[2], bounds[5], bounds[1], bounds[3], bounds[5], bounds[0], bounds[3], bounds[5], bounds[0], bounds[2], bounds[5], 0.0, 0.0, rgbp ? 1.0 : 0.0, frameWidth); backface(FALSE); } else if (outlineBox == OB_GIRDERS) { real expBounds[6]; backface(TRUE); if (!rgbp) SetUIColor(UIGRAY62); expBounds[0] = bounds[0] - frameWidth; expBounds[1] = bounds[1] + frameWidth; expBounds[2] = bounds[2] - frameWidth; expBounds[3] = bounds[3] + frameWidth; expBounds[4] = bounds[4] - frameWidth; expBounds[5] = bounds[5] + frameWidth; /*-x*/ FrameNotchedSpaceRect( bounds[0], bounds[3], bounds[4], bounds[0], bounds[3], bounds[5], bounds[0], bounds[2], bounds[5], bounds[0], bounds[2], bounds[4], rgbp ? 1.0 : 0.0, 0.0, 0.0, frameWidth); FrameWideSpaceRect( expBounds[0], expBounds[2], expBounds[4], expBounds[0], expBounds[2], expBounds[5], expBounds[0], expBounds[3], expBounds[5], expBounds[0], expBounds[3], expBounds[4], rgbp ? -1.0 : 0.0, 0.0, 0.0, frameWidth); /*+x*/ FrameNotchedSpaceRect( bounds[1], bounds[2], bounds[4], bounds[1], bounds[2], bounds[5], bounds[1], bounds[3], bounds[5], bounds[1], bounds[3], bounds[4], rgbp ? -1.0 : 0.0, 0.0, 0.0, frameWidth); FrameWideSpaceRect( expBounds[1], expBounds[3], expBounds[4], expBounds[1], expBounds[3], expBounds[5], expBounds[1], expBounds[2], expBounds[5], expBounds[1], expBounds[2], expBounds[4], rgbp ? 1.0 : 0.0, 0.0, 0.0, frameWidth); if (!rgbp) SetUIColor(UIGRAY25); /*-y*/ FrameNotchedSpaceRect( bounds[1], bounds[2], bounds[4], bounds[0], bounds[2], bounds[4], bounds[0], bounds[2], bounds[5], bounds[1], bounds[2], bounds[5], 0.0, rgbp ? 1.0 : 0.0, 0.0, frameWidth); FrameWideSpaceRect( expBounds[1], expBounds[2], expBounds[5], expBounds[0], expBounds[2], expBounds[5], expBounds[0], expBounds[2], expBounds[4], expBounds[1], expBounds[2], expBounds[4], 0.0, rgbp ? -1.0 : 0.0, 0.0, frameWidth); /*+y*/ FrameNotchedSpaceRect( bounds[1], bounds[3], bounds[4], bounds[1], bounds[3], bounds[5], bounds[0], bounds[3], bounds[5], bounds[0], bounds[3], bounds[4], 0.0, rgbp ? -1.0 : 0.0, 0.0, frameWidth); FrameWideSpaceRect( expBounds[0], expBounds[3], expBounds[4], expBounds[0], expBounds[3], expBounds[5], expBounds[1], expBounds[3], expBounds[5], expBounds[1], expBounds[3], expBounds[4], 0.0, rgbp ? 1.0 : 0.0, 0.0, frameWidth); if (!rgbp) SetUIColor(UIGRAY12); /*floor*/ FrameNotchedSpaceRect( bounds[0], bounds[2], bounds[4], bounds[1], bounds[2], bounds[4], bounds[1], bounds[3], bounds[4], bounds[0], bounds[3], bounds[4], 0.0, 0.0, rgbp ? 1.0 : 0.0, frameWidth); FrameWideSpaceRect( expBounds[0], expBounds[3], expBounds[4], expBounds[1], expBounds[3], expBounds[4], expBounds[1], expBounds[2], expBounds[4], expBounds[0], expBounds[2], expBounds[4], 0.0, 0.0, rgbp ? -1.0 : 0.0, frameWidth); /*ceiling*/ FrameNotchedSpaceRect( bounds[0], bounds[2], bounds[5], bounds[0], bounds[3], bounds[5], bounds[1], bounds[3], bounds[5], bounds[1], bounds[2], bounds[5], 0.0, 0.0, rgbp ? -1.0 : 0.0, frameWidth); FrameWideSpaceRect( expBounds[1], expBounds[2], expBounds[5], expBounds[1], expBounds[3], expBounds[5], expBounds[0], expBounds[3], expBounds[5], expBounds[0], expBounds[2], expBounds[5], 0.0, 0.0, rgbp ? 1.0 : 0.0, frameWidth); backface(FALSE); } OptimizeSharpness(); } #endif return ObjTrue; } static MakeMethod MakeAxesMajorStep(object) ObjPtr object; /*Makes the axis major steps of an object*/ { double maxSize; real bounds[6]; ObjPtr var; real *elements; double majorWidth; int nTics; GetBounds(object, bounds); maxSize = MAX(bounds[1] - bounds[0], MAX(bounds[3] - bounds[2], bounds[5] - bounds[4])); CalcGoodSteps(maxSize, 100, 10, &majorWidth, &nTics); var = NewRealArray(1, 3L); elements = ELEMENTS(var); elements[0] = majorWidth; elements[1] = majorWidth; elements[2] = majorWidth; SetVar(object, AXISMAJORSTEP, var); return ObjTrue; } static MakeMethod MakeAxesDivisions(object) ObjPtr object; /*Makes the axis divisions of an object*/ { double maxSize; real bounds[6]; ObjPtr var; real *elements; double majorWidth; int nTics; GetBounds(object, bounds); maxSize = MAX(bounds[1] - bounds[0], MAX(bounds[3] - bounds[2], bounds[5] - bounds[4])); CalcGoodSteps(maxSize, 100, 10, &majorWidth, &nTics); var = NewRealArray(1, 3L); elements = ELEMENTS(var); elements[0] = nTics; elements[1] = nTics; elements[2] = nTics; SetVar(object, AXISDIVISIONS, var); return ObjTrue; } static ObjPtr DrawWalls(object) ObjPtr object; /*Draw walls around a bounded object. No, that's done in VisObj*/ { return ObjTrue; } static ObjPtr MakePicColored(object) ObjPtr object; /*Makes the picture object in object colored*/ { ObjPtr colorObj; ObjPtr surface; MakeVar(object, SURFACE); surface = GetVar(object, SURFACE); if (!surface) return ObjFalse; /*Make it colored or not according to COLORS and COLOROBJ*/ MakeVar(object, COLORS); if (GetPredicate(object, COLORS) && (colorObj = GetVar(object, COLOROBJ))) { /*Have to make it colored by the object*/ ObjPtr cPalette; MakeVar(object, CPALETTE); cPalette = GetPaletteVar("MakePicColored", object, CPALETTE); if (cPalette) { SetPalette(cPalette); ColorPictureByObject(surface, colorObj, GetPredicate(object, INTERPCOLORS)); } } SetVar(object, PICCOLORED, ObjTrue); return ObjTrue; } static ObjPtr MakePicDeformed(object) ObjPtr object; /*Makes the picture object in object deformed*/ { ObjPtr surface; MakeVar(object, SURFACE); surface = GetPictureVar("MakePicDeformed", object, SURFACE); if (!surface) return ObjFalse; SetupDeformation(object); /*Make it deformed or not*/ DeformPictureByObject(surface); SetVar(object, PICDEFORMED, ObjTrue); return ObjTrue; } static ObjPtr MakeGeoPicColored(object) ObjPtr object; /*Makes the picture object in object colored*/ { ObjPtr colorObj; ObjPtr surface; ObjPtr cPalette; MakeVar(object, CPALETTE); cPalette = GetPaletteVar("MakeGeoPicColored", object, CPALETTE); if (cPalette) { SetPalette(cPalette); } surface = GetPictureVar("MakeGeoPicColored", object, SURFACE); if (!surface) return ObjFalse; /*Make it colored or not according to COLORS and COLOROBJ*/ MakeVar(object, COLORS); if (GetPredicate(object, COLORS) && (colorObj = GetVar(object, COLOROBJ))) { /*Have to make it colored by the object*/ if (colorObj == GetVar(object, REPOBJ)) { ObjPtr data, eternalData, var; /*Color it by itself*/ SetCurField(FIELD1, colorObj); data = curFields[FIELD1] . objectInfo; eternalData = GetVar(colorObj, ETERNALPART); if (eternalData) { PicItemPtr curItems, destItems; destItems = ((PicPtr) surface) -> items; curItems = ((PicPtr) eternalData) -> items; destItems = ColorItemsByItems(destItems, object, curItems); curItems = ((PicPtr) data) -> items; destItems = ColorItemsByItems(destItems, object, curItems); } else { ColorPictureByPicture(surface, object, data); } } else { ColorPictureByObject(surface, colorObj, GetPredicate(object, INTERPCOLORS)); } } SetVar(object, PICCOLORED, ObjTrue); return ObjTrue; } static ObjPtr DrawVisSurface(object) ObjPtr object; /*Draw a surface vis object, by default, gets picture*/ { #ifdef GRAPHICS ObjPtr repObj; if ((!drawSolid) && GetPredicate(object, ISTRANSPARENT) != drawingTransparent) { /*Don't draw if not the same pass*/ return ObjFalse; } /*Get the object's main dataset*/ repObj = GetVar(object, MAINDATASET); if (!repObj) repObj = GetObjectVar("DrawVisSurface", object, REPOBJ); if (repObj) { Bool drawSurface; real baseColor[3]; /*Base color of the object*/ ObjPtr var; ObjPtr surface; ObjPtr colors; drawSurface = GetPredicate(object, DRAWSURFACE); if (drawSurface) { if (DQ_FULL < minDrawingQuality || DQ_FULL > maxDrawingQuality) { drawSurface = false; } } else if (maxDrawingQuality == DQ_FULL && qualityDrawnSoFar <= DQ_MIN) { /*Surface is at the top, draw it anyway*/ drawSurface = true; } if (!drawSurface) { /*Nothing to draw, return*/ return ObjFalse; } if (drawSurface) { qualityDrawnSoFar = MAX(qualityDrawnSoFar, DQ_FULL); } var = GetVar(object, BASECOLOR); if (var) { Array2CArray(baseColor, var); } else { baseColor[0] = 1.0; baseColor[1] = 1.0; baseColor[2] = 1.0; } MakeVar(object, CPALETTE); colors = GetVar(object, CPALETTE); if (!colors) { return ObjFalse; } /*Get the surface*/ MakeVar(object, SURFACE); surface = GetVar(object, SURFACE); if (!surface) { return ObjFalse; } /*Set the palette for subsequent draws*/ SetPalette(colors); if (drawSurface) { /*OK, so everything exists. Fine. Now draw it.*/ real specular, shininess, brightness; int lightShading, colorShading; int matIndex; real specColor[3]; /*Get the light shading of the surface*/ var = GetVar(object, LIGHTSHADING); if (var) { lightShading = GetInt(var); } else { lightShading = NOLIGHT; } /*Get the color shading of the surface*/ MakeVar(object, COLORS); if (GetPredicate(object, COLORS) && GetVar(object, COLOROBJ)) { /*There is a color field. Shade according to value of COLORSHADING*/ colorShading = GetPredicate(object, COLORSHADING) ? SMOOTHCOLOR : MONOCOLOR; } else { /*There is no color field. Shade to nocolors.*/ colorShading = NOCOLOR; } /*Make the material*/ var = GetVar(object, SPECVAL); if (var && IsReal(var)) { specular = GetReal(var); } else { specular = 0.2; } var = GetVar(object, HIGHLIGHTCOLOR); if (var && IsRealArray(var) && RANK(var) == 1 && DIMS(var)[0] == 3) { Array2CArray(specColor, var); specColor[0] *= specular; specColor[1] *= specular; specColor[2] *= specular; } else { specColor[0] = specular; specColor[1] = specular; specColor[2] = specular; } var = GetVar(object, SHINVAL); if (var && IsReal(var)) { shininess = GetReal(var); } else { shininess = 80.0; } var = GetVar(object, BRIGHTNESS); if (var && IsReal(var)) { brightness = GetReal(var); } else { brightness = 1.0; } matIndex = 0; material[matIndex++] = SPECULAR; material[matIndex++] = specColor[0]; material[matIndex++] = specColor[1]; material[matIndex++] = specColor[2]; material[matIndex++] = SHININESS; material[matIndex++] = shininess; material[matIndex++] = DIFFUSE; material[matIndex++] = baseColor[0] * brightness; material[matIndex++] = baseColor[1] * brightness; material[matIndex++] = baseColor[2] * brightness; material[matIndex++] = LMNULL; lmdef(DEFMATERIAL, VISMATERIAL, matIndex, material); if (rgbp) { lmbind(MATERIAL, VISMATERIAL); } if (!drawSolid) { if (GetPredicate(object, ALTTRANSLUCENT)) { BeginAltTranslucent(); } else if (GetPredicate(object, ISTRANSLUCENT)) { BeginTranslucent(); } } /*Set the lighting model*/ if (GetPredicate(object, TWOSIDEDSURFACE)) { TwoSided(true); } OptimizeColor(); /*Make sure it's colored*/ MakeVar(object, PICCOLORED); drawingQuality = DQ_FULL; DrawPicture(surface, drawingTransparent, lightShading, colorShading, colors); OptimizeSharpness(); if (GetPredicate(object, TWOSIDEDSURFACE)) { TwoSided(false); } if ((!drawSolid) && (GetPredicate(object, ISTRANSLUCENT) || GetPredicate(object, ALTTRANSLUCENT))) { EndTranslucent(); } lmcolor(LMC_COLOR); } } else { return ObjFalse; } #endif return ObjTrue; } static ObjPtr DrawVisLines(object) ObjPtr object; /*Draw the lines of a surface vis object, by default, gets picture*/ { #ifdef GRAPHICS ObjPtr repObj; if (drawingTransparent) { /*Don't draw on transparent pass*/ return ObjFalse; } /*Get the object's main dataset*/ repObj = GetVar(object, MAINDATASET); if (!repObj) repObj = GetObjectVar("DrawVisLines", object, REPOBJ); if (repObj) { Bool drawWireFrame; real baseColor[3]; /*Base color of the object*/ ObjPtr var; ObjPtr surface; ObjPtr colors; int colorShading; Bool antiAlias = false; /*Get the color shading of the surface*/ MakeVar(object, COLORS); if (GetPredicate(object, COLORS) && GetVar(object, COLOROBJ)) { /*There is a color field. Shade according to value of COLORSHADING*/ colorShading = GetPredicate(object, COLORSHADING) ? SMOOTHCOLOR : MONOCOLOR; } else { /*There is no color field. Shade to nocolors.*/ colorShading = NOCOLOR; } drawWireFrame = GetPredicate(object, DRAWWIREFRAME); if (drawWireFrame) { /*If it's outside the range, don't draw a thing*/ if (DQ_WIREFRAME < minDrawingQuality || DQ_WIREFRAME > maxDrawingQuality) { drawWireFrame = false; } } else if (maxDrawingQuality == DQ_WIREFRAME && qualityDrawnSoFar <= DQ_MIN) { /*Wire frame is the top, draw it anyway*/ drawWireFrame = true; } if (!drawWireFrame) { /*Nothing to draw, return*/ return ObjFalse; } if (drawWireFrame) { qualityDrawnSoFar = MAX(qualityDrawnSoFar, DQ_WIREFRAME); } var = GetVar(object, BASECOLOR); if (var) { Array2CArray(baseColor, var); } else { baseColor[0] = 1.0; baseColor[1] = 1.0; baseColor[2] = 1.0; } MakeVar(object, CPALETTE); colors = GetVar(object, CPALETTE); if (!colors) { return ObjFalse; } /*Get the surface*/ surface = GetVar(object, SURFACE); MakeVar(objec