/*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(object, SURFACE); if (!surface) { return ObjFalse; } /*Set the palette for subsequent draws*/ SetPalette(colors); var = GetVar(object, LINEWIDTH); if (var) { int width; width = GetReal(var); if (width < 1) width = 1; SetLineWidth(width); } if (hasAntialiasedLines && rgbp && GetPredicate(object, ANTIALIASLINES)) { linesmooth(SML_ON); blendfunction(BF_SA, BF_MSA); subpixel(TRUE); antiAlias = true; } /*Make sure it's colored*/ MakeVar(object, PICCOLORED); drawingQuality = DQ_WIREFRAME; NudgeCloser(); NudgeCloser(); DrawPicture(surface, drawingTransparent, GetPredicate(object, DEPTHCUELINES) ? DEPTHCUELIGHT : NOLIGHT, colorShading, colors); NudgeFarther(); NudgeFarther(); SetLineWidth(1); if (antiAlias) { linesmooth(SML_OFF); blendfunction(BF_ONE, BF_ZERO); subpixel(FALSE); } } else { return ObjFalse; } #endif return ObjTrue; } static ObjPtr PickVisDots(object) ObjPtr object; /*Draws all the dots in an object for picking*/ { ObjPtr picture; MakeVar(object, SURFACE); picture = GetVar(object, SURFACE); if (picture) { PickCanonicalPictureVertices(picture); } return ObjTrue; } static ObjPtr DrawVisDots(object) ObjPtr object; /*Draw the dots 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 drawDots; real baseColor[3]; /*Base color of the object*/ ObjPtr var; ObjPtr surface; ObjPtr colors; int colorShading; Bool antiAlias = false; Bool biggerDots = 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; } drawDots = GetPredicate(object, DRAWDOTS); if (drawDots) { /*If it's outside the range, don't draw a thing*/ if (DQ_DOTS < minDrawingQuality || DQ_DOTS > maxDrawingQuality) { drawDots = false; } } else if (maxDrawingQuality == DQ_DOTS && qualityDrawnSoFar <= DQ_MIN) { /*Dots is the top, draw it anyway*/ drawDots = true; } if (!drawDots) { /*Nothing to draw, return*/ return ObjFalse; } qualityDrawnSoFar = MAX(qualityDrawnSoFar, DQ_DOTS); 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 a surface*/ MakeVar(object, SURFACE); surface = GetVar(object, SURFACE); if (!surface) { return ObjFalse; } /*Set the palette for subsequent draws*/ SetPalette(colors); if (hasAntialiasedPoints && rgbp && GetPredicate(object, ANTIALIASDOTS)) { pntsmooth(SML_ON); blendfunction(BF_SA, BF_MSA); subpixel(TRUE); antiAlias = true; } if (GetPredicate(object, BIGGERDOTS)) { SetPointWidth(2); biggerDots = 0; } else { SetPointWidth(1); } /*Make sure it's colored*/ MakeVar(object, PICCOLORED); drawingQuality = DQ_DOTS; NudgeCloser(); NudgeCloser(); DrawPicture(surface, drawingTransparent, GetPredicate(object, DEPTHCUEDOTS) ? DEPTHCUELIGHT : NOLIGHT, colorShading, colors); NudgeFarther(); NudgeFarther(); if (antiAlias) { pntsmooth(SML_OFF); blendfunction(BF_ONE, BF_ZERO); subpixel(FALSE); } if (biggerDots) { SetPointWidth(1); } } else { return ObjFalse; } #endif return ObjTrue; } static ObjPtr MakeGeoPictureSurface(object) ObjPtr object; /*Makes a geopicture's surface*/ { ObjPtr repObj; ObjPtr picture; ObjPtr newPic; ObjPtr data; ObjPtr eternalData; long flags; ObjPtr var; repObj = GetObjectVar("MakeGeoPictureSurface", object, REPOBJ); if (!repObj) { return ObjFalse; } SetCurField(FIELD1, repObj); flags = GetDatasetInfo(repObj); if (flags & DS_HASGEOMETRY) { picture = curFields[FIELD1] . objectInfo; eternalData = GetVar(repObj, ETERNALPART); if (eternalData) { newPic = ConvertPicture(eternalData, object); if (picture) { ConvertOntoPicture(newPic, picture, object); } SetVar(object, SURFACE, newPic); } else { if (picture) { SetVar(object, SURFACE, newPic = ConvertPicture(picture, object)); } } SetVar(newPic, REPOBJ, object); } else if (flags & DS_HASNEWGEOMETRY) { /*It's a new geometry*/ MakeVar(object, NORMALSWITCH); newPic = ConvertDatasetToPicture(repObj, GetVar(object, NORMALSOBJ)); SetVar(object, SURFACE, newPic); SetVar(newPic, REPOBJ, object); SetVar(newPic, MAINDATASET, repObj); } return ObjTrue; } static MakeMethod MakeColoredPalette(object) ObjPtr object; /*Makes a palette in a color object*/ { ObjPtr palette; ObjPtr var; real brightness; ObjPtr colors; /*Make a palette if none exists*/ palette = GetVar(object, CPALETTE); if (!palette) { palette = NewPalette(DEFPALSIZE); } SetVar(object, CPALETTE, palette); /*Get the brightness*/ var = GetVar(object, BRIGHTNESS); if (var && IsReal(var)) { brightness = GetReal(var); } else { brightness = 1.0; } /*Get the colors of the field*/ if (GetPredicate(object, COLORS) && (colors = GetVar(object, COLOROBJ))) { /*It gets its colors from a field.*/ ObjPtr sourcePalette; sourcePalette = GetVar(colors, CPALETTE); if (!sourcePalette) { return ObjFalse; } CopyAttenuatedPalette(palette, sourcePalette, brightness); } else { real rgb[3]; /*Assume it's going to be a plain ramp to BASECOLOR*/ /*Get the color*/ var = GetVar(object, BASECOLOR); if (var && IsRealArray(var) && RANK(var) == 1 && DIMS(var)[0] == 3) { Array2CArray(rgb, var); } else { rgb[0] = rgb[1] = rgb[2] = 1.0; } InterpPalette(palette, 0, 0, 0, (int) (255.0 * brightness * rgb[0]), (int) (255.0 * brightness * rgb[1]), (int) (255.0 * brightness * rgb[2])); } return ObjTrue; } static ObjPtr HideVisObject(object) ObjPtr object; /*Hides a vis object*/ { SetVar(object, HIDDEN, ObjTrue); ImInvalid(object); return ObjTrue; } static ObjPtr ShowVisObject(object) ObjPtr object; /*Shows a vis object*/ { SetVar(object, HIDDEN, ObjFalse); ImInvalid(object); return ObjTrue; } static ObjPtr replaceList; #ifdef HAVE_PROTOTYPES static void RVHelper(VarsPtr vars, ObjPtr oldVal, ObjPtr newVal) #else static void RVHelper(vars, oldVal, newVal) VarsPtr vars; ObjPtr oldVal; ObjPtr newVal; #endif /*Helper for ReplaceVars, puts symbols to replace on replaceList*/ { if (vars) { if (vars -> value == oldVal) { PrefixList(replaceList, NewSymbol(vars -> name)); } RVHelper(vars -> left, oldVal, newVal); RVHelper(vars -> right, oldVal, newVal); } } #ifdef HAVE_PROTOTYPES static void ReplaceVars(ObjPtr object, ObjPtr oldVal, ObjPtr newVal) #else static void ReplaceVars(object, oldVal, newVal) ObjPtr object, oldVal, newVal; #endif /*For an object, replaces all top level vars with value oldVal to be newVal*/ { ThingListPtr runner; NameTyp id; replaceList = NewList(); RVHelper(object -> vars, oldVal, newVal); runner = LISTOF(replaceList); while (runner) { if (IsSymbol(runner -> thing)) { id = GetSymbolID(runner -> thing); SetVar(object, id, newVal); } runner = runner -> next; } } static ObjPtr CloneVisObject(visObj) ObjPtr visObj; /*Clones a visualization object*/ { FuncTyp method; ObjPtr newVis; ObjPtr palette; ObjPtr mainDataset; ObjPtr dataset; newVis = Clone(visObj); MakeVar(visObj, CPALETTE); palette = GetVar(visObj, CPALETTE); if (palette) { SetVar(newVis, CPALETTE, ClonePalette(palette)); } mainDataset = GetVar(newVis, MAINDATASET); if (mainDataset) { /*Clone main dataset*/ method = GetMethod(mainDataset, CLONE); if (method) { ReplaceVars(newVis, mainDataset, (*method)(mainDataset)); } } return newVis; } static ObjPtr PrefixMainDataset(list, visObject) ObjPtr list, visObject; /*Prefixes the datasets from MAINDATASET or REPOBJ to list*/ { ObjPtr mainDataSet; mainDataSet = GetVar(visObject, MAINDATASET); if (!mainDataSet) mainDataSet = GetVar(visObject, REPOBJ); if (mainDataSet) { PrefixList(list, mainDataSet); } } void PrefixDatasets(list, visObject) ObjPtr list, visObject; /*Prefixes all datastes that visObject uses to list*/ { FuncTyp method; ObjPtr class; class = visObject; while (class) { method = Get1Method(class, PREFIXDATASETS); if (method) { (*method)(list, visObject); } class = ClassOf(class); } } ObjPtr MakeBoundedTicLength(object) ObjPtr object; /*Makes an object's tic length*/ { ObjPtr var; real maxSize; real *elements; real bounds[6]; GetBounds(object, bounds); maxSize = bounds[1] - bounds[0]; maxSize = MAX(maxSize, bounds[3] - bounds[2]); maxSize = MAX(maxSize, bounds[5] - bounds[4]); var = NewRealArray(1, 3L); elements = ELEMENTS(var); elements[0] = elements[1] = elements[2] = maxSize * MAJORTICSIZE; SetVar(object, TICLENGTH, var); return ObjTrue; } static ObjPtr AddGeometryControls(geometry, panelContents) ObjPtr geometry, panelContents; /*Adds controls appropriate to a geometry object to panelContents*/ { ObjPtr titleBox, button, radio, var, corral, icon, name; ObjPtr textBox, defaultIcon; int width, left, top, bottom, right; int bw; width = CWINWIDTH - 2 * CORRALBORDER - CWINCORRALWIDTH; left = MAJORBORDER; top = CWINHEIGHT - MAJORBORDER; /*Make sphere controls*/ right = PICSPHEREBOXWID + left; bottom = top - TITLEBOXTOP - 2 * MINORBORDER - 2 * CHECKBOXSPACING - 3 * CHECKBOXHEIGHT; titleBox = NewTitleBox(left, right, bottom, top, "Spheres"); PrefixList(panelContents, titleBox); SetVar(titleBox, PARENT, panelContents); /*Make the sphere radio button group*/ radio = NewRadioButtonGroup("Sphere Facet Group"); PrefixList(panelContents, radio); SetVar(radio, PARENT, panelContents); top -= TITLEBOXTOP + MINORBORDER; /*Make the buttons*/ button = NewRadioButton(left + MINORBORDER, (left + right) / 2, top - CHECKBOXHEIGHT, top, "8 facets"); AddRadioButton(radio, button); button = NewRadioButton(left + MINORBORDER, (left + right) / 2, top - 2 * CHECKBOXHEIGHT - CHECKBOXSPACING, top - CHECKBOXHEIGHT - CHECKBOXSPACING, "32 facets"); AddRadioButton(radio, button); button = NewRadioButton(left + MINORBORDER, (left + right) / 2, top - 3 * CHECKBOXHEIGHT - 2 * CHECKBOXSPACING, top - 2 * CHECKBOXHEIGHT - 2 * CHECKBOXSPACING, "128 facets"); AddRadioButton(radio, button); button = NewRadioButton((left + right) / 2, right - MINORBORDER, top - CHECKBOXHEIGHT, top, "512 facets"); AddRadioButton(radio, button); button = NewRadioButton((left + right) / 2, right - MINORBORDER, top - 2 * CHECKBOXHEIGHT - CHECKBOXSPACING, top - CHECKBOXHEIGHT - CHECKBOXSPACING, "2048 facets"); AddRadioButton(radio, button); button = NewRadioButton((left + right) / 2, right - MINORBORDER, top - 3 * CHECKBOXHEIGHT - 2 * CHECKBOXSPACING, top - 2 * CHECKBOXHEIGHT - 2 * CHECKBOXSPACING, "8192 facets"); AddRadioButton(radio, button); var = GetIntVar("AddGeometryControls", geometry, SPHERESUBDIV); if (!var) { SetVar(geometry, SPHERESUBDIV, NewInt(2)); } AssocDirectControlWithVar(radio, geometry, SPHERESUBDIV); SetVar(radio, HELPSTRING, NewString("This controls how many facets are used \ to approximate each sphere in the geometry object. Higher numbers provide more \ realistic results, especially with specular reflection. Lower numbers \ result in pictures which can be drawn much more quickly.")); top = bottom - CHECKBOXSPACING; /*Make cylinder controls*/ right = PICSPHEREBOXWID + left; bottom = top - TITLEBOXTOP - 3 * MINORBORDER - 3 * CHECKBOXSPACING - 5 * CHECKBOXHEIGHT; titleBox = NewTitleBox(left, right, bottom, top, "Cylinders and Frusta"); PrefixList(panelContents, titleBox); SetVar(titleBox, PARENT, panelContents); /*Make the cylinder radio button group*/ radio = NewRadioButtonGroup("Cylinder Facet Group"); PrefixList(panelContents, radio); SetVar(radio, PARENT, panelContents); top -= TITLEBOXTOP + MINORBORDER; /*Make the buttons*/ button = NewRadioButton(left + MINORBORDER, (left + right) / 2, top - CHECKBOXHEIGHT, top, "4 facets"); AddRadioButton(radio, button); button = NewRadioButton(left + MINORBORDER, (left + right) / 2, top - 2 * CHECKBOXHEIGHT - CHECKBOXSPACING, top - CHECKBOXHEIGHT - CHECKBOXSPACING, "8 facets"); AddRadioButton(radio, button); button = NewRadioButton(left + MINORBORDER, (left + right) / 2, top - 3 * CHECKBOXHEIGHT - 2 * CHECKBOXSPACING, top - 2 * CHECKBOXHEIGHT - 2 * CHECKBOXSPACING, "16 facets"); AddRadioButton(radio, button); button = NewRadioButton(left + MINORBORDER, (left + right) / 2, top - 4 * CHECKBOXHEIGHT - 3 * CHECKBOXSPACING, top - 3 * CHECKBOXHEIGHT - 3 * CHECKBOXSPACING, "32 facets"); AddRadioButton(radio, button); button = NewRadioButton((left + right) / 2, right - MINORBORDER, top - CHECKBOXHEIGHT, top, "64 facets"); AddRadioButton(radio, button); button = NewRadioButton((left + right) / 2, right - MINORBORDER, top - 2 * CHECKBOXHEIGHT - CHECKBOXSPACING, top - CHECKBOXHEIGHT - CHECKBOXSPACING, "128 facets"); AddRadioButton(radio, button); button = NewRadioButton((left + right) / 2, right - MINORBORDER, top - 3 * CHECKBOXHEIGHT - 2 * CHECKBOXSPACING, top - 2 * CHECKBOXHEIGHT - 2 * CHECKBOXSPACING, "256 facets"); AddRadioButton(radio, button); button = NewRadioButton((left + right) / 2, right - MINORBORDER, top - 4 * CHECKBOXHEIGHT - 3 * CHECKBOXSPACING, top - 3 * CHECKBOXHEIGHT - 3 * CHECKBOXSPACING, "512 facets"); AddRadioButton(radio, button); var = GetIntVar("AddGeometryControls", geometry, FRUSTUMSUBDIV); if (!var) { SetVar(geometry, FRUSTUMSUBDIV, NewInt(2)); } AssocDirectControlWithVar(radio, geometry, FRUSTUMSUBDIV); SetVar(radio, HELPSTRING, NewString("This controls how many facets are used \ to approximate each cylinder in the geometry object. Higher numbers provide more \ realistic results, especially with specular reflection. Lower numbers \ result in pictures which can be drawn much more quickly.")); /*Now the end caps button*/ button = NewCheckBox(left + MINORBORDER, right - MINORBORDER, top - 5 * CHECKBOXHEIGHT - 3 * CHECKBOXSPACING - MINORBORDER, top - 4 * CHECKBOXHEIGHT - 3 * CHECKBOXSPACING - MINORBORDER, "Show end caps", GetPredicate(geometry, CAPENDSP)); SetVar(button, PARENT, panelContents); PrefixList(panelContents, button); if (!GetVar(geometry, CAPENDSP)) SetVar(geometry, CAPENDSP, NewInt(1)); AssocDirectControlWithVar(button, geometry, CAPENDSP); SetVar(button, HELPSTRING, NewString("This controls whether end caps \ are drawn on the cylinders in this geomtry object. If it is checked, \ end caps are drawn, and the cylinders appear as solid rods. If it is not \ checked, the cylinders appear as hollow tubes.")); return ObjTrue; } #ifdef HAVE_PROTOTYPES void ScaleAroundPoint(real sx, real sy, real sz, real px, real py, real pz) #else void ScaleAroundPoint(sx, sy, sz, px, py, pz) real sx; real sy; real sz; real px; real py; real pz; #endif /*Scales subsequent drawing around a point*/ { #ifdef GRAPHICS Matrix m; PushTransformation(); loadmatrix(Identity); translate(px, py, pz); getmatrix(m); PopTransformation(); multmatrix(m); PushTransformation(); loadmatrix(Identity); scale(sx, sy, sz); getmatrix(m); PopTransformation(); multmatrix(m); PushTransformation(); loadmatrix(Identity); translate(-px, -py, -pz); getmatrix(m); PopTransformation(); multmatrix(m); #endif } #ifdef HAVE_PROTOTYPES void DrawPanelLines(real x1, real y1, real z1, real x2, real y2, real z2, char axis, real min, real max, real step) #else void DrawPanelLines( x1, y1, z1, x2, y2, z2, axis, min, max, step) real x1, y1, z1; real x2, y2, z2; char axis; real min, max, step; #endif /*Draws a bunch of lines from min to max by step along axis (x, y, z) using [xyz]1 and [xyz]2 as a basis.*/ { real cur; if (min > max) {cur = max; max = min; min = cur;} cur = rceil(min / step) * step; while (cur <= max) { if (cur >= min) { switch(axis) { case 'x': x1 = x2 = cur; break; case 'y': y1 = y2 = cur; break; case 'z': z1 = z2 = cur; break; } DrawSpaceLine(x1, y1, z1, x2, y2, z2); } cur += step; } } #ifdef HAVE_PROTOTYPES void DrawVisObject(ObjPtr object) #else void DrawVisObject(object) ObjPtr object; #endif /*Draws a visualization object*/ { ObjPtr var; float xScale, yScale, zScale; real bounds[6]; int panelFlags, shadowFlags, mirrorFlags; int oldMinDrawingQuality; Bool drawBackground; Bool antiAlias = false; /*True iff antialiased lines*/ drawBackground = GetPredicate(object, DRAWBACKGROUND); /*Get bounds*/ GetBounds(object, bounds); /*Get x, y, z, scale*/ var = GetVar(object, XSCALE); if (var) { xScale = GetReal(var); } else { xScale = 1.0; } var = GetVar(object, YSCALE); if (var) { yScale = GetReal(var); } else { yScale = 1.0; } var = GetVar(object, ZSCALE); if (var) { zScale = GetReal(var); } else { zScale = 1.0; } PushTransformation(); orderReversed = false; /*Scale the object*/ ScaleAroundPoint(xScale, yScale, zScale, bounds[0], bounds[2], bounds[4]); if (xScale < 0.0) orderReversed = orderReversed ? false : true; if (yScale < 0.0) orderReversed = orderReversed ? false : true; if (zScale < 0.0) orderReversed = orderReversed ? false : true; /*Draw the main object*/ DrawObject(object); oldMinDrawingQuality = minDrawingQuality; minDrawingQuality = DQ_WALLS + 1; /*Scale bounds*/ bounds[1] = bounds[0] + (bounds[1] - bounds[0]) * xScale; bounds[3] = bounds[2] + (bounds[3] - bounds[2]) * xScale; bounds[5] = bounds[4] + (bounds[5] - bounds[4]) * xScale; /*Draw the panels, if appropriate*/ var = GetVar(object, WALLPANELFLAGS); if (var && maxDrawingQuality >= DQ_WALLS && !drawingTransparent) { panelFlags = GetInt(var); } else { panelFlags = 0; } /*See if there are any mirrors*/ var = GetVar(object, WALLMIRRORFLAGS); if (var && maxDrawingQuality >= DQ_WALLS) { mirrorFlags = GetInt(var); } else { mirrorFlags = 0; } /*See if there are any shadows*/ var = GetVar(object, WALLSHADOWFLAGS); if (var && maxDrawingQuality >= DQ_WALLS && !drawingTransparent) { shadowFlags = GetInt(var); } else { shadowFlags = 0; } /*Draw reflections through mirrors*/ if (mirrorFlags) { /*First order reflections*/ orderReversed = orderReversed ? false : true; if (mirrorFlags & 1) /*-X*/ { PushTransformation(); ScaleAroundPoint(-1.0, 1.0, 1.0, bounds[0], bounds[2], bounds[4]); DrawObject(object); PopTransformation(); } if (mirrorFlags & 2) /*+X*/ { PushTransformation(); ScaleAroundPoint(-1.0, 1.0, 1.0, bounds[1], bounds[3], bounds[5]); DrawObject(object); PopTransformation(); } if (mirrorFlags & 4) /*-Y*/ { PushTransformation(); ScaleAroundPoint(1.0, -1.0, 1.0, bounds[0], bounds[2], bounds[4]); DrawObject(object); PopTransformation(); } if (mirrorFlags & 8) /*+Y*/ { PushTransformation(); ScaleAroundPoint(1.0, -1.0, 1.0, bounds[1], bounds[3], bounds[5]); DrawObject(object); PopTransformation(); } if (mirrorFlags & 16) /*-Z*/ { PushTransformation(); ScaleAroundPoint(1.0, 1.0, -1.0, bounds[0], bounds[2], bounds[4]); DrawObject(object); PopTransformation(); } if (mirrorFlags & 32) /*+Z*/ { PushTransformation(); ScaleAroundPoint(1.0, 1.0, -1.0, bounds[1], bounds[3], bounds[5]); DrawObject(object); PopTransformation(); } /*Second order reflections*/ orderReversed = orderReversed ? false : true; if ((mirrorFlags & 1) && (mirrorFlags & 4)) /* -X, -Y */ { PushTransformation(); ScaleAroundPoint(-1.0, -1.0, 1.0, bounds[0], bounds[2], bounds[4]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 1) && (mirrorFlags & 8)) /* -X, +Y */ { PushTransformation(); ScaleAroundPoint(-1.0, -1.0, 1.0, bounds[0], bounds[3], bounds[4]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 2) && (mirrorFlags & 4)) /* +X, -Y */ { PushTransformation(); ScaleAroundPoint(-1.0, -1.0, 1.0, bounds[1], bounds[2], bounds[4]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 2) && (mirrorFlags & 8)) /* +X, +Y */ { PushTransformation(); ScaleAroundPoint(-1.0, -1.0, 1.0, bounds[1], bounds[3], bounds[4]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 1) && (mirrorFlags & 16)) /* -X, -Z */ { PushTransformation(); ScaleAroundPoint(-1.0, 1.0, -1.0, bounds[0], bounds[2], bounds[4]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 1) && (mirrorFlags & 32)) /* -X, +Z */ { PushTransformation(); ScaleAroundPoint(-1.0, 1.0, -1.0, bounds[0], bounds[3], bounds[5]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 2) && (mirrorFlags & 16)) /* +X, -Z */ { PushTransformation(); ScaleAroundPoint(-1.0, 1.0, -1.0, bounds[1], bounds[2], bounds[4]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 2) && (mirrorFlags & 32)) /* +X, +Z */ { PushTransformation(); ScaleAroundPoint(-1.0, 1.0, -1.0, bounds[1], bounds[3], bounds[5]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 4) && (mirrorFlags & 16)) /* -Y, -Z */ { PushTransformation(); ScaleAroundPoint(1.0, -1.0, -1.0, bounds[0], bounds[2], bounds[4]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 4) && (mirrorFlags & 32)) /* -Y, +Z */ { PushTransformation(); ScaleAroundPoint(1.0, -1.0, -1.0, bounds[0], bounds[2], bounds[5]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 8) && (mirrorFlags & 16)) /* +Y, -Z */ { PushTransformation(); ScaleAroundPoint(1.0, -1.0, -1.0, bounds[1], bounds[3], bounds[4]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 8) && (mirrorFlags & 32)) /* +Y, +Z */ { PushTransformation(); ScaleAroundPoint(1.0, -1.0, -1.0, bounds[1], bounds[3], bounds[5]); DrawObject(object); PopTransformation(); } /*Third order reflections*/ orderReversed = orderReversed ? false : true; if ((mirrorFlags & 1) && (mirrorFlags & 4) && (mirrorFlags & 16)) /* -X, -Y, -Z */ { PushTransformation(); ScaleAroundPoint(-1.0, -1.0, -1.0, bounds[0], bounds[2], bounds[4]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 1) && (mirrorFlags & 4) && (mirrorFlags & 32)) /* -X, -Y, +Z */ { PushTransformation(); ScaleAroundPoint(-1.0, -1.0, -1.0, bounds[0], bounds[2], bounds[5]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 1) && (mirrorFlags & 4) && (mirrorFlags & 16)) /* -X, +Y, -Z */ { PushTransformation(); ScaleAroundPoint(-1.0, -1.0, -1.0, bounds[0], bounds[3], bounds[4]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 1) && (mirrorFlags & 4) && (mirrorFlags & 32)) /* -X, +Y, +Z */ { PushTransformation(); ScaleAroundPoint(-1.0, -1.0, -1.0, bounds[0], bounds[3], bounds[5]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 2) && (mirrorFlags & 4) && (mirrorFlags & 16)) /* +X, -Y, -Z */ { PushTransformation(); ScaleAroundPoint(-1.0, -1.0, -1.0, bounds[1], bounds[2], bounds[4]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 2) && (mirrorFlags & 4) && (mirrorFlags & 32)) /* +X, -Y, +Z */ { PushTransformation(); ScaleAroundPoint(-1.0, -1.0, -1.0, bounds[1], bounds[2], bounds[5]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 2) && (mirrorFlags & 4) && (mirrorFlags & 16)) /* +X, +Y, -Z */ { PushTransformation(); ScaleAroundPoint(-1.0, -1.0, -1.0, bounds[1], bounds[3], bounds[4]); DrawObject(object); PopTransformation(); } if ((mirrorFlags & 2) && (mirrorFlags & 4) && (mirrorFlags & 32)) /* +X, +Y, +Z */ { PushTransformation(); ScaleAroundPoint(-1.0, -1.0, -1.0, bounds[1], bounds[3], bounds[5]); DrawObject(object); PopTransformation(); } /*Back to original order*/ orderReversed = orderReversed ? false : true; } /*Draw the panels with no Z-buffering*/ if (panelFlags && drawBackground) { int matIndex; BeginMask(true, true, true, false); backface(TRUE); if (rgbp) { real *elements; var = GetVar(object, WALLPANELCOLOR); if (var) { elements = ELEMENTS(var); } else { 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 (!rgbp) SetUIColor(UIGRAY12); if (panelFlags & 1) { /*-x*/ FillSpaceRect( 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); } if (panelFlags & 2) { /*+x*/ FillSpaceRect( 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); } if (!rgbp) SetUIColor(UIGRAY25); if (panelFlags & 4) { /*-y*/ FillSpaceRect( 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); } if (panelFlags & 8) { /*+y*/ FillSpaceRect( 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); } if (!rgbp) SetUIColor(UIGRAY25); if (panelFlags & 16) { /*floor*/ FillSpaceRect( 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); } if (panelFlags & 32) { /*ceiling*/ FillSpaceRect( 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); } OptimizeSharpness(); if (rgbp) { lmcolor(LMC_COLOR); } backface(FALSE); EndMask(); } /*Draw shadows on panels*/ if (shadowFlags) { drawSolid = true; SetUIColor(UIBLACK); OverrideColor(true); if ((shadowFlags & 1) && (observerPosition[0] > bounds[0])) /*-X*/ { if ((panelFlags & 1) && drawBackground) { BeginMask(true, true, true, false); } PushTransformation(); ScaleAroundPoint(0.0001, 1.0, 1.0, bounds[0], bounds[2], bounds[4]); DrawObject(object); PopTransformation(); if ((panelFlags & 1) && drawBackground) { EndMask(); } } if ((shadowFlags & 2) && (observerPosition[0] < bounds[1])) /*+X*/ { if ((panelFlags & 2) && drawBackground) { BeginMask(true, true, true, false); } PushTransformation(); ScaleAroundPoint(0.0001, 1.0, 1.0, bounds[1], bounds[3], bounds[5]); DrawObject(object); PopTransformation(); if ((panelFlags & 2) && drawBackground) { EndMask(); } } if ((shadowFlags & 4) && (observerPosition[1] > bounds[2])) /*-Y*/ { if ((panelFlags & 4) && drawBackground) { BeginMask(true, true, true, false); } PushTransformation(); ScaleAroundPoint(1.0, 0.0001, 1.0, bounds[0], bounds[2], bounds[4]); DrawObject(object); PopTransformation(); if ((panelFlags & 4) && drawBackground) { EndMask(); } } if ((shadowFlags & 8) && (observerPosition[1] < bounds[3])) /*+Y*/ { if ((panelFlags & 8) && drawBackground) { BeginMask(true, true, true, false); } PushTransformation(); ScaleAroundPoint(1.0, 0.0001, 1.0, bounds[1], bounds[3], bounds[5]); DrawObject(object); PopTransformation(); if ((panelFlags & 8) && drawBackground) { EndMask(); } } if ((shadowFlags & 16) && (observerPosition[2] > bounds[4])) /*-Z*/ { if ((panelFlags & 16) && drawBackground) { BeginMask(true, true, true, false); } PushTransformation(); ScaleAroundPoint(1.0, 1.0, 0.0001, bounds[0], bounds[2], bounds[4]); DrawObject(object); PopTransformation(); if ((panelFlags & 16) && drawBackground) { EndMask(); } } if ((shadowFlags & 32) && (observerPosition[2] < bounds[5])) /*+Z*/ { if ((panelFlags & 32) && drawBackground) { BeginMask(true, true, true, false); } PushTransformation(); ScaleAroundPoint(1.0, 1.0, 0.0001, bounds[1], bounds[3], bounds[5]); DrawObject(object); PopTransformation(); if ((panelFlags & 32) && drawBackground) { EndMask(); } } OverrideColor(false); drawSolid = false; } /*Draw lines over shadow*/ if (panelFlags) { var = GetVar(object, LINEWIDTH); if (var) { int width; width = GetReal(var); if (width < 1) width = 1; SetLineWidth(width); } if (hasAntialiasedLines && rgbp && GetPredicate(object, ANTIALIASLINES)) { linesmooth(SML_ON); blendfunction(BF_SA, BF_MSA); subpixel(TRUE); antiAlias = true; } if (GetPredicate(object, DRAWOUTLINE)) { /*Draw the outline*/ var = GetVar(object, WALLLINESCOLOR); if (var) { SetObjectColor(var); } else { SetUIColor(UIGRAY75); } if (panelFlags & 1) { /*-x*/ FrameSpaceRect( bounds[0], bounds[3], bounds[4], bounds[0], bounds[3], bounds[5], bounds[0], bounds[2], bounds[5], bounds[0], bounds[2], bounds[4]); } if (panelFlags & 2) { /*+x*/ FrameSpaceRect( bounds[1], bounds[2], bounds[4], bounds[1], bounds[2], bounds[5], bounds[1], bounds[3], bounds[5], bounds[1], bounds[3], bounds[4]); } if (!rgbp) SetUIColor(UIGRAY25); if (panelFlags & 4) { /*-y*/ FrameSpaceRect( bounds[1], bounds[2], bounds[4], bounds[0], bounds[2], bounds[4], bounds[0], bounds[2], bounds[5], bounds[1], bounds[2], bounds[5]); } if (panelFlags & 8) { /*+y*/ FrameSpaceRect( bounds[1], bounds[3], bounds[4], bounds[1], bounds[3], bounds[5], bounds[0], bounds[3], bounds[5], bounds[0], bounds[3], bounds[4]); } if (!rgbp) SetUIColor(UIGRAY25); if (panelFlags & 16) { /*floor*/ FrameSpaceRect( bounds[0], bounds[2], bounds[4], bounds[1], bounds[2], bounds[4], bounds[1], bounds[3], bounds[4], bounds[0], bounds[3], bounds[4]); } if (panelFlags & 32) { /*ceiling*/ FrameSpaceRect( bounds[0], bounds[2], bounds[5], bounds[0], bounds[3], bounds[5], bounds[1], bounds[3], bounds[5], bounds[1], bounds[2], bounds[5]); } } if (GetPredicate(object, DRAWGRID)) { /*Draw the grid*/ double xSpace, ySpace, zSpace; real majorStep[3]; real maxSize; int nTics; MakeVar(object, AXISMAJORSTEP); var = GetFixedArrayVar("DrawVisObject", object, AXISMAJORSTEP, 1, 3L); if (var) { Array2CArray(majorStep, var); } else { majorStep[0] = majorStep[1] = majorStep[2] = 1.0; } /*Do the x, y, and z axes*/ xSpace = majorStep[0]; ySpace = majorStep[1]; zSpace = majorStep[2]; var = GetVar(object, WALLLINESCOLOR); if (var) { SetObjectColor(var); } else { SetUIColor(UIGRAY75); } if (panelFlags & 1) { /*-x*/ DrawPanelLines( bounds[0], bounds[2], bounds[4], bounds[0], bounds[3], bounds[4], 'z', bounds[4], bounds[5], zSpace); DrawPanelLines( bounds[0], bounds[2], bounds[4], bounds[0], bounds[2], bounds[5], 'y', bounds[2], bounds[3], ySpace); } if (panelFlags & 2) { /*+x*/ DrawPanelLines( bounds[1], bounds[2], bounds[4], bounds[1], bounds[3], bounds[4], 'z', bounds[4], bounds[5], zSpace); DrawPanelLines( bounds[1], bounds[2], bounds[4], bounds[1], bounds[2], bounds[5], 'y', bounds[2], bounds[3], ySpace); } if (panelFlags & 4) { /*-y*/ DrawPanelLines( bounds[0], bounds[2], bounds[4], bounds[1], bounds[2], bounds[4], 'z', bounds[4], bounds[5], zSpace); DrawPanelLines( bounds[0], bounds[2], bounds[4], bounds[0], bounds[2], bounds[5], 'x', bounds[0], bounds[1], ySpace); } if (panelFlags & 8) { /*+y*/ DrawPanelLines( bounds[0], bounds[3], bounds[4], bounds[1], bounds[3], bounds[4], 'z', bounds[4], bounds[5], zSpace); DrawPanelLines( bounds[0], bounds[3], bounds[4], bounds[0], bounds[3], bounds[5], 'x', bounds[0], bounds[1], ySpace); } if (!rgbp) SetUIColor(UIGRAY25); if (panelFlags & 16) { /*floor*/ DrawPanelLines( bounds[0], bounds[2], bounds[4], bounds[0], bounds[3], bounds[4], 'x', bounds[0], bounds[1], xSpace); DrawPanelLines( bounds[0], bounds[2], bounds[4], bounds[1], bounds[2], bounds[4], 'y', bounds[2], bounds[3], ySpace); } if (panelFlags & 32) { /*ceiling*/ DrawPanelLines( bounds[0], bounds[2], bounds[5], bounds[0], bounds[3], bounds[5], 'x', bounds[0], bounds[1], xSpace); DrawPanelLines( bounds[0], bounds[2], bounds[5], bounds[1], bounds[2], bounds[5], 'y', bounds[2], bounds[3], ySpace); } } SetLineWidth(1); if (antiAlias) { linesmooth(SML_OFF); blendfunction(BF_ONE, BF_ZERO); subpixel(FALSE); } } /*Draw the panels with only Z-buffering, no drawing*/ if (panelFlags && drawBackground) { int matIndex; BeginMask(false, false, false, true); backface(TRUE); if (panelFlags & 1) { /*-x*/ FillSpaceRect( 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); } if (panelFlags & 2) { /*+x*/ FillSpaceRect( 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); } if (panelFlags & 4) { /*-y*/ FillSpaceRect( 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); } if (panelFlags & 8) { /*+y*/ FillSpaceRect( 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); } if (panelFlags & 16) { /*floor*/ FillSpaceRect( 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); } if (panelFlags & 32) { /*ceiling*/ FillSpaceRect( 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); } backface(FALSE); EndMask(); } PopTransformation(); minDrawingQuality = oldMinDrawingQuality; } static ObjPtr GeometryInit(object) ObjPtr object; /*Initializes a geometry object*/ { return ObjTrue; } static ObjPtr MakeGeoPictureColors(object) ObjPtr object; /*Makes a geometry object's colors*/ { ObjPtr minMax; real bounds[6]; real xySize, zSize; ObjPtr colorObj; ObjPtr normalsObj; colorObj = GetVar(object, REPOBJ); if (GetPredicate(colorObj, COLORBYSELF) && GetVar(colorObj, CPALETTE)) { SetVar(object, COLOROBJ, colorObj); if (colorObj) { SetVar(object, COLORS, NewInt(1)); } else { SetVar(object, COLORS, NewInt(0)); } } return ObjTrue; } static ObjPtr MakeGeoPictureNormalSwitch(object) ObjPtr object; /*Makes a geometry object's normal switch*/ { ObjPtr minMax; real bounds[6]; real xySize, zSize; ObjPtr colorObj; ObjPtr normalsObj; colorObj = GetVar(object, REPOBJ); if (normalsObj = GetVar(colorObj, NORMALSOBJ)) { SetVar(object, NORMALSOBJ, normalsObj); } SetVar(object, NORMALSWITCH, NewInt(1)); return ObjTrue; } static ObjPtr VisualizeVisObject(object) ObjPtr object; /*Visualizes a single vis object*/ { if (object) { AddObjToSpace(object, FindSpace(selWinInfo), GetVar((ObjPtr) selWinInfo, CORRAL), NULLOBJ, NULLOBJ); return ObjTrue; } return ObjFalse; } ObjPtr DummyDeformed(object) ObjPtr object; /*Dummy deformed method DIK remove when deformation and scale work on everything.*/ { SetVar(object, PICDEFORMED, ObjTrue); return ObjTrue; } static ObjPtr MakeBoundedXName(object) ObjPtr object; /*Makes a bounded vis object's XNAME*/ { ObjPtr dataset, name; dataset = GetVar(object, MAINDATASET); if (!dataset) { dataset = GetVar(object, REPOBJ); } if (dataset) { MakeVar(dataset, XNAME); name = GetVar(dataset, XNAME); } else { name = NULLOBJ; } if (name) { SetVar(object, XNAME, name); } else { SetVar(object, XNAME, NewString("X")); } return ObjTrue; } static ObjPtr MakeBoundedYName(object) ObjPtr object; /*Makes a bounded vis object's YNAME*/ { ObjPtr dataset, name; dataset = GetVar(object, MAINDATASET); if (!dataset) { dataset = GetVar(object, REPOBJ); } if (dataset) { MakeVar(dataset, YNAME); name = GetVar(dataset, YNAME); } else { name = NULLOBJ; } if (name) { SetVar(object, YNAME, name); } else { SetVar(object, YNAME, NewString("Y")); } return ObjTrue; } static ObjPtr MakeBoundedZName(object) ObjPtr object; /*Makes a bounded vis object's XNAME*/ { ObjPtr dataset, name; dataset = GetVar(object, MAINDATASET); if (!dataset) { dataset = GetVar(object, REPOBJ); } if (dataset) { MakeVar(dataset, ZNAME); name = GetVar(dataset, ZNAME); } else { name = NULLOBJ; } if (name) { SetVar(object, ZNAME, name); } else { SetVar(object, ZNAME, NewString("Z")); } return ObjTrue; } static MakeMethod MakeVisAppearance(object) ObjPtr object; /*Makes a vis object's appearance*/ { SetVar(object, APPEARANCE, ObjTrue); ImInvalid(object); return ObjTrue; } static ObjPtr DropInSizeCorral(corral, object, x, y) ObjPtr corral, object; int x, y; /*Drops an icon in a size corral*/ { ObjPtr visObj; ObjPtr fieldObj; ObjPtr icon; ObjPtr name; ObjPtr defaultIcon; ObjPtr contents; ObjPtr button; long info; /*Find the visualization object*/ visObj = GetObjectVar("DropInSizeCorral", corral, REPOBJ); if (!visObj) { return ObjFalse; } /*Get the field object*/ fieldObj = GetObjectVar("DropInSizeCorral", 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("DropInSizeCorral", 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 ball 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 sized object*/ SetVar(visObj, SIZEOBJ, fieldObj); ImInvalid(visObj); ImInvalid(corral); return ObjTrue; } static ObjPtr AddSizedControls(object, panelContents) ObjPtr object, panelContents; /*Adds controls to a sized object*/ { ObjPtr control, button, checkBox, corral, sw, textBox, slider, icon, radioGroup; ObjPtr sizeObj, titleBox; ObjPtr var; int width, left, right, top, bottom, cellHeight, m1, m2; real initValue; real baseColor[3]; real hs[2], dummy; ObjPtr parent; /*Get the parent*/ parent = GetObjectVar("AddSizedControls", 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 size 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("Size Field")); PrefixList(panelContents, corral); SetVar(corral, HELPSTRING, NewString("This corral shows the dataset that is used to \ determine the size of 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, DropInSizeCorral); /*Create the size source text box*/ textBox = NewTextBox(left, left + ONECORRALWIDTH, m2 - ONECORRALHEIGHT / 2 - TEXTBOXSEP - TEXTBOXHEIGHT, m2 - ONECORRALHEIGHT / 2 - TEXTBOXSEP, 0, "Size Field Text", "Size Field"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, CENTERALIGN); left += ONECORRALWIDTH + MINORBORDER; sizeObj = GetVar(object, SIZEOBJ); if (sizeObj) { ObjPtr name, defaultIcon; /*Drop icon in corral, if need be*/ MakeVar(sizeObj, NAME); name = GetVar(sizeObj, NAME); MakeVar(sizeObj, DEFAULTICON); defaultIcon = GetVar(sizeObj, DEFAULTICON); if (defaultIcon) { icon = NewObject(defaultIcon, 0); SetVar(icon, NAME, name); } else { icon = NewIcon(0, 0, ICONQUESTION, GetString(name)); } SetVar(icon, REPOBJ, sizeObj); SetVar(icon, ICONLOC, NULLOBJ); DropIconInCorral(corral, icon); } /*Create the constant size control*/ var = GetRealVar("AddSizedControls", object, SIZECONSTANT); if (!var) { SetVar(object, SIZECONSTANT, NewReal(0.0)); } textBox = NewTextBox(MAJORBORDER, left - MINORBORDER, m1 - EDITBOXHEIGHT / 2, m1 + EDITBOXHEIGHT / 2, EDITABLE + WITH_PIT + ONE_LINE, "Fixed Size", ""); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetVar(textBox, HELPSTRING, NewString("This text box gives a constant \ size when it is selected by the switch.")); SetVar(textBox, WHICHVAR, NewSymbol(SIZECONSTANT)); SetTextAlign(textBox, RIGHTALIGN); AssocTextRealControlWithVar(textBox, object, SIZECONSTANT, 0.0, plusInf, TR_NE_TOP); /*Create the text box*/ textBox = NewTextBox(MAJORBORDER - 20, left - MINORBORDER + 20, m1 - EDITBOXHEIGHT / 2 - TEXTBOXSEP - 2 * TEXTBOXHEIGHT, m1 - EDITBOXHEIGHT / 2 - TEXTBOXSEP, 0, "Fixed Size Text", "Fixed Size"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, CENTERALIGN); SetVar(textBox, REPOBJ, object); /*Create the choice switch*/ MakeVar(object, SIZESWITCH); var = GetIntVar("AddSizedControls", object, SIZESWITCH); if (!var) { SetVar(object, SIZESWITCH, NewInt(0)); } 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, "Size Switch"); PrefixList(panelContents, sw); SetVar(sw, PARENT, panelContents); SetVar(sw, REPOBJ, object); SetVar(sw, HELPSTRING, NewString("This switch controls whether the \ soze of the visualization object comes from a \ field or from a fixed size.")); AssocDirectControlWithVar(sw, object, SIZESWITCH); left += SWITCHWIDTH + MINORBORDER; /*Create the * text box*/ right = left + MINORBORDER; textBox = NewTextBox(left, right + MINORBORDER, m1 - EDITBOXHEIGHT / 2, m1 + EDITBOXHEIGHT / 2, 0, "Splat", "*"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextFont(textBox, "Courier-Bold"); SetTextSize(textBox, 18); left = right + MINORBORDER; /*Create the size factor*/ var = GetVar(object, SIZEFACTOR); if (!var) { SetVar(object, SIZEFACTOR, NewReal(0.0)); } right = left + SIZEEDITWIDTH; textBox = TemplateTextBox(VisSizeTemplate, "Size Factor", EDITABLE + WITH_PIT + ONE_LINE, ""); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetVar(textBox, HELPSTRING, NewString("This text box gives a multiplier \ for the size provided by the switch.")); SetVar(textBox, WHICHVAR, NewSymbol(SIZEFACTOR)); AssocTextRealControlWithVar(textBox, object, SIZEFACTOR, minusInf, plusInf, TR_NE_BOTTOM | TR_NE_TOP); SetTextAlign(textBox, RIGHTALIGN); /*Create the text box*/ textBox = TemplateTextBox(VisSizeTemplate, "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(VisSizeTemplate, "Plus", 0, "+"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextFont(textBox, "Courier-Bold"); SetTextSize(textBox, 18); left = right + MINORBORDER; /*Create the size offset*/ var = GetRealVar("AddSizedControls", object, SIZEOFFSET); if (!var) { SetVar(object, SIZEOFFSET, NewReal(0.0)); } right = left + SIZEEDITWIDTH; textBox = TemplateTextBox(VisSizeTemplate, "Size Offset", EDITABLE + WITH_PIT + ONE_LINE, ""); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetVar(textBox, HELPSTRING, NewString("This text box gives an offset \ for the size provided by the switch, multiplied by the multiplier.")); AssocTextRealControlWithVar(textBox, object, SIZEOFFSET, minusInf, plusInf, TR_NE_BOTTOM | TR_NE_TOP); SetTextAlign(textBox, RIGHTALIGN); /*Create the text box*/ textBox = TemplateTextBox(VisSizeTemplate, "Offset Text", 0, "Offset"); PrefixList(panelContents, textBox); SetVar(textBox, PARENT, panelContents); SetTextAlign(textBox, CENTERALIGN); SetVar(textBox, REPOBJ, object); left = right + MINORBORDER; return ObjTrue; } Bool cacheMade; /*Global to indicate cache was made*/ static MakeMethod MakeCachedOpaque(object) ObjPtr object; /*Routine to make opaque cache*/ { SetVar(object, CACHEDOPAQUE, GetVar(object, CACHEDOPAQUE)); cacheMade = true; return ObjTrue; } static MakeMethod MakeCachedTransparent(object) ObjPtr object; /*Routine to make transparent cache*/ { SetVar(object, CACHEDTRANSPARENT, GetVar(object, CACHEDTRANSPARENT)); cacheMade = true; return ObjTrue; } static MakeMethod MakeVisColors(object) ObjPtr object; /*Makes a colored visualization's COLORS and COLOROBJ variable. By default, it looks for the main dataset.*/ { ObjPtr colorObj; ObjPtr mainDataset; ObjPtr var; colorObj = GetVar(object, MAINDATASET); #if 0 while (var = GetVar(colorObj, MAINDATASET)) { colorObj = var; } #else #if 0 while (IntVarEql(colorObj, CLASSID, CLASS_MISSER)) { if (var = GetVar(colorObj, MAINDATASET)) { colorObj = var; } } #endif #endif /*See if there's a color object within the main dataset*/ if (colorObj) { var = GetVar(colorObj, COLOROBJ); if (var) { colorObj = var; } #if 0 while (var = GetVar(colorObj, MAINDATASET)) { colorObj = var; } #else #if 0 while (IntVarEql(colorObj, CLASSID, CLASS_MISSER)) { if (var = GetVar(colorObj, MAINDATASET)) { colorObj = var; } } #endif #endif } SetVar(object, COLOROBJ, colorObj); if (colorObj) { SetVar(object, COLORS, NewInt(1)); } else { SetVar(object, COLORS, NewInt(0)); } return ObjTrue; } static ObjPtr MakeVisDeformSwitch(object) ObjPtr object; /*Makes a colored visualization's DEFORMSWITCH and DEFORMOBJ variable. By default, it looks for the main dataset.*/ { ObjPtr deformObj; ObjPtr mainDataset; ObjPtr var; deformObj = GetVar(object, MAINDATASET); while (var = GetVar(deformObj, MAINDATASET)) { deformObj = var; } /*See if there's a deform object within the main dataset*/ if (deformObj) { var = GetVar(deformObj, DEFORMOBJ); if (var) { deformObj = var; } while (var = GetVar(deformObj, MAINDATASET)) { deformObj = var; } } SetVar(object, DEFORMOBJ, deformObj); if (deformObj) { real xySize; ObjPtr minMax; real zSize1, zSize2; real bounds[6]; GetBounds(object, bounds); xySize = bounds[1] - bounds[0]; xySize = MAX(xySize, bounds[3] - bounds[2]); xySize = MAX(xySize, bounds[5] - bounds[4]); MakeVar(deformObj, MINMAX); minMax = GetVar(deformObj, MINMAX); zSize1 = ABS((((real *) ELEMENTS(minMax))[0])); zSize2 = ABS((((real *) ELEMENTS(minMax))[1])); if (zSize1 < xySize * 0.5 && zSize2 < xySize * 0.5) { SetVar(object, DEFORMSWITCH, NewInt(1)); } else { SetVar(object, DEFORMSWITCH, NewInt(0)); } } return ObjTrue; } static ObjPtr MakeVisSizeSwitch(object) ObjPtr object; /*Makes a colored visualization's SIZESWITCH and SIZEOBJ variable. By default, it looks for the main dataset.*/ { ObjPtr sizeObj; ObjPtr mainDataset; ObjPtr var; sizeObj = GetVar(object, MAINDATASET); while (var = GetVar(sizeObj, MAINDATASET)) { sizeObj = var; } sizeObj = GetVar(sizeObj, SIZEOBJ); SetVar(object, SIZEOBJ, sizeObj); if (sizeObj) { SetVar(object, SIZESWITCH, NewInt(1)); } else { SetVar(object, SIZESWITCH, NewInt(0)); } return ObjTrue; } ObjPtr SaveVisObjectFile(object, name) ObjPtr object; char *name; /*Saves a object as name*/ { SaveObject(object, name); return ObjTrue; } ObjPtr LogVisObjectDefinition(object) ObjPtr object; /*Logs a visualization object definition*/ { char *retVar; ObjPtr v; ObjPtr var; int classID; ObjPtr depList; ObjPtr varList; ThingListPtr runner, runner2, runner3; InhibitWindow(true); /*Determine all the dependent vars*/ depList = NewList(); PostfixList(depList, object); depList = AddExternalSnapVarsToSet(depList, object); /*Make the variables*/ varList = NewList(); for (runner = LISTOF(depList); runner; runner = runner -> next) { retVar = LogScriptVarForObject(runner -> thing); /*If it's in the database, emit a setter*/ if (IsUniqueInDatabase(runner -> thing)) { v = GetVar(runner -> thing, CLASSID); if (v) { classID = GetInt(v); MakeVar(runner -> thing, NAME); v = GetVar(runner -> thing, NAME); if (v) { char name[200]; Log("try $"); Log(retVar); Log(" = "); Log(ClassIDToName(classID)); Log("@"); MakeObjectSimpleName(name, runner -> thing); Log(name); Log("\n"); } } } PostfixList(varList, NewString(retVar)); } Log("\n"); /*Make the definition*/ runner2 = LISTOF(varList); for (runner = LISTOF(depList); runner; runner = runner -> next) { /*Log header*/ Log("begin definition "); Log("$"); Log(GetString(runner2 -> thing)); Log("\n"); /*Log history*/ var = GetVar(runner -> thing, HISTORY); if (var) { /*There's a specified history*/ for (runner3 = LISTOF(var); runner3; runner3 = runner3 -> next) { LogObject(runner3 -> thing); } /*If it's in the database, emit a setter*/ if (IsUniqueInDatabase(runner -> thing)) { v = GetVar(runner -> thing, CLASSID); if (v) { classID = GetInt(v); MakeVar(runner -> thing, NAME); v = GetVar(runner -> thing, NAME); if (v) { char name[200]; Log(" $"); Log(GetString(runner2 -> thing)); Log(" = "); Log(ClassIDToName(classID)); Log("@"); MakeObjectSimpleName(name, runner -> thing); Log(name); Log("\n"); } } } } else { /*Make default history, ab initio*/ v = GetVar(runner -> thing, CLASSID); if (v) { classID = GetInt(v); MakeVar(runner -> thing, NAME); v = GetVar(runner -> thing, NAME); if (v) { char name[200]; Log(" $"); Log(GetString(runner2 -> thing)); Log(" = new("); Log(ClassIDToName(classID)); Log("@"); MakeObjectSimpleName(name, runner -> thing); Log(name); Log(")\n"); } } } /*Log current state*/ LogSnapVars(runner -> thing); /*Log end*/ Log("end definition\n\n"); runner2 = runner2 -> next; } Log("\nvisualize $"); Log(GetString(LISTOF(varList) -> thing)); Log("\n"); InhibitWindow(false); return ObjTrue; } void InitVisObjects() /*Initializes the visualization objects.*/ { ObjPtr icon; ObjPtr array, var; ObjPtr list; real *elements; allVisObjClasses = NewList(); AddToReferenceList(allVisObjClasses); visIcon = NewIcon(0, 0, ICONQUESTION, "Visualization Object"); AddToReferenceList(visIcon); SetVar(visIcon, HELPSTRING, NewString("You can create a copy of this visualization, which you can \ then modify, by selecting the icon and choosing the Duplicate item in the Object menu. \ You can show this visualization object in another window as well by dragging the icon into \ the corral of the other window. \ You can show controls that affect this visualization by selecting the icon and \ choosing Show Controls from the Object menu.")); visClass = NewObject(NULLOBJ, 0); AddToReferenceList(visClass); DeclareDependency(visClass, NAME, MAINDATASET); DeclareDependency(visClass, NAME, TEMPLATEP); SetMethod(visClass, NAME, MakeVisName); DefineFixedClass(visClass, CLASS_VISOBJ, "visObj"); SetVar(visClass, MULTIDRAW, ObjTrue); SetVar(visClass, DOUBLECLICK, NewString(OF_SHOW_CONTROLS)); SetMethod(visClass, NEWCTLWINDOW, ShowVisControls); SetMethod(visClass, SHOWCONTROLS, NewControlWindow); SetMethod(visClass, HIDE, HideVisObject); SetMethod(visClass, SHOW, ShowVisObject); AddSnapVar(visClass, HIDDEN); SetMethod(visClass, CLONE, CloneVisObject); SetMethod(visClass, PREFIXDATASETS, PrefixMainDataset); SetMethod(visClass, DELETE, DeleteVisObject); SetMethod(visClass, DUPLICATE, DuplicateSpaceObject); SetMethod(visClass, LOCALCOPY, MakeLocalCopy); SetMethod(visClass, VISUALIZE, VisualizeVisObject); SetMethod(visClass, APPEARANCE, MakeVisAppearance); SetVar(visClass, XSCALE, NewReal(1.0)); SetVar(visClass, YSCALE, NewReal(1.0)); SetVar(visClass, ZSCALE, NewReal(1.0)); AddSnapVar(visClass, XSCALE); AddSnapVar(visClass, YSCALE); AddSnapVar(visClass, ZSCALE); AddSnapVar(visClass, MAINDATASET); SetMethod(visClass, SAVECPANEL, SaveSnapshotControls); SetMethod(visClass, SAVEALLCONTROLS, LogVisObjectDefinition); SetMethod(visClass, SAVEFILE, SaveVisObjectFile); SetVar(visClass, VISOBJP, ObjTrue); visAxes = NewObject(visClass, 0); AddToReferenceList(visAxes); icon = NewIcon(0, 0, ICONAXES, "Axes"); SetVar(icon, HELPSTRING, NewString("Select this icon to show controls to display the axes of the \ visualization object.")); SetVar(visAxes, CONTROLICON, icon); SetVar(icon, PANELHELP, NewString("This panel contains controls that \ let you change the name of the axes and display the axes in various ways.")); SetMethod(visAxes, ADDCONTROLS, AddAxesControls); SetMethod(visAxes, AXISMAJORSTEP, MakeAxesMajorStep); AddSnapVar(visAxes, AXISMAJORSTEP); SetMethod(visAxes, AXISDIVISIONS, MakeAxesDivisions); AddSnapVar(visAxes, AXISDIVISIONS); SetVar(visAxes, DRAWNAMES, NewInt(0)); AddSnapVar(visAxes, DRAWNAMES); AddSnapVar(visAxes, BBFLAGS); visBounded = NewObject(visAxes, 0); AddToReferenceList(visBounded); SetMethod(visBounded, DRAW, DrawBounded); SetMethod(visBounded, ADDCONTROLS, AddBoundedControls); SetMethod(visBounded, BOUNDS, MakeFormBounds); DeclareIndirectDependency(visBounded, BOUNDS, MAINDATASET, DATAFORM); SetMethod(visBounded, TICLENGTH, MakeBoundedTicLength); AddSnapVar(visBounded, TICLENGTH); icon = NewIcon(0, 0, ICONBOX, "Bounds"); SetVar(icon, HELPSTRING, NewString("Select this icon to show controls for a bounded object, such \ as whether to draw bounds, axes, and tic marks.")); SetVar(visBounded, CONTROLICON, icon); SetVar(icon, PANELHELP, NewString("This panel lets you change the bounds \ around a visualization object and lets you decorate the bounds with an outline \ box.")); SetMethod(visBounded, XNAME, MakeBoundedXName); SetMethod(visBounded, YNAME, MakeBoundedYName); SetMethod(visBounded, ZNAME, MakeBoundedZName); AddSnapVar(visBounded, XNAME); AddSnapVar(visBounded, YNAME); AddSnapVar(visBounded, ZNAME); AddSnapVar(visBounded, BOUNDS); SetVar(visBounded, BOUNDSBOX, NewInt(0)); AddSnapVar(visBounded, BOUNDSBOX); visWalls = NewObject(visBounded, 0); AddToReferenceList(visWalls); SetMethod(visWalls, DRAW, DrawWalls); icon = NewIcon(0, 0, ICONWALLS, "Walls"); SetVar(icon, HELPSTRING, NewString("Select this icon to show controls to display the walls of the \ visualization object.")); SetVar(visWalls, CONTROLICON, icon); SetVar(icon, PANELHELP, NewString("There are six walls around every \ visualization object. This control panel lets you display these walls. The series of \ check boxes at the top allow you to turn on individual walls. The Wall check boxes \ display the walls themselves. The Shadow check boxes determine whether the \ visualization object casts a shadow on each wall. The shadows are intended to \ be used to see projections of the visualization objects along an axis and are \ not affected by lighting. The Mirror check boxes determine whether the visualization \ object is to be mirrored on the other side of the wall.\n\n\ The controls at the bottom control how each wall is displayed when its Wall button \ is on.")); SetMethod(visWalls, ADDCONTROLS, AddWallsControls); SetVar(visWalls, DRAWBACKGROUND, ObjTrue); AddSnapVar(visWalls, DRAWBACKGROUND); SetVar(visWalls, DRAWOUTLINE, ObjFalse); AddSnapVar(visWalls, DRAWOUTLINE); SetVar(visWalls, DRAWGRID, ObjFalse); AddSnapVar(visWalls, DRAWGRID); array = NewRealArray(1, 3L); elements = ELEMENTS(array); elements[0] = 0.5; elements[1] = 0.5; elements[2] = 0.5; SetVar(visWalls, WALLPANELCOLOR, array); AddSnapVar(visWalls, WALLPANELCOLOR); array = NewRealArray(1, 3L); elements = ELEMENTS(array); elements[0] = 0.75; elements[1] = 0.75; elements[2] = 0.75; SetVar(visWalls, WALLLINESCOLOR, array); AddSnapVar(visWalls, WALLLINESCOLOR); SetVar(visWalls, WALLPANELFLAGS, NewInt(0)); AddSnapVar(visWalls, WALLPANELFLAGS); SetVar(visWalls, WALLMIRRORFLAGS, NewInt(0)); AddSnapVar(visWalls, WALLMIRRORFLAGS); SetVar(visWalls, WALLSHADOWFLAGS, NewInt(0)); AddSnapVar(visWalls, WALLSHADOWFLAGS); /*Class for any colored object*/ visColored = NewObject(visWalls, 0); AddToReferenceList(visColored); icon = NewIcon(0, 0, ICONCOLOR, "Color"); SetVar(icon, HELPSTRING, NewString("Select this icon to show controls for a colored object, such \ as whether to color using a fixed color or a scalar field.")); SetVar(visColored, CONTROLICON, icon); SetVar(icon, PANELHELP, NewString("This panel lets you control how a \ visualization is colored. At the left is a miniature dataflow diagram which \ specifies that the basic color of an object comes from either a fixed color \ or from a color field. You can drag another field into the icon corral to change \ the field used to color the object. A control called a switch which looks like \ two lines coming into an arrow controls which is used. Click on the section of \ the switch to turn on. The color is passed through a brightness control, giving the \ final color. At the bottom left are controls for shading and transparency.")); SetMethod(visColored, ADDCONTROLS, AddColoredControls); SetVar(visColored, COLORSHADING, ObjTrue); /*Default smooth shaded*/ AddSnapVar(visColored, COLORSHADING); DeclareDependency(visColored, PICCOLORED, INTERPCOLORS); AddSnapVar(visColored, INTERPCOLORS); DeclareDependency(visColored, PICCOLORED, COLORS); AddSnapVar(visColored, COLORS); SetMethod(visColored, COLORS, MakeVisColors); DeclareDependency(visColored, PICCOLORED, COLOROBJ); AddSnapVar(visColored, COLOROBJ); DeclareDependency(visColored, PICCOLORED, CPALETTE); DeclareDependency(visColored, CACHEDOPAQUE, PICCOLORED); AddSnapVar(visColored, PICCOLORED); DeclareDependency(visColored, CACHEDTRANSPARENT, PICCOLORED); DeclareDependency(visColored, APPEARANCE, PICCOLORED); DeclareIndirectDependency(visColored, PICCOLORED, CPALETTE, CHANGED); SetMethod(visColored, PICCOLORED, MakePicColored); var = NewRealArray(1, 3L); elements = ELEMENTS(var); elements[0] = elements[1] = elements[2] = 1.0; SetVar(visColored, BASECOLOR, var); AddSnapVar(visColored, BASECOLOR); SetVar(visColored, BRIGHTNESS, NewReal(1.0)); AddSnapVar(visColored, BRIGHTNESS); SetVar(visColored, INTERPCOLORS, ObjTrue); /*Interpolate colors*/ DeclareDependency(visColored, CPALETTE, COLORS); DeclareDependency(visColored, CPALETTE, BRIGHTNESS); DeclareDependency(visColored, CPALETTE, BASECOLOR); DeclareDependency(visColored, CPALETTE, COLOROBJ); DeclareIndirectDependency(visColored, CPALETTE, COLOROBJ, PALETTESET); DeclareIndirectDependency(visColored, CPALETTE, COLOROBJ, CPALETTE); SetMethod(visColored, CPALETTE, MakeColoredPalette); SetMethod(visColored, PREFIXDATASETS, PrefixColoredDatasets); SetVar(visColored, INTERPOLATEP, ObjTrue); /*Class for any object with dots*/ visDots = NewObject(visColored, 0); icon = NewIcon(0, 0, ICONDOTS, "Dots"); SetVar(visDots, DEPTHCUEDOTS, ObjFalse); AddSnapVar(visDots, DEPTHCUEDOTS); SetMethod(visDots, ADDCONTROLS, AddDotsControls); SetVar(icon, HELPSTRING, NewString("Select this icon to show controls for drawing dots in the \ visualization object.")); SetVar(visDots, CONTROLICON, icon); SetVar(icon, PANELHELP, NewString("This control panel lets you show dots in the visualization \ object. The appearance of the dots depends on the visualization object in use.")); SetMethod(visDots, PICKPOINT, PickVisDots); SetMethod(visDots, DRAW, DrawVisDots); SetVar(visDots, DRAWDOTS, ObjFalse); AddSnapVar(visDots, DRAWDOTS); SetVar(visDots, ANTIALIASDOTS, ObjFalse); AddSnapVar(visDots, ANTIALIASDOTS); SetVar(visDots, BIGGERDOTS, ObjFalse); AddSnapVar(visDots, BIGGERDOTS); DeclareDependency(visDots, SURFACE, TIME); DeclareDependency(visDots, PICCOLORED, SURFACE); DeclareDependency(visDots, APPEARANCE, SURFACE); DeclareDependency(visDots, SURFACE, MAINDATASET); DeclareIndirectDependency(visDots, SURFACE, MAINDATASET, CHANGED); SetVar(visDots, CACHEGRAPHICS, ObjFalse); AddSnapVar(visDots, CACHEGRAPHICS); DeclareDependency(visDots, CACHEDOPAQUE, SURFACE); DeclareDependency(visDots, CACHEDOPAQUE, CACHEGRAPHICS); DeclareDependency(visDots, CACHEDTRANSPARENT, SURFACE); DeclareDependency(visDots, CACHEDTRANSPARENT, CACHEGRAPHICS); SetMethod(visDots, CACHEDOPAQUE, MakeCachedOpaque); SetMethod(visDots, CACHEDTRANSPARENT, MakeCachedTransparent); /*Class for any object with lines*/ visLines = NewObject(visDots, 0); SetVar(visLines, DRAWWIREFRAME, ObjTrue); AddSnapVar(visLines, DRAWWIREFRAME); SetVar(visLines, DEPTHCUELINES, ObjFalse); AddSnapVar(visLines, DEPTHCUELINES); SetVar(visLines, ANTIALIASLINES, ObjFalse); AddSnapVar(visLines, ANTIALIASLINES); SetVar(visLines, LINEWIDTH, NewInt(1)); AddSnapVar(visLines, LINEWIDTH); icon = NewIcon(0, 0, ICONLINES, "Lines"); SetMethod(visLines, ADDCONTROLS, AddLineControls); SetVar(icon, HELPSTRING, NewString("Select this icon to show controls for drawing lines in the \ visualization object.")); SetVar(visLines, CONTROLICON, icon); SetVar(icon, PANELHELP, NewString("This control panel allows you to edit \ the parameters used to draw the lines in the visualizaton object and also allows \ you to draw the visualization object as a wire frame.\n")); SetMethod(visLines, DRAW, DrawVisLines); /*Class for any object with a lit surface*/ visSurface = NewObject(visLines, 0); AddToReferenceList(visSurface); SetVar(visSurface, DRAWSURFACE, ObjTrue); AddSnapVar(visSurface, DRAWSURFACE); SetVar(visSurface, DRAWWIREFRAME, ObjFalse); icon = NewIcon(0, 0, ICONMATERIAL, "Surface"); SetVar(icon, HELPSTRING, NewString("Select this icon to show controls for a surface, such \ as surface highlights and translucency.")); SetVar(icon, PANELHELP, NewString("This panel allows you to change the parameters \ used to draw surfaces in the visualization object.")); SetMethod(visSurface, ADDCONTROLS, AddSurfaceControls); SetVar(visSurface, CONTROLICON, icon); SetVar(visSurface, LIGHTSHADING, NewInt(2)); /*Default smooth shaded*/ AddSnapVar(visSurface, LIGHTSHADING); SetVar(visSurface, SHINVAL, NewReal(80.0)); AddSnapVar(visSurface, SHINVAL); SetVar(visSurface, SPECVAL, NewReal(0.2)); AddSnapVar(visSurface, SPECVAL); SetMethod(visSurface, DRAW, DrawVisSurface); var = NewRealArray(1, 3L); elements = ELEMENTS(var); elements[0] = elements[1] = elements[2] = 1.0; SetVar(visSurface, HIGHLIGHTCOLOR, var); AddSnapVar(visSurface, HIGHLIGHTCOLOR); SetVar(visSurface, ISTRANSPARENT, ObjFalse); AddSnapVar(visSurface, ISTRANSPARENT); SetVar(visSurface, ISTRANSLUCENT, ObjFalse); AddSnapVar(visSurface, ISTRANSLUCENT); SetVar(visSurface, ALTTRANSLUCENT, ObjFalse); AddSnapVar(visSurface, ALTTRANSLUCENT); SetVar(visSurface, TWOSIDEDSURFACE, ObjFalse); AddSnapVar(visSurface, TWOSIDEDSURFACE); DeclareDependency(visSurface, APPEARANCE, ISTRANSPARENT); DeclareDependency(visSurface, APPEARANCE, ISTRANSLUCENT); DeclareDependency(visSurface, APPEARANCE, ALTTRANSLUCENT); /*Class for any object with a deformable surface*/ visDeformed = NewObject(visSurface, 0); AddToReferenceList(visDeformed); SetMethod(visDeformed, ADDCONTROLS, AddDeformedControls); icon = NewIcon(0, 0, ICONDEFORM, "Deform"); SetVar(icon, HELPSTRING, NewString("Select this icon to show controls that deform a visualization object.")); SetVar(visDeformed, CONTROLICON, icon); SetVar(icon, PANELHELP, NewString("This panel lets you control how a \ visualization is deformed. At the left is a miniature dataflow diagram which \ specifies that the deformation of an object comes from either a fixed deformation \ or from a field. You can drag another field into the icon corral to change \ the field used to deformed the object. A control called a switch which looks like \ two lines coming into an arrow controls which is used. Click on the section of \ the switch to turn on. The deformation is then multiplied by a factor and added \ to an offset, both of which you can edit. Objects are deformed by pushing out \ each vertex in the direction of its vertex normal. To prevent an object from \ being deformed, set it to a fixed deformation of 0 with and offset of 0.")); SetVar(visDeformed, DEFFACTOR, NewReal(1.0)); AddSnapVar(visDeformed, DEFFACTOR); SetVar(visDeformed, DEFCONSTANT, NewReal(0.0)); AddSnapVar(visDeformed, DEFCONSTANT); SetVar(visDeformed, DEFOFFSET, NewReal(0.0)); AddSnapVar(visDeformed, DEFOFFSET); SetMethod(visDeformed, DEFORMSWITCH, MakeVisDeformSwitch); AddSnapVar(visDeformed, DEFORMSWITCH); AddSnapVar(visDeformed, DEFORMOBJ); DeclareIndirectDependency(visDeformed, SURFACE, DEFORMOBJ, CHANGED); DeclareDependency(visDeformed, SURFACE, DEFORMOBJ); DeclareDependency(visDeformed, SURFACE, DEFCONSTANT); DeclareDependency(visDeformed, SURFACE, DEFOFFSET); DeclareDependency(visDeformed, SURFACE, DEFFACTOR); DeclareDependency(visDeformed, SURFACE, DEFORMSWITCH); DeclareDependency(visDeformed, PICDEFORMED, SURFACE); SetVar(visDeformed, REVERSESENSE, NewInt(0)); AddSnapVar(visDeformed, REVERSESENSE); /*DIKEO dependency on INTERPwhatever*/ SetMethod(visDeformed, PICDEFORMED, MakePicDeformed); /*Class for a geometry object*/ visGeometryClass = NewObject(visSurface, 0); AddToReferenceList(visGeometryClass); SetMethod(visGeometryClass, ADDCONTROLS, AddGeometryControls); icon = NewIcon(0, 0, ICONGEOMETRY, "Geometry"); SetVar(visGeometryClass, CONTROLICON, icon); SetVar(icon, HELPSTRING, NewString("Press this button to bring up controls \ for the geometry.")); SetVar(icon, PANELHELP, NewString("All visualization objects that use \ geometrical shapes, such as spheres and cylinders, must convert the shapes \ to polygons before displaying. This control panel allows you to specify how \ objects are converted to polygons.")); SetVar(visGeometryClass, SPHERESUBDIV, NewInt(2)); AddSnapVar(visGeometryClass, SPHERESUBDIV); SetVar(visGeometryClass, FRUSTUMSUBDIV, NewInt(2)); AddSnapVar(visGeometryClass, FRUSTUMSUBDIV); SetVar(visGeometryClass, CAPENDSP, ObjTrue); AddSnapVar(visGeometryClass, CAPENDSP); DeclareDependency(visGeometryClass, SURFACE, SPHERESUBDIV); DeclareDependency(visGeometryClass, SURFACE, FRUSTUMSUBDIV); DeclareDependency(visGeometryClass, SURFACE, CAPENDSP); /*Class for any object which can be sized*/ visSized = NewObject(visGeometryClass, 0); AddToReferenceList(visSized); SetMethod(visSized, ADDCONTROLS, AddSizedControls); icon = NewIcon(0, 0, ICONVISSIZE, "Size"); SetVar(icon, HELPSTRING, NewString("Select this icon to show controls to determine \ the size of the elements of the visualization object.")); SetVar(icon, PANELHELP, NewString("This panel lets you control how a \ visualization is sized. At the left is a miniature dataflow diagram which \ specifies that the sized of each element in the visualization \ comes from either a fixed size \ or from a field. You can drag another field into the icon corral to change \ the field used to deformed the object. A control called a switch which looks like \ two lines coming into an arrow controls which is used. Click on the section of \ the switch to turn on.")); SetVar(visSized, CONTROLICON, icon); SetVar(visSized, SIZEFACTOR, NewReal(1.0)); AddSnapVar(visSized, SIZEFACTOR); SetVar(visSized, SIZEOFFSET, NewReal(0.0)); AddSnapVar(visSized, SIZEOFFSET); SetVar(visSized, SIZECONSTANT, NewReal(1.0)); AddSnapVar(visSized, SIZECONSTANT); AddSnapVar(visSized, SIZESWITCH); AddSnapVar(visSized, SIZEOBJ); SetMethod(visSized, SIZESWITCH, MakeVisSizeSwitch); DeclareIndirectDependency(visSized, SURFACE, SIZEOBJ, CHANGED); DeclareDependency(visSized, SURFACE, SIZEOBJ); DeclareDependency(visSized, SURFACE, SIZECONSTANT); DeclareDependency(visSized, SURFACE, SIZEOFFSET); DeclareDependency(visSized, SURFACE, SIZEFACTOR); DeclareDependency(visSized, SURFACE, SIZESWITCH); /*Class for a geometry picture*/ geoPictureClass = NewObject(visGeometryClass, 0); AddToReferenceList(geoPictureClass); DefineFixedClass(geoPictureClass, CLASS_GEOPICTURE, "visGeoPicture"); SetVar(geoPictureClass, NAME, NewString("Geometry")); icon = NewObject(visIcon, 0); SetVar(icon, NAME, NewString("Geometry")); SetVar(icon, WHICHICON, NewInt(ICONGEOMETRY)); SetVar(icon, HELPSTRING, NewString("This icon represents a geometry object, which shows a \ geometry dataset directly as a picture in the space.")); SetVar(geoPictureClass, DEFAULTICON, icon); SetMethod(geoPictureClass, BOUNDS, MakeGeoPictureBounds); SetMethod(geoPictureClass, SURFACE, MakeGeoPictureSurface); SetMethod(geoPictureClass, COLORS, MakeGeoPictureColors); DeclareIndirectDependency(geoPictureClass, COLORS, REPOBJ, CPALETTE); SetMethod(geoPictureClass, NORMALSWITCH, MakeGeoPictureNormalSwitch); DeclareIndirectDependency(geoPictureClass, SURFACE, REPOBJ, CHANGED); SetMethod(geoPictureClass, PICCOLORED, MakeGeoPicColored); AddSnapVar(geoPictureClass, REPOBJ); InitLineEmitters(); InitHoseEmitters(); InitStreamlines(); InitStreamhoses(); InitArrows(); InitIsosurfaces(); InitMeshes(); InitContours(); InitTraces(); InitSticks(); InitPoints(); InitBalls(); InitNumbers(); DefineVisMapping(DS_HASGEOMETRY, -1, -1, -1, geoPictureClass); DefineVisMapping(DS_HASNEWGEOMETRY | DS_HASFORM | DS_UNSTRUCTURED, -1, -1, -1, geoPictureClass); } void KillVisObjects() /*Kills the visobjects*/ { KillNumbers(); KillBalls(); KillPoints(); KillStreamhoses(); KillStreamlines(); KillHoseEmitters(); KillLineEmitters(); KillSticks(); KillArrows(); KillContours(); KillIsosurfaces(); KillTraces(); DeleteThing(geoPictureClass); DeleteThing(visDeformed); DeleteThing(visSurface); DeleteThing(visColored); DeleteThing(visAxes); DeleteThing(visWalls); DeleteThing(visBounded); DeleteThing(visClass); DeleteThing(visIcon); while (nVisSerials) { --nVisSerials; Free(visSerials[nVisSerials] . name); } DeleteThing(allVisObjClasses); }