TubeDisplayImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, February 24, 1987 6:14:41 pm PST
DIRECTORY Contours, Draw2d, Draw3d, Imager, Matrix3d, Rope, Spline3d, TubeDefs, TubeDisplay, TubeMisc, Vector3d;
~
BEGIN
OPEN TubeDefs;
DrawTube:
PUBLIC
PROC [tube: Tube, context: Context, details: Details, view: Matrix] ~ {
IF details = NIL THEN details ← NEW[DetailsRep];
IF details.skeleton THEN DrawSkeleton[tube, context, view];
IF details.spline THEN DrawSplines[tube, context, view];
IF details.lines THEN DrawLines[tube, context, view];
IF details.contours THEN DrawContours[tube, context, view];
IF details.frames THEN DrawFrames[tube, context, view, details.label];
IF details.curvature THEN DrawCurvature[tube, context, view, details.label];
IF details.velocity THEN DrawVelocity[tube, context, view, details.label];
IF details.acceleration THEN DrawAcceleration[tube, context, view, details.label];
IF details.normals THEN DrawNormals[tube, context, view, details.label];
};
DrawSkeleton:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix] ~ {
ApplyDraw: TubeProc ~ {
Draw3d.Segment[context, tube.p0, tube.p1, view, IF tube.selected THEN solid ELSE dotted];
};
TubeMisc.ApplyToTube[tube, ApplyDraw];
};
DrawSplines:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix] ~ {
ApplyDraw: TubeProc ~ {
IF tube.selected
THEN Draw3d.Curve[context, tube.coeffs, view]
ELSE Draw3d.DotCurve[context, tube.coeffs, view];
};
TubeMisc.ApplyToTube[tube, ApplyDraw];
};
DrawSplineEnds:
PUBLIC
PROC [
tube: Tube, context: Context, view: Matrix, mark: MarkType ← dot] ~ {
ApplyDraw: TubeProc ~ {
Draw3d.Mark[context, tube.p0, view, , mark];
Draw3d.Mark[context, tube.p1, view, , mark];
};
TubeMisc.ApplyToTube[tube, ApplyDraw];
};
AxialDrawRes:
PROC [tube: Tube]
RETURNS [
INTEGER] ~ {
nFrames: NAT ← TubeMisc.NFrames[tube];
RETURN[IF tube.next = NIL THEN nFrames ELSE nFrames-1];
};
DrawContours:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix] ~ {
ApplyDraw: TubeProc ~ {
FOR i:
NAT
IN [0..AxialDrawRes[tube])
DO
f: Frame ← tube.frames[i];
IF f.contour #
NIL
AND f.contour.pairs #
NIL
THEN {
pairs: PairSequence ← f.contour.pairs;
p0, psave: Pair ← Matrix3d.TransformD[Matrix3d.TransformPair[pairs[0], f.matrix], view];
FOR j:
NAT
IN [1..pairs.length)
DO
p1: Pair ← Matrix3d.TransformD[Matrix3d.TransformPair[pairs[j], f.matrix], view];
Draw2d.Line[context, p0, p1];
p0 ← p1;
ENDLOOP;
Draw2d.Line[context, p0, psave];
};
ENDLOOP;
};
TubeMisc.ApplyToTube[tube, ApplyDraw];
};
DrawLines:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix] ~ {
ApplyDraw: TubeProc ~ {
Xform:
PROC [p: Pair, m: Matrix]
RETURNS [Pair] ~ {
RETURN[Matrix3d.TransformD[Matrix3d.TransformPair[p, m], view]];
};
allCircles: BOOL ← TRUE;
frames: FrameSequence ← tube.frames;
nFrames: NAT ← TubeMisc.NFrames[tube];
FOR i:
NAT
IN [0..nFrames)
DO
IF frames[i].contour #
NIL
AND
NOT frames[i].contour.circle
THEN {allCircles ← FALSE; EXIT};
ENDLOOP;
IF allCircles
THEN {
circle: PairSequence ← Contours.CirclePairs[tube.circleRes];
FOR i:
NAT
IN [0..tube.circleRes)
DO
p0: Pair ← Xform[circle[i], frames[0].matrix];
FOR j:
NAT
IN [1..nFrames)
DO
p1: Pair ← Xform[circle[i], frames[j].matrix];
Draw2d.Line[context, p0, p1];
p0 ← p1;
ENDLOOP;
ENDLOOP;
}
ELSE {
pc: REAL ← 0.0;
dpc: REAL ← 1.0/MAX[1, tube.circleRes];
FOR i:
NAT
IN [0..tube.circleRes)
DO
p0: Pair ← Xform[Contours.PercentPair[frames[0].contour, pc], frames[0].matrix];
FOR j:
NAT
IN [1..nFrames)
DO
p1: Pair ← Xform[Contours.PercentPair[frames[j].contour, pc], frames[j].matrix];
Draw2d.Line[context, p0, p1];
p0 ← p1;
ENDLOOP;
pc ← pc+dpc;
ENDLOOP;
};
};
TubeMisc.ApplyToTube[tube, ApplyDraw];
};
DrawFrames:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix, label:
BOOL] ~ {
names: ARRAY[0..2] OF Rope.ROPE ← ["x", "y", "z"];
ApplyDraw: TubeProc ~ {
DrawMatrix:
PROC [m: Matrix] ~ {
o: Pair ← Matrix3d.TransformD[[m[3][0], m[3][1], m[3][2]], view];
FOR i:
NAT
IN [0..2]
DO
p: Pair ← Matrix3d.TransformD[
[m[3][0]+0.5*m[i][0], m[3][1]+0.5*m[i][1], m[3][2]+0.5*m[i][2]], view];
Draw2d.Line[context, o, p];
IF label THEN Draw2d.Label[context, p, names[i]];
ENDLOOP;
};
FOR i:
NAT
IN [0..AxialDrawRes[tube])
DO
IF tube.frames[i].matrix # NIL THEN DrawMatrix[tube.frames[i].matrix];
ENDLOOP;
};
TubeMisc.ApplyToTube[tube, ApplyDraw];
};
DrawNormals:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix, label:
BOOL] ~ {
See TubeIO.Points
tapered: BOOL;
vFactor: REAL;
ApplyDraw: TubeProc ~ {
DrawN:
PROC [f: Frame] ~ {
FOR j:
NAT
IN [0..f.contour.pairs.length)
DO
p: Triple ← Matrix3d.TransformPair[f.contour.pairs[j], f.matrix];
n: Triple ← Matrix3d.TransformVec[[f.normals[j].x, f.normals[j].y, 0.0], f.matrix];
IF tapered
THEN {
v: Triple ← Spline3d.Velocity[tube.coeffs, f.t];
len: REAL ← Vector3d.Length[n];
n ← Vector3d.Add[n, Vector3d.Mul[v, len*vFactor/Vector3d.Length[v]]];
};
n ← Vector3d.Normalize[n];
Draw3d.Vector[context, p, n, view, IF label THEN "n" ELSE NIL, 0.1];
ENDLOOP;
};
tapered ← tube.r1 # tube.r0;
IF tapered THEN vFactor ← (tube.r0-tube.r1)/Vector3d.Distance[tube.p0, tube.p1];
FOR i:
NAT
IN [0..AxialDrawRes[tube])
DO
IF tube.frames[i].matrix # NIL THEN DrawN[tube.frames[i]];
ENDLOOP;
};
TubeMisc.ApplyToTube[tube, ApplyDraw];
};
DrawCurvature:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix, label:
BOOL] ~ {
ApplyDraw: TubeProc ~ {
DrawK:
PROC [f: Frame] ~ {
p: Triple ← [f.matrix[3][0], f.matrix[3][1], f.matrix[3][2]];
k: Triple ← Spline3d.Curvature[tube.coeffs, f.t];
Draw3d.Vector[context, p, k, view, IF label THEN "k" ELSE NIL];
};
FOR i:
NAT
IN [0..AxialDrawRes[tube])
DO
IF tube.frames[i].matrix # NIL THEN DrawK[tube.frames[i]];
ENDLOOP;
};
TubeMisc.ApplyToTube[tube, ApplyDraw];
};
DrawVelocity:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix, label:
BOOL] ~ {
ApplyDraw: TubeProc ~ {
DrawV:
PROC [f: Frame] ~ {
p: Triple ← [f.matrix[3][0], f.matrix[3][1], f.matrix[3][2]];
v: Triple ← Spline3d.Velocity[tube.coeffs, f.t];
Draw3d.Vector[context, p, v, view, IF label THEN "v" ELSE NIL];
};
FOR i:
NAT
IN [0..AxialDrawRes[tube])
DO
IF tube.frames[i].matrix # NIL THEN DrawV[tube.frames[i]];
ENDLOOP;
};
TubeMisc.ApplyToTube[tube, ApplyDraw];
};
DrawAcceleration:
PUBLIC
PROC [
tube: Tube, context: Context, view: Matrix, label: BOOL] ~ {
ApplyDraw: TubeProc ~ {
DrawA:
PROC [f: Frame] ~ {
p: Triple ← [f.matrix[3][0], f.matrix[3][1], f.matrix[3][2]];
a: Triple ← Spline3d.Acceleration[tube.coeffs, f.t];
Draw3d.Vector[context, p, a, view, IF label THEN "a" ELSE NIL];
};
FOR i:
NAT
IN [0..AxialDrawRes[tube])
DO
IF tube.frames[i].matrix # NIL THEN DrawA[tube.frames[i]];
ENDLOOP;
};
TubeMisc.ApplyToTube[tube, ApplyDraw];
};
NVectors:
PUBLIC
PROC [tube: Tube, details: Details]
RETURNS [
INTEGER] ~ {
sum: INTEGER ← 0;
IF details.enabled
THEN
FOR t: Tube ← tube, t.next
WHILE t #
NIL
DO
nFrames: INTEGER ← TubeMisc.NFrames[t];
sum ← sum
+(IF details.lines THEN t.circleRes*nFrames ELSE 0)
+(IF details.frames THEN 3*nFrames ELSE 0);
FOR n:
NAT
IN [0..nFrames)
DO
f: Frame ← t.frames[n];
sum ← sum+(IF f.contour # NIL THEN f.contour.pairs.length ELSE t.circleRes);
ENDLOOP;
ENDLOOP;
RETURN[sum];
};