MODULE MakeCube EXPORTS Main; IMPORT Oct, Map, R3, Triang, Fmt, ParseParams, RTMisc, Wr, Scan, Stdio, Thread; FROM Triang IMPORT PrintTopTri, MakeTopology, Coords; FROM Map IMPORT Arc; FROM Oct IMPORT Onext, Oprev, Sym, Flip; FROM Stdio IMPORT stderr; PROCEDURE WalkTriang(a: Arc; READONLY x, y: CARDINAL): Arc = VAR c: Arc; BEGIN c := a; FOR i := 0 TO x-1 DO c := Oprev(Oprev(Oprev(Oprev(Sym(c))))) END; FOR j := 0 TO y-1 DO c := Onext(Onext(Sym(Onext(Onext(c))))) END; RETURN c; END WalkTriang; PROCEDURE MakeCubeT(READONLY GridOrder: CARDINAL): Arc = VAR ca1, ca2, ca3, ca4, ca5: ARRAY [0..7] OF Arc; coord: R3.T; c, ct: Arc; BEGIN (* Make the side 1 of the cube *) ca1 := Triang.MakeGrid(GridOrder); c := Flip(ca1[1]); FOR j := 0 TO GridOrder-1 DO FOR i := 0 TO GridOrder-1 DO ct := WalkTriang(c, i, j); coord := R3.T{0.0, FLOAT(2*i), FLOAT(2*j)}; Triang.SetVertexCoords(Triang.Org(ct), coord); WITH e = Sym(Onext(ct)) DO coord := R3.T{0.0, FLOAT(2*i + 1), FLOAT(2*j + 1)}; Triang.SetVertexCoords(Triang.Org(e), coord); END; END; END; (* Make the side 2 of the cube *) ca2 := Triang.MakeGrid(GridOrder); c := Flip(ca2[1]); FOR j := 0 TO GridOrder-1 DO FOR i := 0 TO GridOrder-1 DO ct := WalkTriang(c, i, j); coord := R3.T{FLOAT(2*(GridOrder-i)), 0.0, FLOAT(2*j)}; Triang.SetVertexCoords(Triang.Org(ct), coord); WITH e = Sym(Onext(ct)) DO coord := R3.T{FLOAT(2*(GridOrder-i-1) + 1), 0.0, FLOAT(2*j + 1)}; Triang.SetVertexCoords(Triang.Org(e), coord); END; END; END; (* Make the side 3 of the cube *) ca3 := Triang.MakeGrid(GridOrder); c := Flip(ca3[1]); FOR j := 0 TO GridOrder-1 DO FOR i := 0 TO GridOrder-1 DO ct := WalkTriang(c, i, j); coord := R3.T{FLOAT(2*GridOrder), FLOAT(2*(GridOrder-i)), FLOAT(2*j)}; Triang.SetVertexCoords(Triang.Org(ct), coord); WITH e = Sym(Onext(ct)) DO coord := R3.T{FLOAT(2*GridOrder), FLOAT(2*(GridOrder-i-1) + 1), FLOAT(2*j + 1)}; Triang.SetVertexCoords(Triang.Org(e), coord); END; END; END; (* Make the side 4 of the cube *) ca4 := Triang.MakeGrid(GridOrder); c := Flip(ca4[1]); FOR j := 0 TO GridOrder-1 DO FOR i := 0 TO GridOrder-1 DO ct := WalkTriang(c, i, j); coord := R3.T{FLOAT(2*i), FLOAT(2*GridOrder), FLOAT(2*j)}; Triang.SetVertexCoords(Triang.Org(ct), coord); WITH e = Sym(Onext(ct)) DO coord := R3.T{FLOAT(2*i + 1), FLOAT(2*GridOrder), FLOAT(2*j + 1)}; Triang.SetVertexCoords(Triang.Org(e), coord); END; END; END; (* Make the side 5 of the cube *) ca5 := Triang.MakeGrid(GridOrder); c := Flip(ca5[1]); FOR j := 0 TO GridOrder-1 DO FOR i := 0 TO GridOrder-1 DO ct := WalkTriang(c, i, j); coord := R3.T{FLOAT(2*i), FLOAT(2*j), 0.0}; Triang.SetVertexCoords(Triang.Org(ct), coord); WITH e = Sym(Onext(ct)) DO coord := R3.T{FLOAT(2*i + 1), FLOAT(2*j + 1),0.0 }; Triang.SetVertexCoords(Triang.Org(e), coord); END; END; END; FOR i := 0 TO GridOrder-1 DO ct := WalkTriang(c, i, GridOrder); coord := R3.T{FLOAT(2*i), FLOAT(2*GridOrder), 0.0}; Triang.SetVertexCoords(Triang.Org(ct), coord); END; FOR j := 0 TO GridOrder DO ct := WalkTriang(c, GridOrder-1, j); coord := R3.T{FLOAT(2*GridOrder), FLOAT(2*j), 0.0}; Triang.SetVertexCoords(Triang.Org(Sym(ct)), coord); END; EVAL Triang.Glue(ca1[0], Flip(ca2[3]), GridOrder); EVAL Triang.Glue(ca2[0], Flip(ca3[3]), GridOrder); EVAL Triang.Glue(ca3[0], Flip(ca4[3]), GridOrder); EVAL Triang.Glue(ca4[0], Flip(ca1[3]), GridOrder); EVAL Triang.Glue(ca5[0], Flip(ca1[1]), GridOrder); EVAL Triang.Glue(ca5[2], Flip(ca2[1]), GridOrder); EVAL Triang.Glue(ca5[4], Flip(ca3[1]), GridOrder); EVAL Triang.Glue(ca5[6], Flip(ca4[1]), GridOrder); (* Make the side 6 of the cube as a plane *) ca5 := Triang.MakeGrid(GridOrder); c := Flip(ca5[1]); FOR j := 0 TO GridOrder-1 DO FOR i := 0 TO GridOrder-1 DO ct := WalkTriang(c, i, j); coord := R3.T{FLOAT(2*(GridOrder-j)), FLOAT(2*(GridOrder-i)), FLOAT(2*GridOrder)}; Triang.SetVertexCoords(Triang.Org(ct), coord); WITH e = Sym(Onext(ct)) DO coord := R3.T{FLOAT(2*(GridOrder-j-1) + 1), FLOAT(2*(GridOrder-i-1) + 1), FLOAT(2*GridOrder)}; Triang.SetVertexCoords(Triang.Org(e), coord) END; END; END; FOR j := 0 TO GridOrder-1 DO ct := WalkTriang(c, j, GridOrder); coord := R3.T{0.0, FLOAT(2*(GridOrder-j)), FLOAT(2*GridOrder)}; Triang.SetVertexCoords(Triang.Org(ct), coord); END; FOR i := 0 TO GridOrder DO ct := WalkTriang(c, GridOrder-1, i); coord := R3.T{FLOAT(2*(GridOrder-i)), 0.0, FLOAT(2*GridOrder)}; Triang.SetVertexCoords(Triang.Org(Sym(ct)), coord); END; EVAL Triang.Glue(ca5[0], Flip(ca4[5]), GridOrder); EVAL Triang.Glue(ca5[2], Flip(ca3[5]), GridOrder); EVAL Triang.Glue(ca5[4], Flip(ca2[5]), GridOrder); EVAL Triang.Glue(ca5[6], Flip(ca1[5]), GridOrder); RETURN ca5[0] END MakeCubeT; PROCEDURE Main() = <* FATAL Wr.Failure, Thread.Alerted *> BEGIN WITH GridOrder = GetOptions(), top = MakeCubeT(GridOrder), t = MakeTopology(top), coords = NEW(REF Coords, t.NV) DO PrintTopTri(t, "cube-" & Fmt.Int(GridOrder)); Wr.PutText(stderr, "Exit MakeCube: \n"); END; END Main; PROCEDURE GetOptions (): CARDINAL = <* FATAL Thread.Alerted, Wr.Failure *> VAR gridOrder: CARDINAL; BEGIN TRY ParseParams.BeginParsing(stderr); ParseParams.GetKeyword("-gridOrder"); gridOrder := ParseParams.GetNextInt(1, 20); ParseParams.EndParsing(); EXCEPT | Scan.BadFormat => Wr.PutText(stderr, "Usage: MakeCube -gridOrder \n"); RTMisc.Exit (1); END; RETURN gridOrder END GetOptions; BEGIN Main(); END MakeCube.