MODULE RandomShapes EXPORTS Main; IMPORT R3, Random, Thread, Wr, Stdio, Fmt, Scan, ParseParams, RTMisc; FROM Stdio IMPORT stderr; FROM Heuristicas IMPORT SpreadOneVertex, FlattenOneVertex; FROM Triang IMPORT Topology, Coords, ReadTopTri, NormalizeCoords, PrintTopTri, GetCoords, SetCoords; TYPE Options = RECORD inFile: TEXT; (* Input file name (minus ".top" extension) *) outFile: TEXT; (* Output file name prefix *) trials: CARDINAL; (* Number of configurations to generate *) jitter: REAL; (* Magnitude of random perturbation *) flatten: BOOLEAN; (* TRUE to apply "flatten" smoothing heuristic *) spread: BOOLEAN; (* TRUE to apply the "spread" smoothing heuristic *) iterations: CARDINAL (* Number of smooting iterations to apply *) END; PROCEDURE PerturbCoords(VAR coords: Coords; coins: Random.T; jitter: REAL) = BEGIN FOR i := 0 TO LAST(coords) DO WITH v = coords[i] DO coords[i] := R3.add( coords[i], R3.T{ jitter * (2.0 * Random.Real(coins) - 1.0), jitter * (2.0 * Random.Real(coins) - 1.0), jitter * (2.0 * Random.Real(coins) - 1.0) } ) END END; END PerturbCoords; PROCEDURE FlattenVertices( READONLY t: Topology; VAR coords: Coords; ) = BEGIN FOR j := 0 TO t.NV-1 DO FlattenOneVertex(t.out[j], coords) END; END FlattenVertices; PROCEDURE SpreadVertices( READONLY t: Topology; VAR coords: Coords; ) = BEGIN FOR j := 0 TO t.NV-1 DO SpreadOneVertex(t.out[j], coords) END END SpreadVertices; PROCEDURE Main() = BEGIN WITH o = GetOptions(), coins = Random.New(), t = ReadTopTri(o.inFile), cOld = NEW(REF ARRAY OF ARRAY OF REAL, t.NV, 3)^, cNew = NEW(REF ARRAY OF ARRAY OF REAL, t.NV, 3)^ DO GetCoords(t, cOld); FOR k := 1 TO o.trials DO cNew := cOld; PerturbCoords(cNew, coins, o.jitter); FOR i := 0 TO o.iterations-1 DO IF o.flatten THEN FlattenVertices(t, cNew) END; IF o.spread THEN SpreadVertices(t, cNew) END; NormalizeCoords(t, cNew) END; SetCoords(t, cNew); PrintTopTri(t, o.outFile & "-" & Fmt.Pad(Fmt.Int(k), 4, '0')) END; END END Main; PROCEDURE GetOptions (): Options = <* FATAL Thread.Alerted, Wr.Failure *> VAR o: Options; BEGIN TRY ParseParams.BeginParsing(stderr); ParseParams.GetKeyword("-inFile"); o.inFile := ParseParams.GetNext(); ParseParams.GetKeyword("-outFile"); o.outFile := ParseParams.GetNext(); ParseParams.GetKeyword("-trials"); o.trials := ParseParams.GetNextInt(1,200); IF ParseParams.KeywordPresent("-jitter") THEN o.jitter := ParseParams.GetNextReal(0.0, 10.0); ELSE o.jitter := 1.0 END; o.flatten := ParseParams.KeywordPresent("-flatten"); o.spread := ParseParams.KeywordPresent("-spread"); IF NOT (o.flatten OR o.spread) THEN Wr.PutText(stderr, "Smoothing mode not specified\n"); RAISE Scan.BadFormat END; IF ParseParams.KeywordPresent("-iterations") THEN o.iterations := ParseParams.GetNextInt(0, 1000000); ELSE o.iterations := 50 END; ParseParams.EndParsing(); EXCEPT | Scan.BadFormat => Wr.PutText(stderr, "Usage: RandomShapes\\\n"); Wr.PutText(stderr, " -inFile -outFile \\\n"); Wr.PutText(stderr, " -trials [ -jitter ]\\\n"); Wr.PutText(stderr, " { -flatten | -spread }\\\n"); Wr.PutText(stderr, " [ -iterations ]\n"); RTMisc.Exit (1); END; RETURN o END GetOptions; BEGIN Main() END RandomShapes.