-- File: TFO3dImpl.mesa
-- Last edited by Bier on December 19, 1982 7:58 pm
-- Author: Eric Bier on July 6, 1983 4:31 pm
-- Contents: Useful functions for creating text files to describe 3d objects and scenes. (used by Fileout3dImpl, BasicObject3dImpl and intended for use by programs which define other master objects to implement their FileoutProc [see DisplayList3d]).

DIRECTORY
 GraphicsColor,
IO,
 Matrix3d,
 Rope,
 SVArtwork,
 SVMappings,
 SVMatrix2d,
 TFO3d;

TFO3dImpl: PROGRAM
IMPORTS GraphicsColor, IO, SVArtwork
EXPORTS TFO3d =

BEGIN

Box: TYPE = SVMappings.Box;
Color: TYPE = GraphicsColor.Color;
Material: TYPE = SVArtwork.Material;
Matrix3by3: TYPE = SVMatrix2d.Matrix3by3;
Matrix4by4: TYPE = Matrix3d.Matrix4by4;
OMap: TYPE = SVArtwork.OMap;
Point3d: TYPE = Matrix3d.Point3d;
Tube: TYPE = SVMappings.Tube;
SMap: TYPE = SVArtwork.SMap;

FileoutMatrix: PUBLIC PROC [f: IO.STREAM, mat: Matrix4by4] = {
 f.PutF["[[%g",[real[mat[1][1]]]];
FOR j: NAT IN[2..4] DO
  f.PutF[",%g",[real[mat[1][j]]]];
ENDLOOP;
 f.PutF["]"];
FOR i: NAT IN[2..3] DO
  f.PutF[", [%g",[real[mat[i][1]]]];
  FOR j: NAT IN[2..4] DO
   f.PutF[",%g",[real[mat[i][j]]]];
  ENDLOOP;
  f.PutF["]"];
ENDLOOP;
 f.PutF["]"];
 };

FileoutMatrix3by3: PUBLIC PROC [f: IO.STREAM, mat: Matrix3by3] = {
 -- only writes the first 2 rows
 f.PutF["[[%g",[real[mat[1][1]]]];
FOR j: NAT IN[2..3] DO
  f.PutF[",%g",[real[mat[1][j]]]];
ENDLOOP;
 f.PutF["]"];
 f.PutF[", [%g",[real[mat[2][1]]]];
FOR j: NAT IN[2..3] DO
  f.PutF[",%g",[real[mat[2][j]]]];
ENDLOOP;
 f.PutF["]]"];
 };

FileoutPoint3d: PUBLIC PROC [f: IO.STREAM, point3d: Point3d] = {
 f.PutF["[%g,%g,%g]",[real[point3d[1]]],[real[point3d[2]]],[real[point3d[3]]]];
 };

FileoutPoint3dAsPoint2d: PUBLIC PROC [f: IO.STREAM, point3d: Point3d] = {
 f.PutF["[%g,%g]",[real[point3d[1]]],[real[point3d[2]]]];
 };


FileoutColor: PUBLIC PROC [f: IO.STREAM, color: Color] = {
 r, g, b: REAL;
 [r, g, b] ← GraphicsColor.ColorToRGB[color];
 f.PutF["[%g,%g,%g]",[real[r]], [real[g]], [real[b]]];
 };

FileoutSurface: PUBLIC PROC [f: IO.STREAM, surface: REF ANY] = {
 IF surface = NIL THEN f.PutF["NIL"]
 ELSE {
  WITH surface SELECT FROM
   tube: Tube => f.PutF["tube [radius: %g, height: %g]", [real[tube.R]], [real[tube.H]]];
   box: Box =>{ f.PutF["box "];
    FileoutPoint3d[f, [box.x, 2*box.halfY, box.z]];
    };
  ENDCASE => ERROR;
  };
 };

FileoutMaterial: PUBLIC PROC [f: IO.STREAM, material: Material] = {
 matRope: Rope.ROPE;
 matRope ← SVArtwork.MaterialToRope[material];
 f.PutRope[matRope];
 };

FileoutSMap: PUBLIC PROC [f: IO.STREAM, sMap: SMap] = {
 mapRope: Rope.ROPE;
 mapRope ← SVArtwork.SMapToRope[sMap];
 f.PutRope[mapRope];
 };

FileoutOMap: PUBLIC PROC [f: IO.STREAM, oMap: OMap] = {
 mapRope: Rope.ROPE;
 mapRope ← SVArtwork.OMapToRope[oMap];
 f.PutRope[mapRope];
 };


END.