<> <> <> DIRECTORY Controls, FS, Imager, ImagerFont, ImagerInterpress, IO, Matrix3d, Rope, ThreeDIO, TubeDefs, TubeDisplay, TubeGeometry, TubeIO, TubeMisc; TubeIOImpl: CEDAR PROGRAM IMPORTS Controls, FS, Imager, ImagerFont, ImagerInterpress, IO, Matrix3d, Rope, ThreeDIO, TubeDisplay, TubeGeometry, TubeMisc EXPORTS TubeIO ~ BEGIN OPEN TubeDefs; Line: TYPE ~ ThreeDIO.Line; <> WriteTriple: PROC [stream: STREAM, t: Triple] ~ { WriteJustified[stream, t.x]; WriteJustified[stream, t.y]; WriteJustified[stream, t.z]; IO.PutF[stream, "\t"]; }; WriteJustified: PROC [stream: STREAM, r: REAL] ~ { IF r >= 0.0 THEN IO.PutF[stream, " "]; IO.PutF[stream, "%6.5f ", IO.real[r]] }; <> QueryAndWritePointsPoly: PUBLIC PROC [tube: Tube, o: OuterData, m: Matrix _ NIL] ~ { nPoints, nPolys: INT; fileName: ROPE _ Controls.TypeScriptReadFileName[o]; IF fileName = NIL THEN RETURN; [nPoints, nPolys] _ WritePointsPolys[tube, fileName, m]; Controls.TypeScriptWrite[o, IO.PutFR["%g points and %g polys written\n", IO.int[nPoints], IO.int[nPolys]]]; }; WritePointsPolys: PUBLIC PROC [tube: Tube, fileName: ROPE, m: Matrix _ NIL] RETURNS [nPoints, nPolys: INT] ~ { Point: PointProc ~ { IO.PutF[out, "%g\t", IO.int[id]]; WriteTriple[out, position]; WriteTriple[out, normal]; IO.PutF[out, "%6.5f %6.5f 0.0\n", IO.real[u], IO.real[v]]; }; Poly: PolyProc ~ { IO.PutF[out,"%g\t%4g %4g %4g\n", IO.int[id], IO.int[p0], IO.int[p1], IO.int[p2]]; }; out: STREAM _ FS.StreamOpen[fileName, $create]; IO.PutF[out, "Vertices~ index: integer xyzCoords: triple normalVec: triple textureCoords: triple\n\n"]; nPoints _ TubeMisc.Points[tube, Point, m]; IO.PutF[out, "\nPolygons~ index: integer vertices: nats\n\n"]; nPolys _ TubeMisc.Polys[tube, Poly]; IO.Close[out]; }; <> QueryAndWriteMaxPointsPoly: PUBLIC PROC [tube: Tube, o: OuterData, m: Matrix _ NIL] ~ { nPoints, nPolys: INT; fileName: ROPE _ Controls.TypeScriptReadFileName[o]; IF fileName = NIL THEN RETURN; [nPoints, nPolys] _ WriteMaxPointsPolys[tube, fileName, m]; Controls.TypeScriptWrite[o, IO.PutFR["%g points and %g polys written\n", IO.int[nPoints], IO.int[nPolys]]]; }; WriteMaxPointsPolys: PUBLIC PROC [tube: Tube, fileName: ROPE, m: Matrix _ NIL] RETURNS [nPoints, nPolys: INT] ~ { MaxPoint: PointProc ~ { IO.PutF[out, "%g,", IO.int[id]]; IO.PutF[out, "%6.5f,%6.5f,%6.5f,", IO.real[position.x], IO.real[position.y], IO.real[position.z]]; IO.PutF[out, "%6.5f,%6.5f,%6.5f,", IO.real[normal.x], IO.real[normal.y], IO.real[normal.z]]; IO.PutF[out, "%6.5f,%6.5f,\n", IO.real[u], IO.real[v]]; }; MaxPoly: PolyProc ~ { IO.PutF[out, "%g,%g,%g,%g,\n", IO.int[id], IO.int[p0], IO.int[p1], IO.int[p2]]; }; out: STREAM _ FS.StreamOpen[fileName, $create]; nPoints _ TubeMisc.Points[tube, MaxPoint, m]; IO.PutF[out, "-1\n"]; nPolys _ TubeMisc.Polys[tube, MaxPoly]; IO.PutF[out, "-1\n"]; IO.Close[out]; }; <> QueryAndWriteIP: PUBLIC PROC [tube: Tube, o: OuterData, details: Details, m: Matrix] ~ { fileName: ROPE _ Controls.TypeScriptReadFileName[o]; IF fileName # NIL THEN { ref: ImagerInterpress.Ref _ ImagerInterpress.Create[fileName]; WriteIP[ref, tube, details, m]; ImagerInterpress.Close[ref]; }; }; WriteIP: 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.DrawTube[tube, context, details, m]; }; ImagerInterpress.DoPage[ref, ContextProc]; }; <> QueryAndWriteTube: PUBLIC PROC [tube: Tube, o: OuterData, m: Matrix _ NIL] ~ { fileName: ROPE _ Controls.TypeScriptReadFileName[o]; IF fileName # NIL THEN { stream: STREAM _ FS.StreamOpen[fileName, $create]; IO.PutF[stream, "\n-- %g, format for each line:\n", IO.rope[fileName]]; IO.PutF[stream, "-- Tube: p0, p1, v0, v1, r0, r1 tw0, tw1 , nBranches\n\n"]; WriteTube[stream, tube, m]; IO.Close[stream]; }; }; WriteTube: PUBLIC PROC [stream: STREAM, tube: Tube, m: Matrix _ NIL] ~ { Write: TubeProc ~ { IO.PutF[stream, "Tube: "]; WriteTriple[stream, IF m = NIL THEN tube.p0 ELSE Matrix3d.Transform[tube.p0, m]]; WriteTriple[stream, IF m = NIL THEN tube.p1 ELSE Matrix3d.Transform[tube.p1, m]]; WriteTriple[stream, IF m = NIL THEN tube.v0 ELSE Matrix3d.TransformVec[tube.v0, m]]; WriteTriple[stream, IF m = NIL THEN tube.v1 ELSE Matrix3d.TransformVec[tube.v1, m]]; IO.PutF[stream, "%5.4f %5.4f ", IO.real[tube.r0], IO.real[tube.r1]]; IO.PutF[stream, "%5.4f %5.4f ", IO.real[tube.tw0], IO.real[tube.tw1]]; IO.PutF[stream, IF tube.next # NIL THEN "next " ELSE "no "]; IO.PutF[stream, "%g", IO.int[TubeMisc.NBranches[tube]]]; IO.PutF[stream, "\n"]; }; TubeMisc.ApplyToTube[tube, Write]; }; QueryAndReadTube: PUBLIC PROC [o: OuterData] RETURNS [Tube] ~ { tube: Tube _ NIL; name: ROPE _ Controls.TypeScriptReadFileName[o]; IF name # NIL THEN { stream: STREAM _ FS.StreamOpen[name ! FS.Error => GOTO noOpen]; tube _ ReadTube[stream]; IO.Close[stream]; EXITS noOpen => Controls.TypeScriptWrite[o, IO.PutFR["Couldn't open %g\n", IO.rope[name]]]; }; RETURN[tube]; }; ReadTube: PUBLIC PROC [stream: STREAM] RETURNS [Tube] ~ { GetTubeLine: PROC [stream: STREAM] RETURNS [line: Line] ~ { DO line _ ThreeDIO.GetLine[stream ! IO.EndOfStream => GOTO eof]; IF Rope.Equal[ThreeDIO.GetWord[line], "tube:", FALSE] THEN RETURN; REPEAT eof => RETURN[NIL]; ENDLOOP; }; InnerReadTube: PROC [prev: Tube] RETURNS [tube: Tube] ~ { line: Line _ GetTubeLine[stream]; IF line = NIL THEN RETURN[NIL]; tube _ NEW[TubeRep]; tube.prev _ prev; tube.p0 _ ThreeDIO.GetTriple[line]; tube.p1 _ ThreeDIO.GetTriple[line]; tube.v0 _ ThreeDIO.GetTriple[line]; tube.v1 _ ThreeDIO.GetTriple[line]; tube.r0 _ ThreeDIO.GetReal[line]; tube.r1 _ ThreeDIO.GetReal[line]; tube.tw0 _ ThreeDIO.GetReal[line]; tube.tw1 _ ThreeDIO.GetReal[line]; tube.next _ IF Rope.Equal[ThreeDIO.GetWord[line], "next", FALSE] THEN InnerReadTube[tube] ELSE NIL; tube.branches _ NEW[TubeSequenceRep[ThreeDIO.GetInteger[line]]]; tube.branches.length _ tube.branches.maxLength; TubeGeometry.SetCoeffs[tube]; IF tube.branches # NIL THEN FOR n: NAT IN [0..tube.branches.length) DO tube.branches[n] _ InnerReadTube[tube]; ENDLOOP; }; IF stream = NIL THEN RETURN[NIL] ELSE RETURN[InnerReadTube[NIL]]; }; WriteTubeInfo: PUBLIC PROC [tube: Tube, o: OuterData] ~ { nPoints, nPolys, minCres, maxCres: INTEGER; [nPoints, nPolys, minCres, maxCres] _ TubeMisc.Info[tube]; Controls.TypeScriptWrite[o, IO.PutFR["%g points, %g polygons, cres: %g-%g\n", IO.int[nPoints], IO.int[nPolys], IO.int[minCres], IO.int[maxCres]]]; }; END.