0851
|
Scian.h,
ScianDatasets.h,
ScianDraw.c,
ScianMain.c,
ScianObjFunctions.c,
ScianPreferences.c,
ScianVisContours.c,
ScianVisMesh.c,
ScianVisTraces.c,
ScianVisWindows.c,
|
|
|
/*ScianVisTraces.c
Eric Pepke
September 9, 1991
Trace visualization object in SciAn
*/
#include "Scian.h"
#include "ScianTypes.h"
#include "ScianArrays.h"
#include "ScianWindows.h"
#include "ScianTextBoxes.h"
#include "ScianObjWindows.h"
#include "ScianIcons.h"
#include "ScianColors.h"
#include "ScianControls.h"
#include "ScianLists.h"
#include "ScianSpaces.h"
#include "ScianButtons.h"
#include "ScianSliders.h"
#include "ScianIDs.h"
#include "ScianDatasets.h"
#include "ScianErrors.h"
#include "ScianVisObjects.h"
#include "ScianVisWindows.h"
#include "ScianStyle.h"
#include "ScianPictures.h"
#include "ScianTimers.h"
#ifndef RELEASE
#define NSEGMENTS 10 /*Number of segments in a trace to show*/
ObjPtr traceClass; /*Class for trace*/
static ObjPtr MakeTraceBounds(object)
ObjPtr object;
/*Makes bounds for a trace*/
{
ObjPtr objBounds;
real bounds[6];
ObjPtr dataObj;
ObjPtr var;
int component;
long index, *dims;
real sample;
/*Go through all data expanding bounds*/
bounds[0] = 1E12;
bounds[1] = -1E12;
bounds[2] = 1E12;
bounds[3] = -1E12;
bounds[4] = 1E12;
bounds[5] = -1E12;
/*X bounds*/
dataObj = GetObjectVar("TraceBounds", object, XFIELD);
var = GetIntVar("TraceBounds", object, XTOPDIM);
if (!dataObj || !var)
{
return ObjFalse;
}
component = GetInt(var);
SetCurField(FIELD1, dataObj);
if (GetNComponents(FIELD1) < component)
{
component = GetNComponents(FIELD1);
}
if (CountComponentDims(FIELD1, component) != 1)
{
ReportError("TraceBounds", "Only one-dimensional components are valid in a trace");
return ObjFalse;
}
dims = GetComponentDims(FIELD1, component);
index = 0;
sample = SelectFieldComponent(FIELD1, component, &index);
bounds[0] = sample;
bounds[1] = sample;
for (index = 1; index < dims[0]; ++index)
{
sample = SelectFieldComponent(FIELD1, component, &index);
if (sample < bounds[0]) bounds[0] = sample;
if (sample > bounds[1]) bounds[1] = sample;
}
/*Y bounds*/
dataObj = GetObjectVar("TraceBounds", object, YFIELD);
var = GetIntVar("TraceBounds", object, YTOPDIM);
if (!dataObj || !var)
{
return ObjFalse;
}
component = GetInt(var);
SetCurField(FIELD1, dataObj);
if (GetNComponents(FIELD1) < component)
{
component = GetNComponents(FIELD1);
printf("Bumping component down to %d", component);
}
if (CountComponentDims(FIELD1, component) != 1)
{
ReportError("TraceBounds", "Only one-dimensional components are valid in a trace");
return ObjFalse;
}
dims = GetComponentDims(FIELD1, component);
index = 0;
sample = SelectFieldComponent(FIELD1, component, &index);
bounds[2] = sample;
bounds[3] = sample;
for (index = 1; index < dims[0]; ++index)
{
sample = SelectFieldComponent(FIELD1, component, &index);
if (sample < bounds[2]) bounds[2] = sample;
if (sample > bounds[3]) bounds[3] = sample;
}
/*Z bounds*/
dataObj = GetObjectVar("TraceBounds", object, ZFIELD);
var = GetIntVar("TraceBounds", object, ZTOPDIM);
if (!dataObj || !var)
{
return ObjFalse;
}
component = GetInt(var);
SetCurField(FIELD1, dataObj);
if (GetNComponents(FIELD1) < component)
{
component = GetNComponents(FIELD1);
}
if (CountComponentDims(FIELD1, component) != 1)
{
ReportError("TraceBounds", "Only one-dimensional components are valid in a trace");
return ObjFalse;
}
dims = GetComponentDims(FIELD1, component);
index = 0;
sample = SelectFieldComponent(FIELD1, component, &index);
bounds[4] = sample;
bounds[5] = sample;
for (index = 0; index < dims[0]; ++index)
{
sample = SelectFieldComponent(FIELD1, component, &index);
if (sample < bounds[4]) bounds[4] = sample;
if (sample > bounds[5]) bounds[5] = sample;
}
objBounds = NewRealArray(1, (long) 6);
CArray2Array(objBounds, bounds);
SetVar(object, BOUNDS, objBounds);
return ObjTrue;
}
static ObjPtr ChangeMovingTrace(object)
ObjPtr object;
/*Changed value for a moving trace*/
{
int movingTrace;
ObjPtr val;
ObjPtr repObj;
repObj = GetObjectVar("ChangeMovingTrace", object, REPOBJ);
if (!repObj)
{
return ObjFalse;
}
val = GetVar(object, VALUE);
if (val)
{
movingTrace = GetInt(val);
}
else
{
movingTrace = false;
}
DoNotDisturb(repObj, WAKEUP);
if (movingTrace)
{
SetVar(repObj, HILITESEGMENT, NewInt(1));
WakeMe(repObj, WAKEUP, Clock());
}
else
{
SetVar(repObj, HILITESEGMENT, NULLOBJ);
}
ImInvalid(repObj);
return ObjTrue;
}
static ObjPtr AddTraceControls(object, panelContents)
ObjPtr object, panelContents;
/*Adds controls for a trace object*/
{
int width;
int left, top;
ObjPtr checkBox;
int smooth;
width = CWINWIDTH - 2 * CORRALBORDER - CWINCORRALWIDTH;
left = MAJORBORDER;
top = CWINHEIGHT - MAJORBORDER;
/****UPDATE*** moving trace is not the best idea*/
/*Create the check box for moving trace*/
checkBox = NewCheckBox(left, left + width,
top - CHECKBOXHEIGHT, top,
"Moving Trace", GetVar(object, HILITESEGMENT) ? 1 : 0);
if (!checkBox)
{
return ObjFalse;
}
PrefixList(panelContents, checkBox);
SetVar(checkBox, HELPSTRING,
NewString("If this box is checked, a moving red trace will follow \
the trace through time.\n"));
SetVar(checkBox, PARENT, panelContents);
SetVar(checkBox, REPOBJ, object);
SetMethod(checkBox, CHANGEDVALUE, ChangeMovingTrace);
top -= CHECKBOXHEIGHT + CHECKBOXSPACING;
/*Create the check box for smooth trace*/
smooth = GetPredicate(object, SMOOTH);
checkBox = NewCheckBox(left, left + width,
top - CHECKBOXHEIGHT, top, "Smooth Trace", smooth);
if (!GetVar(object, SMOOTH))
{
SetVar(object, SMOOTH, NewInt(0));
}
if (!checkBox)
{
return ObjFalse;
}
PrefixList(panelContents, checkBox);
SetVar(checkBox, HELPSTRING,
NewString("If this box is checked, the trace will be drawn smoothly \
using a Cardinal spline. If not, the trace will be drawn with a series of \
line segments."));
SetVar(checkBox, PARENT, panelContents);
AssocDirectControlWithVar(checkBox, object, SMOOTH);
top -= CHECKBOXHEIGHT + CHECKBOXSPACING;
return ObjTrue;
}
static ObjPtr WakeTrace(object)
ObjPtr object;
/*Wakes up a trace*/
{
ObjPtr space;
WinInfoPtr window;
ObjPtr hiliteObj;
ObjPtr dataField;
long nSamples;
int xComponent;
ObjPtr var;
long *dims;
int hiliteSegment;
/*Set up X coordinate*/
dataField = GetObjectVar("WakeTrace", object, XFIELD);
var = GetIntVar("WakeTrace", object, XTOPDIM);
if (!dataField || !var)
{
return ObjFalse;
}
xComponent = GetInt(var);
SetCurField(FIELD1, dataField);
if (GetNComponents(FIELD1) < xComponent)
{
xComponent = GetNComponents(FIELD1);
}
if (CountComponentDims(FIELD1, xComponent) != 1)
{
ReportError("WakeTrace", "Only one-dimensional components are valid in a trace");
}
dims = GetComponentDims(FIELD1, xComponent);
nSamples = *dims;
/*Next highlighted segment*/
hiliteObj = GetVar(object, HILITESEGMENT);
if (hiliteObj)
{
hiliteSegment = GetInt(hiliteObj);
hiliteSegment += 1;
if (hiliteSegment > nSamples)
{
SetVar(object, HILITESEGMENT, NewInt(0));
}
else
{
SetVar(object, HILITESEGMENT, NewInt(hiliteSegment));
}
WakeMe(object, WAKEUP, Clock() + 1.0 / 30.0);
}
ImInvalid(object);
return ObjTrue;
}
static ObjPtr SetTraceMainDataset(visObj, dataSet)
ObjPtr visObj, dataSet;
/*Sets the main data set of visObj to dataSet*/
{
SetVar(visObj, XFIELD, dataSet);
SetVar(visObj, YFIELD, dataSet);
SetVar(visObj, ZFIELD, dataSet);
SetVar(visObj, MAINDATASET, dataSet);
return ObjTrue;
}
static ObjPtr InitTrace(visObj)
ObjPtr visObj;
/*Initializes a trace*/
{
SetVar(visObj, XTOPDIM, NewInt(0));
SetVar(visObj, YTOPDIM, NewInt(1));
SetVar(visObj, ZTOPDIM, NewInt(2));
return ObjTrue;
}
static ObjPtr DrawTrace(object)
ObjPtr object;
/*Draw a trace*/
{
#ifdef GRAPHICS
long k;
int xComponent, yComponent, zComponent;
int x, y, z;
real xScale, yScale, zScale;
ObjPtr dataField, var;
Bool smooth;
long *dims;
int hiliteSegment;
Coord curveSeg[4][3];
long nSamples; /*The number of samples*/
/*Get x, y, z, scale*/
var = GetRealVar("DrawTrace", object, XSCALE);
if (var)
{
xScale = GetReal(var);
}
else
{
xScale = 1.0;
}
var = GetRealVar("DrawTrace", object, YSCALE);
if (var)
{
yScale = GetReal(var);
}
else
{
yScale = 1.0;
}
var = GetRealVar("DrawTrace", object, ZSCALE);
if (var)
{
zScale = GetReal(var);
}
else
{
zScale = 1.0;
}
/*Set up X coordinate*/
dataField = GetObjectVar("DrawTrace", object, XFIELD);
var = GetIntVar("DrawTrace", object, XTOPDIM);
if (!dataField || !var)
{
return ObjFalse;
}
xComponent = GetInt(var);
SetCurField(FIELD1, dataField);
if (GetNComponents(FIELD1) < xComponent)
{
xComponent = GetNComponents(FIELD1);
}
if (CountComponentDims(FIELD1, xComponent) != 1)
{
ReportError("DrawTrace", "Only one-dimensional components are valid in a trace");
}
dims = GetComponentDims(FIELD1, xComponent);
nSamples = *dims;
/*Set up Y coordinate*/
dataField = GetObjectVar("DrawTrace", object, YFIELD);
var = GetIntVar("DrawTrace", object, YTOPDIM);
if (!dataField || !var)
{
return ObjFalse;
}
yComponent = GetInt(var);
SetCurField(FIELD2, dataField);
if (GetNComponents(FIELD2) < yComponent)
{
yComponent = GetNComponents(FIELD2);
}
if (CountComponentDims(FIELD2, yComponent) != 1)
{
ReportError("DrawTrace", "Only one-dimensional components are valid in a trace");
}
dims = GetComponentDims(FIELD2, yComponent);
if (*dims != nSamples)
{
/****UPDATE*** do something else*/
nSamples = MIN(*dims, nSamples);
}
/*Set up Z coordinate*/
dataField = GetObjectVar("DrawTrace", object, ZFIELD);
var = GetIntVar("DrawTrace", object, ZTOPDIM);
if (!dataField || !var)
{
return ObjFalse;
}
zComponent = GetInt(var);
SetCurField(FIELD3, dataField);
if (GetNComponents(FIELD3) < zComponent)
{
zComponent = GetNComponents(FIELD3);
}
if (CountComponentDims(FIELD3, zComponent) != 1)
{
ReportError("DrawTrace", "Only one-dimensional components are valid in a trace");
}
dims = GetComponentDims(FIELD3, zComponent);
if (*dims != nSamples)
{
/****UPDATE*** do something else*/
nSamples = MIN(*dims, nSamples);
}
/*Get smooth predicate*/
smooth = GetPredicate(object, SMOOTH);
/*Determine which segment to hilite, if any*/
var = GetVar(object, HILITESEGMENT);
if (var && IsInt(var))
{
hiliteSegment = GetInt(var);
}
else
{
hiliteSegment = -50;
}
SetLineWidth(1);
/*Make z-buffer read-only*/
BeginMask(true, true, true, false);
if (smooth)
{
int b, e;
curvebasis(CARDBASIS);
SetUIColor(WHITE);
/*Draw the unhilited segments*/
k = 0;
x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
curveSeg[0][0] = x;
curveSeg[0][1] = y;
curveSeg[0][2] = z;
curveSeg[1][0] = x;
curveSeg[1][1] = y;
curveSeg[1][2] = z;
k = 1;
x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
curveSeg[2][0] = x;
curveSeg[2][1] = y;
curveSeg[2][2] = z;
k = 2;
x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
curveSeg[3][0] = x;
curveSeg[3][1] = y;
curveSeg[3][2] = z;
for (k = 1; k < nSamples; ++k)
{
crv(curveSeg);
/*Shift everything down and add new point*/
curveSeg[0][0] = curveSeg[1][0];
curveSeg[0][1] = curveSeg[1][1];
curveSeg[0][2] = curveSeg[1][2];
curveSeg[1][0] = curveSeg[2][0];
curveSeg[1][1] = curveSeg[2][1];
curveSeg[1][2] = curveSeg[2][2];
curveSeg[2][0] = curveSeg[3][0];
curveSeg[2][1] = curveSeg[3][1];
curveSeg[2][2] = curveSeg[3][2];
if (k < nSamples - 1)
{
curveSeg[3][0] = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
curveSeg[3][1] = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
curveSeg[3][2] = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
}
}
/*Draw the hilited segments*/
SetUIColor(UIRED);
SetLineWidth(3);
b = hiliteSegment - NSEGMENTS;
e = hiliteSegment;
if (b < 0) b = 0;
if (e >= nSamples) e = nSamples - 1;
if (b > 0)
{
k = b - 1;
x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
curveSeg[0][0] = x;
curveSeg[0][1] = y;
curveSeg[0][2] = z;
++k;
}
else
{
k = b;
x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
curveSeg[0][0] = x;
curveSeg[0][1] = y;
curveSeg[0][2] = z;
}
x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
curveSeg[1][0] = x;
curveSeg[1][1] = y;
curveSeg[1][2] = z;
++k;
x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
curveSeg[2][0] = x;
curveSeg[2][1] = y;
curveSeg[2][2] = z;
++k;
x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
curveSeg[3][0] = x;
curveSeg[3][1] = y;
curveSeg[3][2] = z;
for (k = b + 1; k < e; ++k)
{
crv(curveSeg);
/*Shift everything down and add new point*/
curveSeg[0][0] = curveSeg[1][0];
curveSeg[0][1] = curveSeg[1][1];
curveSeg[0][2] = curveSeg[1][2];
curveSeg[1][0] = curveSeg[2][0];
curveSeg[1][1] = curveSeg[2][1];
curveSeg[1][2] = curveSeg[2][2];
curveSeg[2][0] = curveSeg[3][0];
curveSeg[2][1] = curveSeg[3][1];
curveSeg[2][2] = curveSeg[3][2];
if (k < nSamples - 1)
{
x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
curveSeg[3][0] = x;
curveSeg[3][1] = y;
curveSeg[3][2] = z;
}
}
}
else
{
/*Draw the unhilited segments*/
long b, e;
SetUIColor(WHITE);
SetLineWidth(1);
k = 0;
x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
y = yScale * SelectFieldComponent(FIELD2, yComponent, &k);
z = zScale * SelectFieldComponent(FIELD3, zComponent, &k);
move(x, y, z);
for (k = 1; k < nSamples; ++k)
{
x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
y = yScale * SelectFieldComponent(FIELD1, yComponent, &k);
z = zScale * SelectFieldComponent(FIELD1, zComponent, &k);
draw(x, y, z);
}
SetUIColor(UIRED);
SetLineWidth(3);
/*Draw the hilited segments*/
b = hiliteSegment - NSEGMENTS;
e = hiliteSegment;
if (b < 0) b = 0;
if (e >= nSamples) e = nSamples - 1;
x = xScale * SelectFieldComponent(FIELD1, xComponent, &b);
y = yScale * SelectFieldComponent(FIELD2, yComponent, &b);
z = zScale * SelectFieldComponent(FIELD3, zComponent, &b);
move(x, y, z);
for (k = b + 1; k <= e; ++k)
{
x = xScale * SelectFieldComponent(FIELD1, xComponent, &k);
y = yScale * SelectFieldComponent(FIELD1, yComponent, &k);
z = zScale * SelectFieldComponent(FIELD1, zComponent, &k);
draw(x, y, z);
}
}
SetLineWidth(1);
SetUIColor(UIGRAY50);
EndMask();
#endif
return ObjTrue;
}
#endif
void InitTraces()
/*Initializes the traces*/
{
#ifndef RELEASE
ObjPtr icon;
/*Class for a trace displayer*/
traceClass = NewObject(visColored, 0);
AddToReferenceList(traceClass);
SetVar(traceClass, NAME, NewString("Trace"));
SetMethod(traceClass, BOUNDS, MakeTraceBounds);
SetMethod(traceClass, ADDCONTROLS, AddTraceControls);
SetMethod(traceClass, SETMAINDATASET, SetTraceMainDataset);
SetMethod(traceClass, INITIALIZE, InitTrace);
icon = NewIcon(0, 0, ICONTRACE , "Trace");
SetVar(icon, HELPSTRING,
NewString("Select this icon to show controls for a trace, such \
as whether to smooth the trace and show a moving trace."));
SetVar(traceClass, CONTROLICON, icon);
icon = NewObject(visIcon, 0);
SetVar(icon, WHICHICON, NewInt(ICONTRACE));
SetVar(icon, NAME, NewString("Trace"));
SetVar(icon, HELPSTRING,
NewString("This icon represents a trace object. A trace object shows \
a 1-D vector field as a trace in 3-space, taking the x, y, and z positions \
from components of the vector."));
SetVar(traceClass, DEFAULTICON, icon);
SetMethod(traceClass, DRAW, DrawTrace);
SetMethod(traceClass, WAKEUP, WakeTrace);
/* DefineVisMapping(DS_HASFORM | DS_HASFIELD, 1, -1, -1, traceClass);
DefineVisMapping(DS_HASFIELD, 1, -1, -1, traceClass);
*/
DefineVisMapping(DS_HASFORM | DS_HASFIELD | DS_VECTOR, 1, -1, -1, traceClass);
DefineVisMapping(DS_HASFIELD | DS_VECTOR, 1, -1, -1, traceClass);
#endif
}
void KillTraces()
/*Kills the traces*/
{
#ifndef RELEASE
DeleteThing(traceClass);
#endif
}
|