|
/*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);
}
|