TubeDisplayImpl:
CEDAR
PROGRAM
IMPORTS Controls, Draw2d, Draw3d, Matrix3d, Spline3d, TubeStructure, Vector3d
EXPORTS TubeDisplay
~ BEGIN
OPEN TubeDefs;
ShowTube:
PUBLIC
PROC [tube: Tube, context: Context, details: Details, view: Matrix] ~ {
IF details.skel THEN ShowSkel[tube, context, view];
IF details.spline THEN ShowSplines[tube, context, view];
IF details.lines THEN ShowLines[tube, context, view];
IF details.circles THEN ShowCircles[tube, context, view];
IF details.frames THEN ShowFrames[tube, context, view, details.label];
IF details.normals THEN ShowNormals[tube, context, view, details.label];
IF details.curv THEN ShowCurv[tube, context, view, details.label];
IF details.vel THEN ShowVel[tube, context, view, details.label];
IF details.acc THEN ShowAcc[tube, context, view, details.label];
};
ShowSkel:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix] ~ {
IF tube = NIL THEN RETURN;
Draw3d.PP[tube.p0, tube.p1, context, view, IF tube.selected THEN solid ELSE dot];
ShowSkel[tube.next, context, view];
FOR n:
NAT
IN [0..tube.nBranches)
DO
ShowSkel[tube.branches[n], context, view];
ENDLOOP;
};
ShowSplines:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix] ~ {
IF tube = NIL THEN RETURN;
IF tube.selected
THEN Draw3d.DrawCurve[tube.c, context, view]
ELSE Draw3d.DotCurve[tube.c, context, view];
ShowSplines[tube.next, context, view];
FOR n:
NAT
IN [0..tube.nBranches)
DO
ShowSplines[tube.branches[n], context, view];
ENDLOOP;
};
ShowSplineEnds:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix, mark: Draw2d.MarkType ← dot] ~ {
IF tube = NIL THEN RETURN;
Draw3d.Mark[tube.p0, context, view, mark];
Draw3d.Mark[tube.p1, context, view, mark];
ShowSplineEnds[tube.next, context, view];
FOR n:
NAT
IN [0..tube.nBranches)
DO
ShowSplines[tube.branches[n], context, view];
ENDLOOP;
};
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
p0, psave: Pair ←
Matrix3d.TransformD[Matrix3d.TransformPair[circle[0], t.frames[i].m], view];
FOR j:
NAT
IN[1..tube.circleRes)
DO
p1: Pair ← Matrix3d.TransformD[Matrix3d.TransformPair[circle[j], t.frames[i].m], view];
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];
FOR i:
NAT
IN[0..tube.circleRes)
DO
p0: Pair ← Matrix3d.TransformD[Matrix3d.TransformPair[circle[i], tube.frames[0].m], view];
FOR j:
NAT
IN[1..tube.axialRes)
DO
p1: Pair ← Matrix3d.TransformD[Matrix3d.TransformPair[circle[i],tube.frames[j].m],view];
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;
};
ShowFrames:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix, label:
BOOL] ~ {
names: ARRAY[0..2] OF Rope.ROPE ← ["x", "y", "z"];
ShowMatrix:
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]+m[i][0],m[3][1]+m[i][1],m[3][2]+m[i][2]],view];
Draw2d.Solid[context, o, p];
IF label THEN Draw2d.Label[context, p, names[i]];
ENDLOOP;
};
IF tube = NIL THEN RETURN;
FOR i:
NAT
IN[0..(
IF tube.next =
NIL
THEN tube.axialRes
ELSE tube.axialRes-1))
DO
IF tube.frames[i].m # NIL THEN ShowMatrix[tube.frames[i].m];
ENDLOOP;
ShowFrames[tube.next, context, view, label];
FOR n:
NAT
IN [0..tube.nBranches)
DO
ShowFrames[tube.branches[n], context, view, label];
ENDLOOP;
};
ShowNormals:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix, label:
BOOL] ~ {
See TubeIOImpl.Points
tapered: BOOL;
vFactor: REAL;
circle: PairSequence;
ShowN:
PROC [f: Frame] ~ {
FOR j:
NAT
IN[0..tube.circleRes)
DO
p: Triple ← Matrix3d.TransformPair[circle[j], f.m];
n: Triple ← Matrix3d.TransformVec[[circle[j].x, circle[j].y, 0.0], f.m];
IF tapered
THEN {
v: Triple ← Spline3d.Velocity[tube.c, f.t];
len: REAL ← Vector3d.Mag[n];
n ← Vector3d.Add[n, Vector3d.Mul[v, len*vFactor/Vector3d.Mag[v]]];
};
n ← Vector3d.Normalize[n];
Draw3d.PV[p, n, IF label THEN "n" ELSE NIL, context, view, , 0.1];
ENDLOOP;
};
IF tube = NIL THEN RETURN;
circle ← TubeStructure.GetCircle[tube.circleRes];
tapered ← tube.r1 # tube.r0;
IF tapered THEN vFactor ← (tube.r0-tube.r1)/Vector3d.Distance[tube.p0, tube.p1];
FOR i:
NAT
IN[0..(
IF tube.next =
NIL
THEN tube.axialRes
ELSE tube.axialRes-1))
DO
IF tube.frames[i].m # NIL THEN ShowN[tube.frames[i]];
ENDLOOP;
ShowNormals[tube.next, context, view, label];
FOR n:
NAT
IN [0..tube.nBranches)
DO
ShowNormals[tube.branches[n], context, view, label];
ENDLOOP;
};
ShowCurv:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix, label:
BOOL] ~ {
ShowK:
PROC [f: Frame] ~ {
p: Triple ← [f.m[3][0], f.m[3][1], f.m[3][2]];
k: Triple ← Spline3d.Curvature[tube.c, f.t];
Draw3d.PV[p, k, IF label THEN "k" ELSE NIL, context, view];
};
IF tube = NIL THEN RETURN;
FOR i:
NAT
IN[0..(
IF tube.next =
NIL
THEN tube.axialRes
ELSE tube.axialRes-1))
DO
IF tube.frames[i].m # NIL THEN ShowK[tube.frames[i]];
ENDLOOP;
ShowCurv[tube.next, context, view, label];
FOR n:
NAT
IN [0..tube.nBranches)
DO
ShowCurv[tube.branches[n], context, view, label];
ENDLOOP;
};
ShowVel:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix, label:
BOOL] ~ {
ShowV:
PROC [f: Frame] ~ {
p: Triple ← [f.m[3][0], f.m[3][1], f.m[3][2]];
v: Triple ← Spline3d.Velocity[tube.c, f.t];
Draw3d.PV[p, v, IF label THEN "v" ELSE NIL, context, view];
};
IF tube = NIL THEN RETURN;
FOR i: NAT IN[0..(IF tube.next = NIL THEN tube.axialRes ELSE tube.axialRes-1)) DO
IF tube.frames[i].m # NIL THEN ShowV[tube.frames[i]];
ENDLOOP;
ShowV[tube.frames[0]];
IF tube.next = NIL THEN ShowV[tube.frames[tube.axialRes-1]];
ShowVel[tube.next, context, view, label];
FOR n:
NAT
IN [0..tube.nBranches)
DO
ShowVel[tube.branches[n], context, view, label];
ENDLOOP;
};
ShowAcc:
PUBLIC
PROC [tube: Tube, context: Context, view: Matrix, label:
BOOL] ~ {
ShowA:
PROC [f: Frame] ~ {
p: Triple ← [f.m[3][0], f.m[3][1], f.m[3][2]];
a: Triple ← Spline3d.Acceleration[tube.c, f.t];
Draw3d.PV[p, a, IF label THEN "a" ELSE NIL, context, view];
};
IF tube = NIL THEN RETURN;
FOR i:
NAT
IN[0..(
IF tube.next =
NIL
THEN tube.axialRes
ELSE tube.axialRes-1))
DO
IF tube.frames[i].m # NIL THEN ShowA[tube.frames[i]];
ENDLOOP;
ShowAcc[tube.next, context, view, label];
FOR n:
NAT
IN [0..tube.nBranches)
DO
ShowAcc[tube.branches[n], context, view, label];
ENDLOOP;
};
NVectors:
PUBLIC
PROC [tube: Tube, details: Details]
RETURNS [
NAT] ~ {
sum: NAT ← 0;
IF details.on
THEN
FOR t: Tube ← tube, t.next
WHILE t #
NIL
DO
sum ← sum
+(IF details.circles THEN t.circleRes*t.axialRes ELSE 0)
+(IF details.lines THEN t.circleRes*t.axialRes ELSE 0)
+(IF details.frames THEN 3*t.axialRes ELSE 0);
ENDLOOP;
RETURN[sum];
};
ToggleDetail:
PUBLIC
PROC [details: Details, toToggle: DetailType, trueName, falseName: Rope.
ROPE, outerData: Controls.OuterData] ~ {
state: BOOL;
SELECT toToggle
FROM
auto => state ← details.auto ← NOT details.auto;
label => state ← details.label ← NOT details.label;
skel => state ← details.skel ← NOT details.skel;
pick => state ← details.pick ← NOT details.pick;
spline => state ← details.spline ← NOT details.spline;
circles => state ← details.circles ← NOT details.circles;
lines => state ← details.lines ← NOT details.lines;
frames => state ← details.frames ← NOT details.frames;
normals => state ← details.normals ← NOT details.normals;
curv => state ← details.curv ← NOT details.curv;
vel => state ← details.vel ← NOT details.vel;
acc => state ← details.acc ← NOT details.acc;
ENDCASE => NULL;
details.shape ← details.circles OR details.lines OR details.frames OR details.normals;
details.on ← details.spline OR details.shape OR details.curv OR details.vel OR details.acc;
Controls.EntryToggle[outerData, state, trueName, falseName];
};
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;
};