File: TFI3dImpl.mesa (Text File-In for 3d scenes)
Last edited by Bier on July 17, 1987 12:45:56 pm PDT
Copyright © 1984 by Xerox Corporation. All rights reserved.
Contents: convenience functions for parsing low-level parts of a 3d fileout produced by fileout3d.mesa
DIRECTORY
AtomButtonsTypes, CoordSys, Feedback, FS, GGParseIn, Imager, ImagerColor, IO, Matrix3d, Rope, SV2d, SV3d, SVArtwork, SVGraphics, SVMappings, SVMatrix2d, SVModelTypes, SVPolygon3d, SVScene, SVSceneTypes, TFI3d, ViewerClasses;
TFI3dImpl: CEDAR PROGRAM
IMPORTS CoordSys, Feedback, FS, GGParseIn, ImagerColor, IO, Matrix3d, Rope, SVArtwork, SVGraphics, SVMappings, SVMatrix2d, SVPolygon3d, SVScene
EXPORTS TFI3d =
BEGIN
Artwork: TYPE = SVModelTypes.Artwork;
ArtworkClass: TYPE = SVModelTypes.ArtworkClass;
Color: TYPE = Imager.Color;
CoordSystem: TYPE = SVModelTypes.CoordSystem;
CoordSysList: TYPE = SVModelTypes.CoordSysList;
DrawStyle: TYPE = SVModelTypes.DrawStyle;
FeedbackData: TYPE = AtomButtonsTypes.FeedbackData;
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;
Slice: TYPE = SVSceneTypes.Slice;
SpaceFunction: TYPE = REF SpaceFunctionObj;
SpaceFunctionObj: TYPE = SVModelTypes.SpaceFunctionObj;
Vector3d: TYPE = SV3d.Vector3d;
Viewer: TYPE = ViewerClasses.Viewer;
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[];
GGParseIn.ReadWRope[f, "["];
GGParseIn.ReadWRope[f, "["];
mat[1][1] ← GGParseIn.ReadWReal[f];
FOR j: NAT IN[2..4] DO
GGParseIn.ReadWRope[f,","];
mat[1][j] ← GGParseIn.ReadWReal[f];
ENDLOOP;
GGParseIn.ReadBlank[f];
GGParseIn.ReadWRope[f, "]"];
FOR i: NAT IN[2..3] DO
GGParseIn.ReadWRope[f, ","];
GGParseIn.ReadWRope[f, "["];
mat[i][1] ← GGParseIn.ReadWReal[f];
FOR j: NAT IN[2..4] DO
GGParseIn.ReadWRope[f, ","];
mat[i][j] ← GGParseIn.ReadWReal[f];
ENDLOOP;
GGParseIn.ReadWRope[f, "]"];
ENDLOOP;
GGParseIn.ReadWRope[f, "]"];
}; -- end of FileinMatrix
FileinMatrix3by3: PUBLIC PROC [f: IO.STREAM] RETURNS [mat: Matrix3by3] = {
mat ← SVMatrix2d.Identity[];
GGParseIn.ReadWRope[f, "["];
GGParseIn.ReadWRope[f, "["];
mat[1][1] ← GGParseIn.ReadWReal[f];
FOR j: NAT IN[2..3] DO
GGParseIn.ReadWRope[f,","];
mat[1][j] ← GGParseIn.ReadWReal[f];
ENDLOOP;
GGParseIn.ReadBlank[f];
GGParseIn.ReadWRope[f, "]"];
GGParseIn.ReadWRope[f, ","];
GGParseIn.ReadWRope[f, "["];
mat[2][1] ← GGParseIn.ReadWReal[f];
FOR j: NAT IN[2..3] DO
GGParseIn.ReadWRope[f, ","];
mat[2][j] ← GGParseIn.ReadWReal[f];
ENDLOOP;
GGParseIn.ReadWRope[f, "]"];
GGParseIn.ReadWRope[f, "]"];
}; -- end of FileinMatrix3by3
RopeNotOnTop: PUBLIC SIGNAL [position: NAT, wasThere: Rope.ROPE, notThere: Rope.ROPE] = CODE;
ReadReturn: PUBLIC PROC [f: IO.STREAM] = {
Convenience function. Equivalent to GGParseIn.ReadChar[f, IO.CR];
GGParseIn.ReadChar[f, IO.CR];
};
KeyWordBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED {
SELECT char FROM
IO.CR =>RETURN [break];
': => RETURN [break];
ENDCASE => RETURN [other];
};
ReadKeyWord: PUBLIC PROC [f: IO.STREAM] RETURNS [keyWord: Rope.ROPE, good: BOOL] = {
Reads a rope until a ':' or <CR> are encountered. If CR is encountered first, then good is FALSE since ":" is expected after a keyword.
end: BOOLFALSE;
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];
};
ReadPoint3d: PUBLIC PROC [f: IO.STREAM] RETURNS [point3d: Point3d] = {
Assumes the next rope on the stream will be of the form "[<real1>,<real2>,<real3>]".
GGParseIn.ReadWRope[f, "["];
point3d[1] ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, ","];
point3d[2] ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, ","];
point3d[3] ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, "]"];
};
ReadPoint2d: PUBLIC PROC [f: IO.STREAM] RETURNS [point2d: Point2d] = {
Assumes the next rope on the stream will be of the form "[<real1>,<real2>]".
GGParseIn.ReadWRope[f, "["];
point2d[1] ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, ","];
point2d[2] ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, "]"];
};
ReadPoint2dAsPoint3d: PUBLIC PROC [f: IO.STREAM] RETURNS [point3d: Point3d] = {
Assumes the next rope on the stream will be of the form "[<real1>,<real2>]". Fills in point3d[3] with zero.
GGParseIn.ReadWRope[f, "["];
point3d[1] ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, ","];
point3d[2] ← GGParseIn.ReadWReal[f];
point3d[3] ← 0;
GGParseIn.ReadWRope[f, "]"];
};
ReadPlane: PUBLIC PROC [f: IO.STREAM] RETURNS [plane: Plane] = {
A, B, C, D: REAL;
GGParseIn.ReadWRope[f, "["];
A ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, ","];
B ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, ","];
C ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, ","];
D ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, "]"];
plane ← SVPolygon3d.PlaneFromCoefficients[A, B, C, D];
};
ReadColor: PUBLIC PROC [f: IO.STREAM] RETURNS [color: Color] = {
r, g, b: REAL;
GGParseIn.ReadChar[f, '[];
r ← GGParseIn.ReadWReal[f];
GGParseIn.ReadChar[f, ',];
g ← GGParseIn.ReadWReal[f];
GGParseIn.ReadChar[f, ',];
b ← GGParseIn.ReadWReal[f];
GGParseIn.ReadChar[f, ']];
color ← ImagerColor.ColorFromRGB[[r, g, b]];
}; -- end of ReadColor
ReadSurface: PUBLIC PROC [f: IO.STREAM] RETURNS [surface: REF ANY] = {
surfType: Rope.ROPE ← GGParseIn.ReadWWord[f];
SELECT TRUE FROM
Rope.Equal[surfType, "tube", FALSE] => {
radius, height: REAL;
GGParseIn.ReadWRope[f, "[radius:"];
radius ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, ","];
GGParseIn.ReadWRope[f, "height:"];
height ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, "]"];
surface ← SVMappings.CreateTube[radius, height];
};
Rope.Equal[surfType, "box", FALSE] => {
boxSide: Vector3d;
GGParseIn.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 ← GGParseIn.ReadWWord[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 ← GGParseIn.ReadWWord[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 ← GGParseIn.ReadWWord[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;
GGParseIn.ReadWRope[f, "Camera:"];
name ← GGParseIn.ReadWWord[f];
GGParseIn.ReadWRope[f, "origin:"];
GGParseIn.ReadBlank[f];
origin ← ReadPoint3d[f];
GGParseIn.ReadWRope[f, "focusPoint:"];
GGParseIn.ReadBlank[f];
focusPoint ← ReadPoint3d[f];
GGParseIn.ReadWRope[f, "slant:"];
slant ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, "resolution:"];
resolution ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, "focalLength:"];
focalLength ← GGParseIn.ReadWReal[f];
IF version > 5.1 THEN {
GGParseIn.ReadWRope[f, "projection:"];
projectionRope ← GGParseIn.ReadWWord[f];
[projection, success] ← SVGraphics.RopeToProjection[projectionRope];
IF NOT success THEN projection ← perspective;
}
ELSE projection ← perspective;
GGParseIn.ReadWRope[f, "frame:"];
GGParseIn.ReadBlank[f];
frame ← ReadFrame[f, version];
GGParseIn.ReadWRope[f, "clippingPlanes:"];
clippingPlanes ← ReadClippingPlanes[f];
GGParseIn.ReadWRope[f, "visibleAssemblies:"];
visibleAssemblies ← ReadListOfRope[f];
GGParseIn.ReadBlank[f];
fileCamera ← SVScene.CreateFileCamera[name, origin, focusPoint, slant, resolution, focalLength, projection, frame, clippingPlanes, visibleAssemblies];
};
ReadFrame: PUBLIC PROC [f: IO.STREAM, version: REAL] RETURNS [frame: FrameBox] = {
success: BOOL;
point: Point2d;
frame ← NEW[FrameBoxObj];
GGParseIn.ReadWRope[f, "["];
GGParseIn.ReadBlank[f];
point ← ReadPoint2d[f];
frame.downLeft[1] ← point[1];
frame.upRight[2] ← point[2];
GGParseIn.ReadWRope[f, ","];
GGParseIn.ReadBlank[f];
point ← ReadPoint2d[f];
frame.upRight[1] ← point[1];
frame.downLeft[2] ← point[2];
GGParseIn.ReadWRope[f, "fullScreen:"];
GGParseIn.ReadBlank[f];
[frame.fullScreen, success] ← GGParseIn.ReadBool[f, version];
IF NOT success THEN frame.fullScreen ← TRUE;
GGParseIn.ReadWRope[f, "]"];
}; -- end of ReadFrame
ReadClippingPlanes: PUBLIC PROC [f: IO.STREAM] RETURNS [clippingPlanes: LIST OF Plane] = {
plane: Plane;
continue: BOOL;
clippingPlanes ← NIL;
continue ← GGParseIn.ReadHorizontalBlank[f];
IF NOT continue THEN RETURN;
plane ← ReadPlane[f];
clippingPlanes ← AppendPlaneToList[plane, clippingPlanes];
WHILE TRUE DO
continue ← GGParseIn.ReadHorizontalBlank[f];
IF NOT continue THEN RETURN;
GGParseIn.ReadWRope[f, ","];
GGParseIn.ReadBlank[f];
plane ← ReadPlane[f];
clippingPlanes ← AppendPlaneToList[plane, clippingPlanes];
ENDLOOP;
};
ReadVisibleAssemblies: PUBLIC PROC [f: IO.STREAM, scene: Scene, feedback: FeedbackData] RETURNS [assemblyList: LIST OF Slice] = {
end: BOOLFALSE;
assembly: Slice;
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, ----] ← SVScene.FindAssemblyFromName[assemblyName, scene
! SVScene.AssemblyNotFound => {found ← FALSE; CONTINUE}];
IF NOT found THEN {
index: NATIO.GetIndex[f];
Feedback.PutF[feedback, oneLiner, "Slice %g not found at: %g.", [rope[assemblyName]], [integer[index]]];
Feedback.Blink[feedback];
}
ELSE assemblyList ← AppendAssemblyToList[assembly, assemblyList];
};
ENDLOOP;
};
AppendPlaneToList: PROC [plane: Plane, list: LIST OF Plane] RETURNS [LIST OF Plane] = {
A copy of List.Nconc1 for LIST OF Plane instead of LIST OF REF ANY
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];
};
ReadStyle: PUBLIC PROC [f: IO.STREAM] RETURNS [style: DrawStyle] = {
styleName: Rope.ROPE ← GGParseIn.ReadWWord[f];
success: BOOL;
[style, success] ← SVGraphics.RopeToDrawStyle[styleName];
IF NOT success THEN style ← wire;
}; -- end of ReadStyle
RopeToArtworkClass: PROC [className: Rope.ROPE] RETURNS [class: ArtworkClass] = {
SELECT TRUE FROM
Rope.Equal[className, "c"] => class ← justColor;
Rope.Equal[className, "justColor"] => class ← justColor;
Rope.Equal[className, "simpleSurface"] => class ← simpleSurface;
Rope.Equal[className, "spaceFunction"] => class ← spaceFunction;
ENDCASE => ERROR;
};
ReadArtwork: PUBLIC PROC [f: IO.STREAM, csList: CoordSysList, defaultCS: CoordSystem, wdir: Rope.ROPE, version: REAL, feedback: FeedbackData] RETURNS [artwork: Artwork] = {
source, isColorRope, nextWord, aisFileName: Rope.ROPENIL;
surface: REF ANY;
material: Material;
mat: Matrix3by3;
color: Imager.Color;
isColorFile: BOOL;
sMap: SMap;
oMap: OMap;
resolution: REAL;
success: BOOL;
csName, className: Rope.ROPE;
coordSys: CoordSystem;
class: ArtworkClass;
IF version >= 7.03 THEN {
className ← GGParseIn.ReadWWord[f];
class ← RopeToArtworkClass[className];
GGParseIn.ReadBlank[f];
material ← ReadMaterial[f];
GGParseIn.ReadBlank[f];
SELECT class FROM
justColor => {
color ← ReadColor[f];
artwork ← SVArtwork.CreateColorArtwork[color, material];
RETURN;
};
simpleSurface, spaceFunction => {
GGParseIn.ReadWRope[f, "coordSys: "];
csName ← GGParseIn.ReadWWord[f];
IF Rope.Equal[csName, "NIL"] THEN coordSys ← NIL
ELSE coordSys ← CoordSys.FindCoordSysInList[csName, csList];
};
ENDCASE => ERROR;
}
ELSE {
IF version > 5.2 THEN {
GGParseIn.ReadWRope[f, "coordSys: "];
csName ← GGParseIn.ReadWWord[f];
IF Rope.Equal[csName, "NIL"] THEN coordSys ← NIL
ELSE coordSys ← CoordSys.FindCoordSysInList[csName, csList];
GGParseIn.ReadWRope[f, "class: "];
className ← GGParseIn.ReadWWord[f];
class ← RopeToArtworkClass[className];
}
ELSE {
coordSys ← defaultCS;
class ← simpleSurface;
};
GGParseIn.ReadWRope[f, "material:"];
GGParseIn.ReadBlank[f];
material ← ReadMaterial[f];
};
GGParseIn.ReadWRope[f, "surface:"];
surface ← ReadSurface[f];
IF (surface # NIL) AND class # spaceFunction THEN {
nextWord ← GGParseIn.ReadWWord[f];
SELECT TRUE FROM
Rope.Equal[nextWord, "source:"] => {-- oMap and sMap are defaulted
source ← GGParseIn.ReadWWord[f];
SELECT TRUE FROM
ISTYPE[surface, SVModelTypes.Tube] => {oMap ← tubeO; sMap ← tubeS};
ISTYPE[surface, SVModelTypes.Box] => {oMap ← orthogonal; sMap ← unfoldedBox};
ENDCASE => ERROR;
};
Rope.Equal[nextWord, "SMap:"] => {
GGParseIn.ReadBlank[f];
sMap ← ReadSMap[f];
GGParseIn.ReadWRope[f, "OMap:"];
GGParseIn.ReadBlank[f];
oMap ← ReadOMap[f];
GGParseIn.ReadWRope[f, "source:"];
source ← GGParseIn.ReadWWord[f];
};
ENDCASE => ERROR;
isColorRope ← GGParseIn.ReadWWord[f];
SELECT TRUE FROM
Rope.Equal[isColorRope, "colorFile", FALSE] => isColorFile ← TRUE;
Rope.Equal[isColorRope, "bwFile", FALSE] => isColorFile ← FALSE;
ENDCASE => ERROR;
GGParseIn.ReadWRope[f, "resolution:"];
GGParseIn.ReadBlank[f];
resolution ← GGParseIn.ReadWReal[f];
GGParseIn.ReadWRope[f, "mat:"];
GGParseIn.ReadBlank[f];
mat ← FileinMatrix3by3[f];
success ← TRUE;
[aisFileName,,] ← FS.ExpandName[source, wdir
! FS.Error => {
IF error.group = user THEN {
success ← FALSE;
Feedback.Append[feedback, error.explanation, oneLiner];
CONTINUE;
};
}];
IF NOT success THEN ERROR SVArtwork.FileNotFound;
GGParseIn.ReadWRope[f, "color:"];
GGParseIn.ReadBlank[f];
color ← ReadColor[f];
artwork ← SVArtwork.CreateFileArtwork[coordSys, material, surface, oMap, sMap, aisFileName, isColorFile, color, resolution, mat]; -- may generate ERROR SVArtwork.FileNotFound
}
ELSE {
IF surface = NIL AND class#spaceFunction THEN {
GGParseIn.ReadWRope[f, "color:"];
GGParseIn.ReadBlank[f];
color ← ReadColor[f];
artwork ← SVArtwork.CreateColorArtwork[color, material]
}
ELSE {
spaceFunction: SpaceFunction;
GGParseIn.ReadWRope[f, "scalars:"];
spaceFunction ← NEW[SpaceFunctionObj];
GGParseIn.ReadBlank[f];
spaceFunction.scalars ← ReadPoint3d[f];
GGParseIn.ReadWRope[f, "func: colorcube"];
artwork ← SVArtwork.Create3DArtwork[coordSys, material, spaceFunction];
};
};
};
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: BOOLFALSE;
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] = {
A copy of List.Nconc1 for LIST OF Rope.ROPE instead of LIST OF REF ANY
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];
};
AppendAssemblyToList: PROC [assembly: Slice, list: LIST OF Slice] RETURNS [LIST OF Slice] = {
A copy of List.Nconc1 for LIST OF Slice instead of LIST OF REF ANY
z: LIST OF Slice ← 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.