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;
TubeDisplayImpl: CEDAR PROGRAM
IMPORTS Contours, Draw2d, Draw3d, Matrix3d, Spline3d, TubeMisc, Vector3d
EXPORTS TubeDisplay
~ 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: BOOLTRUE;
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];
};
END.
..
ShowCircles: PUBLIC PROC [tube: Tube, context: Context, view: Matrix] ~ {
InnerShowCircles: PROC [t: Tube] ~ {
circle: PairSequence ← TubeStructure.GetCircle[tube.circleRes];
FOR i: NAT IN [0..(IF t.next = NIL THEN t.axialRes ELSE t.axialRes-1)) DO
m: Matrix ← Matrix3d.Mul[t.frames[i].m, view];
psave, p0: Pair ← Matrix3d.TransformPairD[circle[0], m];
FOR j: NAT IN [1..tube.circleRes) DO
p1: Pair ← Matrix3d.TransformPairD[circle[j], m];
Draw2d.Solid[context, p0, p1];
p0 ← p1;
ENDLOOP;
Draw2d.Solid[context, p0, psave];
ENDLOOP;
};
IF tube = NIL THEN RETURN;
InnerShowCircles[tube];
ShowCircles[tube.next, context, view];
FOR n: NAT IN [0..tube.nBranches) DO
ShowCircles[tube.branches[n], context, view];
ENDLOOP;
};
ShowLines: PUBLIC PROC [tube: Tube, context: Context, view: Matrix] ~ {
circle: PairSequence;
IF tube = NIL THEN RETURN;
circle ← TubeStructure.GetCircle[tube.circleRes];
IF xmats = NIL OR tube.axialRes > xmats.length
THEN xmats ← NEW[MatrixSeqRep[tube.axialRes]];
FOR i: NAT IN [0..tube.axialRes) DO
xmats[i] ← Matrix3d.Mul[tube.frames[i].m, view--, xmats[i]--];
ENDLOOP;
FOR i: NAT IN [0..tube.circleRes) DO
p0: Pair ← Matrix3d.TransformPairD[circle[i], xmats[0]];
FOR j: NAT IN [1..tube.axialRes) DO
p1: Pair ← Matrix3d.TransformPairD[circle[i], xmats[j]];
Draw2d.Solid[context, p0, p1];
p0 ← p1;
ENDLOOP;
ENDLOOP;
ShowLines[tube.next, context, view];
FOR n: NAT IN [0..tube.nBranches) DO
ShowLines[tube.branches[n], context, view];
ENDLOOP;
};