DIRECTORY Controls, FS, Imager, ImagerFont, ImagerInterpress, IO, Matrix3d, Spline3d, TubeDefs, TubeDisplay, TubeIO, TubeStructure, Vector3d; TubeIOImpl: CEDAR PROGRAM IMPORTS Controls, FS, Imager, ImagerFont, ImagerInterpress, IO, Matrix3d, Spline3d, TubeDisplay, TubeStructure, Vector3d EXPORTS TubeIO ~ BEGIN OPEN TubeDefs; PI: REAL ~ 3.1415926535; OuterData: TYPE ~ Controls.OuterData; PointProc: TYPE ~ TubeIO.PointProc; PolyProc: TYPE ~ TubeIO.PolyProc; QueryAndPointsPolyOut: PUBLIC PROC [tube: Tube, outer: OuterData, m: Matrix _ NIL] ~ { nPoints, nPolys: INT; fileName: ROPE _ Controls.TypeScriptReadFileName[outer]; IF fileName = NIL THEN RETURN; [nPoints, nPolys] _ PointsPolysOut[tube, fileName, m]; Controls.TypeScriptWrite[outer, IO.PutFR["%g points and %g polys written\n", IO.int[nPoints], IO.int[nPolys]]]; }; QueryAndMaxPointsPolyOut: PUBLIC PROC [tube: Tube, outer: OuterData, m: Matrix _ NIL] ~ { nPoints, nPolys: INT; fileName: ROPE _ Controls.TypeScriptReadFileName[outer]; IF fileName = NIL THEN RETURN; [nPoints, nPolys] _ MaxPointsPolysOut[tube, fileName, m]; Controls.TypeScriptWrite[outer, IO.PutFR["%g points and %g polys written\n", IO.int[nPoints], IO.int[nPolys]]]; }; PointsPolysOut: PUBLIC PROC [tube: Tube, fileName: ROPE, m: Matrix _ NIL] RETURNS [nPoints, nPolys: INT] ~ { out: IO.STREAM _ FS.StreamOpen[fileName, $create]; IO.PutF[out, "Vertices: idx: xyz: nrm: uvw:\n\n"]; nPoints _ Points[tube, out, , m]; IO.PutF[out, "\nPolygons: idx:\n\n"]; nPolys _ Polys[tube, out]; IO.Close[out]; }; MaxPointsPolysOut: PUBLIC PROC [tube: Tube, fileName: ROPE, m: Matrix _ NIL] RETURNS [nPoints, nPolys: INT] ~ { out: IO.STREAM _ FS.StreamOpen[fileName, $create]; nPoints _ Points[tube, out, MaxPointProc, m]; IO.PutF[out, "-1\n"]; nPolys _ Polys[tube, out, MaxPolyProc]; IO.PutF[out, "-1\n"]; IO.Close[out]; }; DefaultPointProc: PUBLIC PointProc ~ { IO.PutF[out, "%g\t", IO.int[id]]; IO.PutF[out, "%6.5f %6.5f %6.5f\t", IO.real[p.x], IO.real[p.y], IO.real[p.z]]; IO.PutF[out, "%6.5f %6.5f %6.5f\t", IO.real[n.x], IO.real[n.y], IO.real[n.z]]; IO.PutF[out, "%6.5f %6.5f 0.0\n", IO.real[u], IO.real[v]]; }; DefaultPolyProc: PUBLIC PolyProc ~ { IO.PutF[out,"%g\t%4g %4g %4g\n", IO.int[id], IO.int[p0], IO.int[p1], IO.int[p2]]; }; MaxPointProc: PUBLIC PointProc ~ { IO.PutF[out, "%g,", IO.int[id]]; IO.PutF[out, "%6.5f,%6.5f,%6.5f,", IO.real[p.x], IO.real[p.y], IO.real[p.z]]; IO.PutF[out, "%6.5f,%6.5f,%6.5f,", IO.real[n.x], IO.real[n.y], IO.real[n.z]]; IO.PutF[out, "%6.5f,%6.5f,\n", IO.real[u], IO.real[v]]; }; MaxPolyProc: PUBLIC PolyProc ~ { IO.PutF[out, "%g,%g,%g,%g,\n", IO.int[id], IO.int[p0], IO.int[p1], IO.int[p2]]; }; Points: PUBLIC PROC [ tube: Tube, out: IO.STREAM, pointProc: PointProc _ DefaultPointProc, view: Matrix _ NIL] RETURNS [nPoints: INT] ~ { pointId: INT _ 0; uRangeStart: REAL _ 2.0*PI*tube.r0; OneSpline: PROC [t: Tube, iStart: NAT, uRange0, v: REAL] ~ { IF t # NIL THEN { uRange1: REAL _ uRange0*(0.5+0.5*(t.r1/t.r0)); -- a compromise duRange: REAL _ (uRange1-uRange0)/(t.axialRes-1.0); circle: PairSequence _ TubeStructure.GetCircle[t.circleRes]; tapered: BOOL _ t.r1 # t.r0; vFactor: REAL _ IF tapered THEN (t.r0-t.r1)/Vector3d.Distance[t.p0, t.p1] ELSE 1.0; pNow, pPrev: Triple _ t.p0; odd: BOOL _ t.circleRes MOD 2 = 1; istart: NAT _ IF t.prev # NIL AND t.prev.next = t AND t.prev.r1 = t.r0 THEN 1 ELSE 0; FOR i: NAT IN[iStart..t.axialRes) DO uRange: REAL _ uRange0+i*duRange; u: REAL _ 0.0; du: REAL _ 0.5*uRange/t.circleRes; m: Matrix _ t.frames[i].m; mm: Matrix _ IF view # NIL THEN Matrix3d.Mul[m, view] ELSE m; pPrev _ pNow; pNow _ [m[3][0], m[3][1], m[3][2]]; IF i # 0 THEN v _ v+Vector3d.Distance[pNow, pPrev]; FOR j: NAT IN[0..t.circleRes) DO p: Triple _ Matrix3d.TransformPair[circle[j], mm]; n: Triple _ Matrix3d.TransformVec[[circle[j].x, circle[j].y, 0.0], mm]; IF tapered THEN { vv: Triple _ Spline3d.Velocity[t.c, t.frames[i].t]; len: REAL _ Vector3d.Mag[n]; n _ Vector3d.Add[n, Vector3d.Mul[vv, len*vFactor/Vector3d.Mag[vv]]]; }; n _ Vector3d.Normalize[n]; pointProc[out, pointId, p, n, u, v]; pointId _ pointId+1; u _ IF j < t.circleRes/2 OR odd THEN u+du ELSE u-du; -- radial symmetry for u ENDLOOP; ENDLOOP; IF t.next # NIL AND t.next.circleRes = t.circleRes AND t.next.r0 = t.r1 THEN OneSpline[t.next, 1, uRange1, v] -- skip first frame ELSE OneSpline[t.next, 0, uRange1, v]; -- do first frame FOR n: NAT IN [0..t.nBranches) DO OneSpline[t.branches[n], 0, uRangeStart, v]; -- use first frame of first tube of branch ENDLOOP; }; }; OneSpline[tube, 0, uRangeStart, 0.0]; -- start with first frame of first tube RETURN[pointId]; }; Polys: PUBLIC PROC [tube: Tube, out: IO.STREAM, polyProc: PolyProc _ DefaultPolyProc] RETURNS [nPolys: INT] ~ { polyId, pointId: NAT _ 0; OneSpline: PROC [t: Tube] ~ { IF t # NIL THEN { cRes: NAT _ t.circleRes; FOR i: NAT IN [0..t.axialRes-1) DO -- connect ith frame to (i+1)th frame n: NAT _ pointId; FOR ii: NAT IN[0..cRes) DO nn: NAT _ IF ii = cRes-1 THEN pointId ELSE n+1; r: NAT _ n+cRes; rr: NAT _ nn+cRes; polyProc[out, polyId, r, nn, n]; polyId _ polyId+1; polyProc[out, polyId, rr, nn, r]; n _ n+1; polyId _ polyId+1; ENDLOOP; pointId _ pointId+cRes; ENDLOOP; IF t.next = NIL OR t.next.circleRes # t.circleRes OR t.next.r0 # t.r1 THEN pointId _ pointId+cRes; -- end of branch or discontinuity from t to t.next OneSpline[t.next]; FOR n: NAT IN [0..t.nBranches) DO OneSpline[t.branches[n]]; ENDLOOP; }; }; OneSpline[tube]; RETURN[polyId]; }; NPolys: PROC [tube: Tube] RETURNS [NAT] ~ { n: NAT _ 0; FOR t: Tube _ tube, t.next WHILE t # NIL DO n _ n+2*(t.axialRes-1)*t.circleRes; ENDLOOP; RETURN[n]; }; NPoints: PROC [tube: Tube] RETURNS [NAT] ~ { n: NAT _ 0; FOR t: Tube _ tube, t.next WHILE t # NIL DO n _ n+(t.axialRes-1)*t.circleRes; ENDLOOP; RETURN[n+tube.circleRes]; }; QueryAndIPOut: PUBLIC PROC [tube: Tube, outer: OuterData, details: Details, m: Matrix] ~ { fileName: ROPE _ Controls.TypeScriptReadFileName[outer]; IF fileName # NIL THEN { ref: ImagerInterpress.Ref _ ImagerInterpress.Create[fileName]; IPOut[ref, tube, details, m]; ImagerInterpress.Close[ref]; }; }; IPOut: PUBLIC PROC [ref: ImagerInterpress.Ref, tube: Tube, details: Details, m: Matrix] ~ { font: ImagerFont.Font _ ImagerFont.Scale[ImagerFont.Find["xerox/pressfonts/helvetica-mrr"], 12.0]; ContextProc: PROC [context: Context] ~ { metersPerPoint: REAL ~ .0254/72.0; Imager.ScaleT[context, metersPerPoint]; Imager.SetStrokeWidth[context, 1.0]; Imager.SetStrokeEnd[context, round]; Imager.SetFont[context, font]; Imager.TranslateT[context, [0.0, 0.5*11.0*72.0]]; TubeDisplay.ShowTube[tube, context, details, m]; }; ImagerInterpress.DoPage[ref, ContextProc]; }; WriteTubeInfo: PUBLIC PROC [tube: Tube, outer: OuterData] ~ { nPoints, nPolys, minCres, maxCres: INTEGER; [nPoints, nPolys, minCres, maxCres] _ TubeStructure.TubeResInfo[tube]; Controls.TypeScriptWrite[outer, IO.PutFR["%g points, %g polygons, cres: %g-%g\n", IO.int[nPoints], IO.int[nPolys], IO.int[minCres], IO.int[maxCres]]]; }; END. žTubeIOImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Bloomenthal, May 22, 1986 11:54:44 pm PDT See TubeDisplayImpl.ShowNormals Κ ˜šœ™Jšœ Οmœ1™Kšœ žœ&˜3Jšœ<˜˜>Jšœ˜Jšœ˜J˜—J˜J˜—š‘œžœžœI˜[Jšœ:Οsœ ˜bš‘ œžœ˜(Kšœžœ˜"Kšœ'˜'K˜$K˜$Jšœ˜J˜1Jšœ0˜0Jšœ˜—J˜Jšœ*˜*J˜—J˜š‘ œž œ#˜=Jšœ#žœ˜+JšœF˜Fšœžœ/˜QJšžœžœžœžœ˜D—J˜—J˜Jšžœ˜J˜—J˜—…—ˆ%6