public void Export(TileModel model, TilePropagator tilePropagator, string filename, DeBroglieConfig config, ExportOptions exportOptions) { var array = tilePropagator.ToArray(new Tile("?"), new Tile("!")); using (var s = File.OpenWrite(filename)) using (var tw = new StreamWriter(s)) { for (var z = 0; z < array.Topology.Depth; z++) { if (z != 0) { tw.WriteLine(); } for (var y = 0; y < array.Topology.Height; y++) { for (var x = 0; x < array.Topology.Width; x++) { if (x != 0) { tw.Write(","); } tw.Write(array.Get(x, y, z).Value?.ToString()); } tw.WriteLine(); } } } }
public void Export(TileModel model, TilePropagator tilePropagator, string filename, DeBroglieConfig config, ExportOptions exportOptions) { Vox vox; ITopoArray <byte> array; if (exportOptions is VoxExportOptions veo) { vox = veo.Template; array = tilePropagator.ToValueArray <byte>(); } else if (exportOptions is VoxSetExportOptions vseo) { vox = vseo.Template; var tileArray = tilePropagator.ToArray(); var subTiles = vseo.SubTiles.ToDictionary(x => x.Key, x => VoxUtils.ToTopoArray(x.Value)); array = MoreTopoArrayUtils.ExplodeTiles(tileArray, subTiles, vseo.TileWidth, vseo.TileHeight, vseo.TileDepth); } else { throw new System.Exception($"Cannot export from {exportOptions.TypeDescription} to .vox"); } VoxUtils.Save(vox, array); using (var stream = new FileStream(filename, FileMode.Create)) { var br = new BinaryWriter(stream); VoxSerializer.Write(br, vox); } }
public void TestLargeSeparationConstraint() { var model = new AdjacentModel(DirectionSet.Cartesian2d); var tile1 = new Tile(1); var tile2 = new Tile(2); var tiles = new[] { tile1, tile2 }; model.AddAdjacency(tiles, tiles, Direction.XPlus); model.AddAdjacency(tiles, tiles, Direction.YPlus); model.SetUniformFrequency(); var separationConstraint = new SeparationConstraint { Tiles = new[] { tile1 }.ToHashSet(), MinDistance = 10, }; var topology = new GridTopology(100, 100, false); var options = new TilePropagatorOptions { Constraints = new ITileConstraint[] { separationConstraint }, BacktrackType = BacktrackType.Backtrack, }; var propagator = new TilePropagator(model, topology, options); propagator.Run(); Assert.AreEqual(Resolution.Decided, propagator.Status); var r = propagator.ToArray(); for (var x = 0; x < 100; x++) { for (var y = 0; y < 100; y++) { if (r.Get(x, y) != tile1) { continue; } for (var dx = -1; dx <= 1; dx += 2) { for (var dy = -1; dy <= 1; dy += 2) { var x2 = x + dx; var y2 = y + dy; if (x2 >= 0 && x2 < 100 && y2 >= 0 && y2 < 100) { Assert.AreNotEqual(r.Get(x2, y2), tile1); } } } } } }
public void Export(TileModel model, TilePropagator propagator, string filename, DeBroglieConfig config, ExportOptions exportOptions) { if (config.Animate) { if (exportOptions is BitmapExportOptions) { var topoArray = propagator.ToWeightedArraySets().Map(WeightedColorAverage); var bitmap = BitmapUtils.ToBitmap(topoArray.ToArray2d()); bitmap.Save(filename); } else if (exportOptions is BitmapSetExportOptions bseo) { var topoArray = propagator.ToWeightedArraySets(); var tileTopology = topoArray.Topology.AsGridTopology().WithSize(bseo.TileWidth, bseo.TileHeight, 1); var subTiles = bseo.Bitmaps.ToDictionary(x => x.Key, x => TopoArray.Create(BitmapUtils.ToColorArray(x.Value), tileTopology).Map(c => new Tile(c))); var exploded = MoreTopoArrayUtils.ExplodeWeightedTiles(topoArray, subTiles, bseo.TileWidth, bseo.TileHeight, 1).Map(WeightedColorAverage); var bitmap = BitmapUtils.ToBitmap(exploded.ToArray2d()); bitmap.Save(filename); } else { throw new System.Exception($"Cannot export from {exportOptions.TypeDescription} to bitmap."); } } else { if (exportOptions is BitmapExportOptions) { var topoArray = propagator.ToValueArray(Rgba32.Gray, Rgba32.Magenta); var bitmap = BitmapUtils.ToBitmap(topoArray.ToArray2d()); bitmap.Save(filename); } else if (exportOptions is BitmapSetExportOptions bseo) { var undecided = new Tile(new object()); var contradiction = new Tile(new object()); var topoArray = propagator.ToArray(undecided, contradiction); var tileTopology = topoArray.Topology.AsGridTopology().WithSize(bseo.TileWidth, bseo.TileHeight, 1); var subTiles = bseo.Bitmaps.ToDictionary(x => x.Key, x => TopoArray.Create(BitmapUtils.ToColorArray(x.Value), tileTopology)); subTiles[undecided] = TopoArray.FromConstant(Rgba32.Gray, tileTopology); subTiles[contradiction] = TopoArray.FromConstant(Rgba32.Magenta, tileTopology); var exploded = MoreTopoArrayUtils.ExplodeTiles(topoArray, subTiles, bseo.TileWidth, bseo.TileHeight, 1); var bitmap = BitmapUtils.ToBitmap(exploded.ToArray2d()); bitmap.Save(filename); } else { throw new System.Exception($"Cannot export from {exportOptions.TypeDescription} to bitmap."); } } }
public void Export(TileModel model, TilePropagator tilePropagator, string filename, DeBroglieConfig config, ExportOptions exportOptions) { var tiledExportOptions = exportOptions as TiledExportOptions; if (tiledExportOptions == null) { throw new System.Exception($"Cannot export from {exportOptions.TypeDescription} to .tmx"); } var map = tiledExportOptions.Template; var srcFilename = tiledExportOptions.SrcFileName; var layerArray = tilePropagator.ToArray(); map.Layers = new BaseLayer[layerArray.Topology.Depth]; for (var z = 0; z < layerArray.Topology.Depth; z++) { map.Layers[z] = TiledUtil.MakeTileLayer(map, layerArray, z); } map.Width = map.Layers[0].Width; map.Height = map.Layers[0].Height; TiledUtil.Save(filename, map); // Check for any external files that may also need copying foreach (var tileset in map.Tilesets) { if (tileset is ExternalTileset e) { var srcPath = Path.Combine(Path.GetDirectoryName(srcFilename), e.source); var destPath = Path.Combine(Path.GetDirectoryName(filename), e.source); if (File.Exists(srcPath) && !File.Exists(destPath)) { File.Copy(srcPath, destPath); } } if (tileset.ImagePath != null) { var srcImagePath = Path.Combine(Path.GetDirectoryName(srcFilename), tileset.ImagePath); var destImagePath = Path.Combine(Path.GetDirectoryName(filename), tileset.ImagePath); if (File.Exists(srcImagePath) && !File.Exists(destImagePath)) { File.Copy(srcImagePath, destImagePath); } } } }
public void TestSeparationConstraint() { var model = new AdjacentModel(DirectionSet.Cartesian2d); var tile1 = new Tile(1); var tile2 = new Tile(2); var tiles = new[] { tile1, tile2 }; model.AddAdjacency(tiles, tiles, Direction.XPlus); model.AddAdjacency(tiles, tiles, Direction.YPlus); model.SetUniformFrequency(); var separationConstraint = new SeparationConstraint { Tiles = new[] { tile1 }.ToHashSet(), MinDistance = 3, }; var countConstraint = new CountConstraint { Tiles = new[] { tile1 }.ToHashSet(), Count = 2, Comparison = CountComparison.Exactly, }; var topology = new GridTopology(4, 1, false); var options = new TilePropagatorOptions { Constraints = new ITileConstraint[] { separationConstraint, countConstraint }, BacktrackType = BacktrackType.Backtrack, }; var propagator = new TilePropagator(model, topology, options); propagator.Run(); Assert.AreEqual(Resolution.Decided, propagator.Status); var r = propagator.ToArray(); // Only possible solution given the constraints Assert.AreEqual(tile1, r.Get(0)); Assert.AreEqual(tile2, r.Get(1)); Assert.AreEqual(tile2, r.Get(2)); Assert.AreEqual(tile1, r.Get(3)); }
public void TestMirrorConstraint() { var trb = new TileRotationBuilder(4, true, TileRotationTreatment.Missing); var tile1 = new Tile(1); var tile2 = new Tile(2); var tile3 = new Tile(3); var tile4 = new Tile(4); var tile5 = new Tile(5); var tiles = new[] { tile1, tile2, tile3, tile4 }; var reflectX = new Rotation(0, true); trb.Add(tile1, reflectX, tile2); trb.Add(tile3, reflectX, tile3); trb.Add(tile5, reflectX, tile5); var model = new AdjacentModel(DirectionSet.Cartesian2d); model.AddAdjacency(tiles, tiles, Direction.XPlus); model.AddAdjacency(new[] { tile5 }, tiles, Direction.XPlus); model.AddAdjacency(new[] { tile5 }, tiles, Direction.XMinus); model.SetUniformFrequency(); model.SetFrequency(tile5, 0.0); var tr = trb.Build(); var constraints = new[] { new MirrorXConstraint { TileRotation = tr } }; // tile1 reflects to tile 2 { var t2 = new GridTopology(2, 1, false); var p2 = new TilePropagator(model, t2, constraints: constraints); p2.Select(0, 0, 0, tile1); var status = p2.Run(); Assert.AreEqual(Resolution.Decided, status); Assert.AreEqual(tile2, p2.ToArray().Get(1, 0)); } // tile3 reflects to tile3 { var t2 = new GridTopology(2, 1, false); var p2 = new TilePropagator(model, t2, constraints: constraints); p2.Select(0, 0, 0, tile3); var status = p2.Run(); Assert.AreEqual(Resolution.Decided, status); Assert.AreEqual(tile3, p2.ToArray().Get(1, 0)); } // tile3 only tile that can go in a central space // (tile5 can go, but has zero frequency) // So tile3 should be selected reliably { var t2 = new GridTopology(3, 1, false); var p2 = new TilePropagator(model, t2, constraints: constraints); var status = p2.Run(); Assert.AreEqual(Resolution.Decided, status); Assert.AreEqual(tile3, p2.ToArray().Get(1, 0)); } // tile5 can be reflected, but cannot // be placed adjacent to it's own reflection { var t2 = new GridTopology(2, 1, false); var p2 = new TilePropagator(model, t2, constraints: constraints); p2.Select(0, 0, 0, tile5); var status = p2.Run(); Assert.AreEqual(Resolution.Contradiction, status); } { var t2 = new GridTopology(4, 1, false); var p2 = new TilePropagator(model, t2, constraints: constraints); p2.Select(0, 0, 0, tile5); var status = p2.Run(); Assert.AreEqual(Resolution.Decided, status); } }
public void Export(TileModel model, TilePropagator tilePropagator, string filename, DeBroglieConfig config, ExportOptions exportOptions) { var topoArray = tilePropagator.ToArray(new Tile("?"), new Tile("!")); var topology = topoArray.Topology; using (var s = File.Open(filename, FileMode.Create)) using (var tw = new StreamWriter(s)) { tw.WriteLine("%YAML 1.1"); tw.WriteLine("%TAG !u! tag:unity3d.com,2011:"); int id = 1; foreach (var index in topology.GetIndices()) { var objectId = id++; var transformId = id++; topology.GetCoord(index, out var x, out var y, out var z); var str = @" --- !u!1 &objectId GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - component: {fileID: transformId} m_Layer: 0 m_Name: objectName m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 --- !u!4 &transformId Transform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: objectId} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: transformX, y: transformY, z: transformZ} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} "; str = str .Trim() .Replace("objectId", objectId.ToString()) .Replace("transformId", transformId.ToString()) .Replace("transformX", x.ToString()) .Replace("transformY", y.ToString()) .Replace("transformZ", z.ToString()) .Replace("objectName", topoArray.Get(index).Value?.ToString()) ; tw.WriteLine(str); } } }
public void Export(TileModel model, TilePropagator propagator, string filename, DeBroglieConfig config, ExportOptions exportOptions) { if (config.Animate) { if (exportOptions is BitmapExportOptions) { var topoArray = propagator.ToValueSets <Rgba32>().Map(BitmapUtils.ColorAverage); var bitmap = BitmapUtils.ToBitmap(topoArray.ToArray2d()); bitmap.Save(filename); } else if (exportOptions is BitmapSetExportOptions bseo) { var topoArray = propagator.ToArraySets(); var tileTopology = topoArray.Topology.AsGridTopology().WithSize(bseo.TileWidth, bseo.TileHeight, 1); var subTiles = bseo.Bitmaps.ToDictionary(x => x.Key, x => TopoArray.Create(BitmapUtils.ToColorArray(x.Value), tileTopology)); var exploded = MoreTopoArrayUtils.ExplodeTileSets(topoArray, subTiles, bseo.TileWidth, bseo.TileHeight, 1).Map(BitmapUtils.ColorAverage); var bitmap = BitmapUtils.ToBitmap(exploded.ToArray2d()); bitmap.Save(filename); } else { throw new System.Exception($"Cannot export from {exportOptions.TypeDescription} to bitmap."); } } else { if (exportOptions is BitmapExportOptions) { var topoArray = propagator.ToValueArray(Rgba32.Gray, Rgba32.Magenta); var bitmap = BitmapUtils.ToBitmap(topoArray.ToArray2d()); var index = 0; var noExtension = Path.GetFileNameWithoutExtension(filename); var justExtension = Path.GetExtension(filename); var pathNoFile = Path.GetDirectoryName(filename); var seqFilename = ""; do { seqFilename = pathNoFile + Path.DirectorySeparatorChar + noExtension + (index == 0 ? "" : index.ToString()) + justExtension; index++; } while (File.Exists(seqFilename)); bitmap.Save(seqFilename); } else if (exportOptions is BitmapSetExportOptions bseo) { var undecided = new Tile(new object()); var contradiction = new Tile(new object()); var topoArray = propagator.ToArray(undecided, contradiction); var tileTopology = topoArray.Topology.AsGridTopology().WithSize(bseo.TileWidth, bseo.TileHeight, 1); var subTiles = bseo.Bitmaps.ToDictionary(x => x.Key, x => TopoArray.Create(BitmapUtils.ToColorArray(x.Value), tileTopology)); subTiles[undecided] = TopoArray.FromConstant(Rgba32.Gray, tileTopology); subTiles[contradiction] = TopoArray.FromConstant(Rgba32.Magenta, tileTopology); var exploded = MoreTopoArrayUtils.ExplodeTiles(topoArray, subTiles, bseo.TileWidth, bseo.TileHeight, 1); var bitmap = BitmapUtils.ToBitmap(exploded.ToArray2d()); bitmap.Save(filename); } else { throw new System.Exception($"Cannot export from {exportOptions.TypeDescription} to bitmap."); } } }