<> <> <> <> DIRECTORY CSGGraphics, DisplayList3d, GraphicsColor, IO, Matrix3d, Rope, SV2d, SV3d, SVArtwork, SVError, SVPolygon3d, SVMappings, SVMatrix2d, SVModelTypes, SVSceneTypes, TFI3d; TFI3dImpl: PROGRAM IMPORTS CSGGraphics, DisplayList3d, GraphicsColor, IO, Matrix3d, SVArtwork, SVError, SVMappings, SVMatrix2d, SVPolygon3d, Rope EXPORTS TFI3d = BEGIN Assembly: TYPE = SVSceneTypes.Assembly; Color: TYPE = GraphicsColor.Color; CoordSystem: TYPE = SVModelTypes.CoordSystem; DrawStyle: TYPE = SVModelTypes.DrawStyle; FileCamera: TYPE = SVSceneTypes.FileCamera; FrameBox: TYPE = REF FrameBoxObj; FrameBoxObj: TYPE = SVModelTypes.FrameBoxObj; Matrix3by3: TYPE = SV2d.Matrix3by3; Matrix4by4: TYPE = SV3d.Matrix4by4; OMap: TYPE = SVModelTypes.OMap; Plane: TYPE = SV3d.Plane; Point3d: TYPE = SV3d.Point3d; Point2d: TYPE = SV2d.Point2d; Projection: TYPE = SVModelTypes.Projection; Scene: TYPE = SVSceneTypes.Scene; Vector: TYPE = SV3d.Vector; Material: TYPE = SVModelTypes.Material; SMap: TYPE = SVModelTypes.SMap; CharClass: TYPE = IO.CharClass; <<{break, sepr, other}>> FileinMatrix: PUBLIC PROC [f: IO.STREAM] RETURNS [mat: Matrix4by4] = { mat _ Matrix3d.Identity[]; ReadRope[f, "["]; ReadBlankAndRope[f, "["]; mat[1][1] _ ReadBlankAndReal[f]; FOR j: NAT IN[2..4] DO ReadBlankAndRope[f,","]; mat[1][j] _ ReadBlankAndReal[f]; ENDLOOP; ReadBlank[f]; ReadBlankAndRope[f, "]"]; FOR i: NAT IN[2..3] DO ReadBlankAndRope[f, ","]; ReadBlankAndRope[f, "["]; mat[i][1] _ ReadBlankAndReal[f]; FOR j: NAT IN[2..4] DO ReadBlankAndRope[f, ","]; mat[i][j] _ ReadBlankAndReal[f]; ENDLOOP; ReadBlankAndRope[f, "]"]; ENDLOOP; ReadBlankAndRope[f, "]"]; }; -- end of FileinMatrix FileinMatrix3by3: PUBLIC PROC [f: IO.STREAM] RETURNS [mat: Matrix3by3] = { mat _ SVMatrix2d.Identity[]; ReadRope[f, "["]; ReadBlankAndRope[f, "["]; mat[1][1] _ ReadBlankAndReal[f]; FOR j: NAT IN[2..3] DO ReadBlankAndRope[f,","]; mat[1][j] _ ReadBlankAndReal[f]; ENDLOOP; ReadBlank[f]; ReadBlankAndRope[f, "]"]; ReadBlankAndRope[f, ","]; ReadBlankAndRope[f, "["]; mat[2][1] _ ReadBlankAndReal[f]; FOR j: NAT IN[2..3] DO ReadBlankAndRope[f, ","]; mat[2][j] _ ReadBlankAndReal[f]; ENDLOOP; ReadBlankAndRope[f, "]"]; ReadBlankAndRope[f, "]"]; }; -- end of FileinMatrix3by3 ReadRope: PUBLIC PROC [f: IO.STREAM, rope: Rope.ROPE] = { <> <> c: CHAR; endofstream: BOOL _ FALSE; FOR i: INT IN[1..Rope.Length[rope]] DO c _ IO.GetChar[f ! IO.EndOfStream => {endofstream _ TRUE; CONTINUE}]; IF endofstream THEN SIGNAL RopeNotOnTop [IO.GetIndex[f], NIL, rope]; IF NOT c = Rope.Fetch[rope,i-1] THEN SIGNAL RopeNotOnTop [IO.GetIndex[f], Rope.FromChar[c], rope]; ENDLOOP; }; RopeNotOnTop: PUBLIC SIGNAL [position: NAT, wasThere: Rope.ROPE, notThere: Rope.ROPE] = CODE; ReadChar: PUBLIC PROC [f: IO.STREAM, c: CHAR] = { streamC: CHAR _ IO.GetChar[f]; IF NOT c = streamC THEN SIGNAL RopeNotOnTop[IO.GetIndex[f], Rope.FromChar[streamC], Rope.FromChar[c]]; }; ReadReturn: PUBLIC PROC [f: IO.STREAM] = { <> ReadChar[f, IO.CR]; }; WordBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.TAB => RETURN [break]; IO.CR =>RETURN [break]; IO.SP => RETURN [break]; ', => RETURN [break]; '] => RETURN [break]; ') => RETURN [break]; ENDCASE => RETURN [other]; }; KeyWordBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR =>RETURN [break]; ': => RETURN [break]; ENDCASE => RETURN [other]; }; ReadWord: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { <, , or are encountered. Used to read in a rope which is data. ie the name of a coordinate system from a 3d file.>> [word, ----] _ IO.GetTokenRope[f, WordBreakProc !IO.EndOfStream => {word _ NIL; CONTINUE}]; }; ReadKeyWord: PUBLIC PROC [f: IO.STREAM] RETURNS [keyWord: Rope.ROPE, good: BOOL] = { < are encountered. If CR is encountered first, then good is FALSE since ":" is expected after a keyword.>> end: BOOL _ FALSE; nextChar: Rope.ROPE; [keyWord, ----] _ IO.GetTokenRope[f, KeyWordBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; keyWord _ NIL; RETURN}; [nextChar, ----] _ IO.GetTokenRope[f, KeyWordBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; RETURN}; good _ Rope.Equal[nextChar, ":", TRUE]; }; LineBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR =>RETURN [break]; ENDCASE => RETURN [other]; }; ReadLine: PUBLIC PROC [f: IO.STREAM] RETURNS [line: Rope.ROPE] = { < is encountered. Used to read Solidviews version rope>> end: BOOL _ FALSE; [line, ----] _ IO.GetTokenRope[f, LineBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {line _ NIL; RETURN}; [----, ----] _ IO.GetTokenRope[f, LineBreakProc]; -- remove }; WhiteSpaceProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM IO.TAB => RETURN [other]; IO.CR =>RETURN [other]; IO.SP => RETURN [other]; ENDCASE => RETURN [break]; }; ReadWhiteSpace: PUBLIC PROC [f: IO.STREAM] = { <'s, 's, and 's until something else is encountered. Signals RopeNotOnTop if no white space characters are found.>> whiteSpace: Rope.ROPE; end: BOOL _ FALSE; [whiteSpace, ----] _ IO.GetTokenRope[f, WhiteSpaceProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end OR Rope.Size[whiteSpace] = 0 THEN SIGNAL RopeNotOnTop[IO.GetIndex[f], "null", ""]; }; ReadBlank: PUBLIC PROC [f: IO.STREAM] = { <'s, 's, and 's until something else is encountered. Doesn't mind if no white space characters are found. Treats comments as white space.>> [] _ IO.SkipWhitespace[f, TRUE]; }; ReadHorizontalBlank: PUBLIC PROC [f: IO.STREAM] RETURNS [good: BOOL] = { <'s, and 's until something else is encountered. Returns good = FALSE if a CR is encountered before anything else>> whiteSpace: Rope.ROPE; c: CHAR; end: BOOL _ FALSE; good _ TRUE; [whiteSpace, ----] _ IO.GetTokenRope[f, HorizontalBlankProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; RETURN}; c _ Rope.Fetch[whiteSpace, 0]; SELECT c FROM IO.CR => {good _ FALSE; RETURN}; IO.TAB, IO.SP => {good _ TRUE; RETURN}; ENDCASE => {good _ TRUE; IO.Backup[f, c]; RETURN}; }; HorizontalBlankProc: SAFE PROC [char: CHAR] RETURNS [CharClass] = TRUSTED { SELECT char FROM IO.TAB, IO.SP => RETURN [other]; ENDCASE => RETURN [break]; }; ReadBlankAndRope: PUBLIC PROC [f: IO.STREAM, rope: Rope.ROPE] = { ReadBlank[f]; ReadRope[f, rope]; }; ReadBlankAndReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = { <> ReadBlank[f]; r _ ReadReal[f]; }; ReadBlankAndWord: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { <> ReadBlank[f]; word _ ReadWord[f]; }; ReadBlankAndNAT: PUBLIC PROC [f: IO.STREAM] RETURNS [n: NAT] = { <> ReadBlank[f]; n _ ReadNAT[f]; }; ReadPoint3d: PUBLIC PROC [f: IO.STREAM] RETURNS [point3d: Point3d] = { <,,]".>> ReadRope[f, "["]; point3d[1] _ ReadBlankAndReal[f]; ReadRope[f, ","]; point3d[2] _ ReadBlankAndReal[f]; ReadRope[f, ","]; point3d[3] _ ReadBlankAndReal[f]; ReadRope[f, "]"]; }; ReadPoint2d: PUBLIC PROC [f: IO.STREAM] RETURNS [point2d: Point2d] = { <,]".>> ReadRope[f, "["]; point2d[1] _ ReadBlankAndReal[f]; ReadRope[f, ","]; point2d[2] _ ReadBlankAndReal[f]; ReadRope[f, "]"]; }; ReadPoint2dAsPoint3d: PUBLIC PROC [f: IO.STREAM] RETURNS [point3d: Point3d] = { <,]". Fills in point3d[3] with zero.>> ReadRope[f, "["]; point3d[1] _ ReadBlankAndReal[f]; ReadRope[f, ","]; point3d[2] _ ReadBlankAndReal[f]; point3d[3] _ 0; ReadRope[f, "]"]; }; RealBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM '], ', => RETURN [break]; IO.CR =>RETURN [break]; IO.SP => RETURN [break]; ENDCASE => RETURN [other]; }; ReadReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = { <, or . Leaves these terminators on the stream.>> realRope: Rope.ROPE; end: BOOL _ FALSE; [realRope, ----] _ IO.GetTokenRope[f, RealBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {r _ 0.0; RETURN}; IF Rope.Find[realRope, ".", 0, FALSE] = -1 THEN realRope _ Rope.Concat[realRope, ".0"]; r _ IO.GetReal[IO.RIS[realRope]]; }; NATBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM '], IO.CR, IO.SP, '., ', => RETURN [break]; ENDCASE => RETURN [other]; }; ReadNAT: PUBLIC PROC [f: IO.STREAM] RETURNS [n: NAT] = { <, . Leaves these terminators on the stream.>> end: BOOL _ FALSE; intRope: Rope.ROPE; [intRope, ----] _ IO.GetTokenRope[f, NATBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {n _ 1; RETURN}; n _ IO.GetInt[IO.RIS[intRope]]; }; BoolBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { SELECT char FROM '], IO.CR, IO.SP, '., ', => RETURN [break]; ENDCASE => RETURN [other]; }; ReadBool: PUBLIC PROC [f: IO.STREAM] RETURNS [truth: BOOL, good: BOOL] = { <> end: BOOL _ FALSE; boolRope: Rope.ROPE; [boolRope, ----] _ IO.GetTokenRope[f, BoolBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; truth _ FALSE; RETURN}; good _ TRUE; IF Rope.Equal[boolRope, "TRUE", TRUE] THEN truth _ TRUE ELSE IF Rope.Equal[boolRope, "FALSE", TRUE] THEN truth _ FALSE ELSE {truth _ FALSE; good _ FALSE}; }; ReadColor: PUBLIC PROC [f: IO.STREAM] RETURNS [color: Color] = { r, g, b: REAL; ReadChar[f, '[]; r _ ReadBlankAndReal[f]; ReadChar[f, ',]; g _ ReadBlankAndReal[f]; ReadChar[f, ',]; b _ ReadBlankAndReal[f]; ReadChar[f, ']]; color _ GraphicsColor.RGBToColor[r, g, b]; }; -- end of ReadColor ReadSurface: PUBLIC PROC [f: IO.STREAM] RETURNS [surface: REF ANY] = { surfType: Rope.ROPE _ ReadBlankAndWord[f]; SELECT TRUE FROM Rope.Equal[surfType, "tube", FALSE] => { radius, height: REAL; ReadBlankAndRope[f, "[radius:"]; radius _ ReadBlankAndReal[f]; ReadBlankAndRope[f, ","]; ReadBlankAndRope[f, "height:"]; height _ ReadBlankAndReal[f]; ReadBlankAndRope[f, "]"]; surface _ SVMappings.CreateTube[radius, height]; }; Rope.Equal[surfType, "box", FALSE] => { boxSide: Vector; ReadBlank[f]; boxSide _ ReadPoint3d[f]; surface _ SVMappings.CreateBox[boxSide[1], boxSide[2], boxSide[3]]; }; Rope.Equal[surfType, "NIL"] => {}; ENDCASE => ERROR; }; -- end of ReadSurface ReadMaterial: PUBLIC PROC [f: IO.STREAM] RETURNS [material: Material] = { matRope: Rope.ROPE _ ReadWord[f]; success: BOOL; [material, success] _ SVArtwork.RopeToMaterial[matRope]; IF NOT success THEN ERROR; }; ReadSMap: PUBLIC PROC [f: IO.STREAM] RETURNS [sMap: SMap] = { mapRope: Rope.ROPE _ ReadWord[f]; success: BOOL; [sMap, success] _ SVArtwork.RopeToSMap[mapRope]; IF NOT success THEN ERROR; }; ReadOMap: PUBLIC PROC [f: IO.STREAM] RETURNS [oMap: OMap] = { mapRope: Rope.ROPE _ ReadWord[f]; success: BOOL; [oMap, success] _ SVArtwork.RopeToOMap[mapRope]; IF NOT success THEN ERROR; }; ReadCamera: PUBLIC PROC [f: IO.STREAM, worldCS: CoordSystem, scene: Scene, version: REAL] RETURNS [fileCamera: FileCamera] = { name: Rope.ROPE; origin, focusPoint: Point3d; slant, focalLength, resolution: REAL; projection: Projection; projectionRope: Rope.ROPE; clippingPlanes: LIST OF Plane; visibleAssemblies: LIST OF Rope.ROPE; frame: FrameBox; success: BOOL; ReadBlankAndRope[f, "Camera:"]; name _ ReadBlankAndWord[f]; ReadBlankAndRope[f, "origin:"]; ReadBlank[f]; origin _ ReadPoint3d[f]; ReadBlankAndRope[f, "focusPoint:"]; ReadBlank[f]; focusPoint _ ReadPoint3d[f]; ReadBlankAndRope[f, "slant:"]; slant _ ReadBlankAndReal[f]; ReadBlankAndRope[f, "resolution:"]; resolution _ ReadBlankAndReal[f]; ReadBlankAndRope[f, "focalLength:"]; focalLength _ ReadBlankAndReal[f]; IF version > 5.1 THEN { ReadBlankAndRope[f, "projection:"]; projectionRope _ ReadBlankAndWord[f]; [projection, success] _ CSGGraphics.RopeToProjection[projectionRope]; IF NOT success THEN projection _ perspective; } ELSE projection _ perspective; ReadBlankAndRope[f, "frame:"]; ReadBlank[f]; frame _ ReadFrame[f]; ReadBlankAndRope[f, "clippingPlanes:"]; clippingPlanes _ ReadClippingPlanes[f]; ReadBlankAndRope[f, "visibleAssemblies:"]; visibleAssemblies _ ReadListOfRope[f]; ReadBlank[f]; fileCamera _ DisplayList3d.CreateFileCamera[name, origin, focusPoint, slant, resolution, focalLength, projection, frame, clippingPlanes, visibleAssemblies]; }; ReadClippingPlanes: PUBLIC PROC [f: IO.STREAM] RETURNS [clippingPlanes: LIST OF Plane] = { plane: Plane; continue: BOOL; clippingPlanes _ NIL; continue _ ReadHorizontalBlank[f]; IF NOT continue THEN RETURN; plane _ ReadPlane[f]; clippingPlanes _ AppendPlaneToList[plane, clippingPlanes]; WHILE TRUE DO continue _ ReadHorizontalBlank[f]; IF NOT continue THEN RETURN; ReadRope[f, ","]; ReadBlank[f]; plane _ ReadPlane[f]; clippingPlanes _ AppendPlaneToList[plane, clippingPlanes]; ENDLOOP; }; AppendPlaneToList: PROC [plane: Plane, list: LIST OF Plane] RETURNS [LIST OF Plane] = { <> z: LIST OF Plane _ list; IF z = NIL THEN RETURN[CONS[plane,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[plane,NIL]; RETURN[list]; }; ReadPlane: PUBLIC PROC [f: IO.STREAM] RETURNS [plane: Plane] = { A, B, C, D: REAL; ReadBlankAndRope[f, "["]; A _ ReadBlankAndReal[f]; ReadBlankAndRope[f, ","]; B _ ReadBlankAndReal[f]; ReadBlankAndRope[f, ","]; C _ ReadBlankAndReal[f]; ReadBlankAndRope[f, ","]; D _ ReadBlankAndReal[f]; ReadBlankAndRope[f, "]"]; plane _ SVPolygon3d.PlaneFromCoefficients[A, B, C, D]; }; ReadStyle: PUBLIC PROC [f: IO.STREAM] RETURNS [style: DrawStyle] = { styleName: Rope.ROPE _ ReadBlankAndWord[f]; success: BOOL; [style, success] _ CSGGraphics.RopeToDrawStyle[styleName]; IF NOT success THEN style _ wire; }; -- end of ReadStyle ReadFrame: PUBLIC PROC [f: IO.STREAM] RETURNS [frame: FrameBox] = { success: BOOL; point: Point2d; frame _ NEW[FrameBoxObj]; ReadBlankAndRope[f, "["]; ReadBlank[f]; point _ ReadPoint2d[f]; frame.downLeft[1] _ point[1]; frame.upRight[2] _ point[2]; ReadBlankAndRope[f, ","]; ReadBlank[f]; point _ ReadPoint2d[f]; frame.upRight[1] _ point[1]; frame.downLeft[2] _ point[2]; ReadBlankAndRope[f, "fullScreen:"]; ReadBlank[f]; [frame.fullScreen, success] _ ReadBool[f]; IF NOT success THEN frame.fullScreen _ TRUE; ReadBlankAndRope[f, "]"]; }; -- end of ReadFrame RopesOnOneLineProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR =>RETURN [break]; IO.SP, IO.TAB, ', , '; => RETURN [sepr]; ENDCASE => RETURN [other]; }; ReadListOfRope: PUBLIC PROC [f: IO.STREAM] RETURNS [ropeList: LIST OF Rope.ROPE] = { rope: Rope.ROPE; end: BOOL _ FALSE; ropeList _ NIL; WHILE TRUE DO [rope, ----] _ IO.GetTokenRope[f, RopesOnOneLineProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end OR rope = NIL THEN RETURN; IF Rope.Equal[rope, Rope.FromChar[IO.CR]] THEN RETURN ELSE ropeList _ AppendRopeToRopeList[rope, ropeList]; ENDLOOP; }; AppendRopeToRopeList: PROC [rope: Rope.ROPE, list: LIST OF Rope.ROPE] RETURNS [LIST OF Rope.ROPE] = { <> z: LIST OF Rope.ROPE _ list; IF z = NIL THEN RETURN[CONS[rope,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[rope,NIL]; RETURN[list]; }; ReadVisibleAssemblies: PUBLIC PROC [f: IO.STREAM, scene: Scene] RETURNS [assemblyList: LIST OF Assembly] = { end: BOOL _ FALSE; assembly: Assembly; assemblyName: Rope.ROPE; continue, found: BOOL; assemblyList _ NIL; found _ TRUE; WHILE continue DO [assemblyName, ----] _ IO.GetTokenRope[f, RopesOnOneLineProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end OR assemblyName = NIL OR Rope.Equal[assemblyName, Rope.FromChar[IO.CR]] THEN continue _ FALSE ELSE { [assembly, ----] _ DisplayList3d.FindAssemblyFromName[assemblyName, scene !DisplayList3d.AssemblyNotFound => {found _ FALSE; CONTINUE}]; IF NOT found THEN { index: NAT; errorRope: Rope.ROPE; index _ IO.GetIndex[f]; errorRope _ IO.PutFR["Assembly %g not found at: %g.", [rope[assemblyName]], [integer[index]]]; SVError.Append[errorRope, TRUE, TRUE]; SVError.Blink[]; } ELSE assemblyList _ AppendAssemblyToList[assembly, assemblyList]; }; ENDLOOP; }; AppendAssemblyToList: PROC [assembly: Assembly, list: LIST OF Assembly] RETURNS [LIST OF Assembly] = { <> z: LIST OF Assembly _ list; IF z = NIL THEN RETURN[CONS[assembly,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[assembly,NIL]; RETURN[list]; }; END.