<> <> <> 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: 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] ~ { <> 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. .. <<>> <> <> <> <<>> <> <> <> <<>> <> <> <> <> <> <<>> <> <> <<};>> <<>> <> <> <<>> <> <<>> <> <> <> <<};>> <<>> <> <> <<>> <> <> <<>> < xmats.length>> <> <<>> <> <> <> <<>> <> <> <> <> <> <> <> <> <<>> <> <<>> <> <> <> <<};>> <<>> <<>>