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: 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];
};
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: BOOL ← FALSE;
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: NAT ← IO.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.ROPE ← NIL;
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: 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] = {
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.