Esempio n. 1
0
        private Vector3Int?GetContradictionLocation(ITopoArray <ModelTile?> result)
        {
            var topology = result.Topology;
            var mask     = topology.Mask;

            var empty = mask.ToArray();

            for (var x = 0; x < topology.Width; x++)
            {
                for (var y = 0; y < topology.Height; y++)
                {
                    for (var z = 0; z < topology.Depth; z++)
                    {
                        var p = new Vector3Int(x, y, z);
                        // Skip if already filled
                        if (!empty[GetMaskIndex(p)])
                        {
                            continue;
                        }
                        var modelTile = result.Get(x, y, z);
                        if (modelTile == null)
                        {
                            continue;
                        }
                        var tile = modelTile.Value.Tile;
                        if (tile == null)
                        {
                            return(new Vector3Int(x, y, z));
                        }
                    }
                }
            }

            return(null);
        }
 public WeightSetCollection(ITopoArray <int> weightSetByIndex, IDictionary <int, IDictionary <Tile, PriorityAndWeight> > weightSets, TileModelMapping tileModelMapping)
 {
     this.weightSetByIndex = weightSetByIndex;
     this.weightSets       = weightSets;
     this.tileModelMapping = tileModelMapping;
     frequencySets         = new Dictionary <int, FrequencySet>();
 }
Esempio n. 3
0
        /// <summary>
        /// Calls <c>func</c> on each element of the array, returning a new <see cref="ITopoArray{T}"/>
        /// </summary>
        public static ITopoArray <U> Map <T, U>(this ITopoArray <T> topoArray, Func <T, U> func)
        {
            /*
             * var width = topoArray.Topology.Width;
             * var height = topoArray.Topology.Height;
             * var depth = topoArray.Topology.Depth;
             * var r = new U[width, height, depth];
             *
             * for (var z = 0; z < depth; z++)
             * {
             *  for (var y = 0; y < height; y++)
             *  {
             *      for (var x = 0; x < width; x++)
             *      {
             *          r[x, y, z] = func(topoArray.Get(x, y, z));
             *      }
             *  }
             * }
             *
             * return new TopoArray3D<U>(r, topoArray.Topology);
             */
            var r = new U[topoArray.Topology.IndexCount];

            foreach (var i in topoArray.Topology.GetIndices())
            {
                r[i] = func(topoArray.Get(i));
            }
            return(new TopoArray1D <U>(r, topoArray.Topology));
        }
Esempio n. 4
0
        public static ITopoArray <T> Scale <T>(ITopoArray <T> topoArray, int scale)
        {
            var topology = topoArray.Topology.AsGridTopology();

            if (topology.Mask != null)
            {
                throw new NotSupportedException();
            }
            var result = new T[topology.Width * scale, topology.Height *scale, topology.Depth *scale];

            for (var z = 0; z < topology.Depth; z++)
            {
                for (var y = 0; y < topology.Height; y++)
                {
                    for (var x = 0; x < topology.Width; x++)
                    {
                        var value = topoArray.Get(x, y, z);
                        for (var dz = 0; dz < scale; dz++)
                        {
                            for (var dy = 0; dy < scale; dy++)
                            {
                                for (var dx = 0; dx < scale; dx++)
                                {
                                    result[x * scale + dx, y *scale + dy, z *scale + dz] = value;
                                }
                            }
                        }
                    }
                }
            }
            var resultTopology = topology.WithSize(topology.Width * scale, topology.Height * scale, topology.Depth * scale);

            return(TopoArray.Create(result, resultTopology));
        }
Esempio n. 5
0
        public void QuickStartTest()
        {
            ITopoArray <char> sample = TopoArray.Create(new[, ]
            {
                { '_', '_', '_' },
                { '_', '*', '_' },
                { '_', '_', '_' },
            }, periodic: false);
            // Specify the model used for generation
            var model = new AdjacentModel(sample.ToTiles());
            // Set the output dimensions
            var topology = new Topology(10, 10, periodic: false);
            // Actually run the algorithm
            var propagator = new TilePropagator(model, topology);
            var status     = propagator.Run();

            if (status != Resolution.Decided)
            {
                throw new Exception("Undecided");
            }
            var output = propagator.ToValueArray <char>();

            // Display the results
            for (var y = 0; y < 10; y++)
            {
                for (var x = 0; x < 10; x++)
                {
                    System.Console.Write(output.Get(x, y));
                }
                System.Console.WriteLine();
            }
        }
Esempio n. 6
0
        private static void Save(Size size, Xyzi xyzi, ITopoArray <byte> topArray)
        {
            // TODO
            size.SizeX  = topArray.Topology.Width;
            size.SizeY  = topArray.Topology.Height;
            size.SizeZ  = topArray.Topology.Depth;
            xyzi.Voxels = new List <Voxel>();

            for (var z = 0; z < size.SizeZ; z++)
            {
                for (var y = 0; y < size.SizeY; y++)
                {
                    for (var x = 0; x < size.SizeX; x++)
                    {
                        var colorIndex = topArray.Get(x, y, z);
                        if (colorIndex != 0)
                        {
                            xyzi.Voxels.Add(new Voxel
                            {
                                X          = (byte)x,
                                Y          = (byte)y,
                                Z          = (byte)z,
                                ColorIndex = colorIndex,
                            });
                        }
                    }
                }
            }
        }
Esempio n. 7
0
        private static FrequencySet[] GetFrequencySets(ITopoArray <IDictionary <Tile, PriorityAndWeight> > weights, TileModelMapping tileModelMapping)
        {
            var frequencies = new FrequencySet[tileModelMapping.PatternTopology.IndexCount];

            foreach (var patternIndex in tileModelMapping.PatternTopology.GetIndices())
            {
                // TODO
                if (tileModelMapping.PatternCoordToTileCoordIndexAndOffset != null)
                {
                    throw new NotImplementedException();
                }

                // TODO: Detect duplicate dictionaries by reference and share the frequency sets?

                var tileIndex     = patternIndex;
                var offset        = 0;
                var weightDict    = weights.Get(tileIndex);
                var newWeights    = new double[tileModelMapping.PatternModel.PatternCount];
                var newPriorities = new int[tileModelMapping.PatternModel.PatternCount];
                foreach (var kv in weightDict)
                {
                    var pattern = tileModelMapping.TilesToPatternsByOffset[offset][kv.Key].Single();
                    newWeights[pattern]    = kv.Value.Weight;
                    newPriorities[pattern] = kv.Value.Priority;
                }
                frequencies[patternIndex] = new FrequencySet(newWeights, newPriorities);
            }
            return(frequencies);
        }
Esempio n. 8
0
 public void AddSample(ITopoArray <Tile> sample, int rotationalSymmetry, bool reflectionalSymmetry, TileRotation tileRotation = null)
 {
     foreach (var s in OverlappingAnalysis.GetRotatedSamples(sample, rotationalSymmetry, reflectionalSymmetry, tileRotation))
     {
         AddSample(s);
     }
 }
Esempio n. 9
0
 public static IEnumerable <ITopoArray <Tile> > GetRotatedSamples(
     ITopoArray <Tile> sample,
     int rotationalSymmetry,
     bool reflectionalSymmetry,
     TileRotation tileRotation = null)
 {
     if (sample.Topology.Directions.Type == DirectionsType.Hexagonal2d)
     {
         var reflections = reflectionalSymmetry ? 2 : 1;
         for (var r = 0; r < reflections; r++)
         {
             for (var i = 0; i < 6; i += (6 / rotationalSymmetry))
             {
                 yield return(TopoArrayUtils.HexRotate(sample, i, r > 0, tileRotation));
             }
         }
     }
     else
     {
         var reflections = reflectionalSymmetry ? 2 : 1;
         for (var r = 0; r < reflections; r++)
         {
             for (var i = 0; i < 4; i += (4 / rotationalSymmetry))
             {
                 yield return(TopoArrayUtils.Rotate(sample, i, r > 0, tileRotation));
             }
         }
     }
 }
Esempio n. 10
0
        public SampleSet Load(string filename)
        {
            var srcFilename = filename;
            // Hack for tsx files. Should handle this more properly in future
            var tileset = TiledUtil.LoadTileset(filename);

            tileset.FirstGid = 1;
            var map = new Map
            {
                CellWidth    = tileset.TileWidth,
                CellHeight   = tileset.TileHeight,
                Tilesets     = new[] { tileset },
                TiledVersion = "1.1.6",
                RenderOrder  = RenderOrder.rightdown,
            };
            var tilesByName = new Dictionary <string, Tile>();

            TiledMapImporter.AddTileset(tilesByName, tileset);
            // TODO: Other directions
            var directions = DirectionSet.Cartesian2d;

            map.Orientation = Orientation.orthogonal;
            var samples = new ITopoArray <Tile> [0];

            return(new SampleSet
            {
                Directions = directions,
                Samples = samples,
                TilesByName = tilesByName,
                ExportOptions = new TiledExportOptions {
                    Template = map,
                    SrcFileName = srcFilename,
                },
            });
        }
Esempio n. 11
0
 public void AddSample(ITopoArray <Tile> sample, TileRotation tileRotation = null)
 {
     foreach (var s in OverlappingAnalysis.GetRotatedSamples(sample, tileRotation))
     {
         AddSample(s);
     }
 }
Esempio n. 12
0
        private static bool TryExtract(ITopoArray <Tile> sample, int nx, int ny, int nz, int x, int y, int z, out PatternArray pattern)
        {
            var width  = sample.Topology.Width;
            var height = sample.Topology.Height;
            var depth  = sample.Topology.Depth;
            var values = new Tile[nx, ny, nz];

            for (int tx = 0; tx < nx; tx++)
            {
                var sx = (x + tx) % width;
                for (int ty = 0; ty < ny; ty++)
                {
                    var sy = (y + ty) % height;
                    for (int tz = 0; tz < nz; tz++)
                    {
                        var sz    = (z + tz) % depth;
                        var index = sample.Topology.GetIndex(sx, sy, sz);
                        if (!sample.Topology.ContainsIndex(index))
                        {
                            pattern = default(PatternArray);
                            return(false);
                        }
                        values[tx, ty, tz] = sample.Get(sx, sy, sz);
                    }
                }
            }
            pattern = new PatternArray {
                Values = values
            };
            return(true);
        }
Esempio n. 13
0
        public static ITopoArray <Tile> HexRotate(ITopoArray <Tile> original, Rotation rotation, TileRotation tileRotation = null)
        {
            bool TileRotate(Tile tile, out Tile result)
            {
                return(tileRotation.Rotate(tile, rotation, out result));
            }

            return(HexRotate <Tile>(original, rotation, tileRotation == null ? null : (TileRotate <Tile>)TileRotate));
        }
Esempio n. 14
0
        public static ITopoArray <Tile> HexRotate(ITopoArray <Tile> original, int rotate, bool reflectX = false, TileRotation tileRotation = null)
        {
            bool TileRotate(Tile tile, out Tile result)
            {
                return(tileRotation.Rotate(tile, rotate, reflectX, out result));
            }

            return(HexRotate <Tile>(original, rotate, reflectX, tileRotation == null ? null : (TileRotate <Tile>)TileRotate));
        }
        public static IEnumerable<ITopoArray<Tile>> GetRotatedSamples(
            ITopoArray<Tile> sample,
            TileRotation tileRotation = null)
        {
            tileRotation = tileRotation ?? new TileRotation();

            foreach (var rotation in tileRotation.RotationGroup)
            {
                yield return TopoArrayUtils.Rotate(sample, rotation, tileRotation);
            }
        }
Esempio n. 16
0
        private static ITopoArray <T> RotateInner <T>(ITopoArray <T> original, Func <int, int, ValueTuple <int, int> > mapCoord, TileRotate <T> tileRotate = null)
        {
            var originalTopology = original.Topology.AsGridTopology();

            // Find new bounds
            var(x1, y1) = mapCoord(0, 0);
            var(x2, y2) = mapCoord(originalTopology.Width - 1, 0);
            var(x3, y3) = mapCoord(originalTopology.Width - 1, originalTopology.Height - 1);
            var(x4, y4) = mapCoord(0, originalTopology.Height - 1);

            var minx = Math.Min(Math.Min(x1, x2), Math.Min(x3, x4));
            var maxx = Math.Max(Math.Max(x1, x2), Math.Max(x3, x4));
            var miny = Math.Min(Math.Min(y1, y2), Math.Min(y3, y4));
            var maxy = Math.Max(Math.Max(y1, y2), Math.Max(y3, y4));

            // Arrange so that co-ordinate transfer is into the rect bounced by width, height
            var offsetx = -minx;
            var offsety = -miny;
            var width   = maxx - minx + 1;
            var height  = maxy - miny + 1;
            var depth   = originalTopology.Depth;

            var mask     = new bool[width * height * depth];
            var topology = new GridTopology(originalTopology.Directions, width, height, originalTopology.Depth, false, false, false, mask);
            var values   = new T[width, height, depth];

            // Copy from original to values based on the rotation, setting up the mask as we go.
            for (var z = 0; z < originalTopology.Depth; z++)
            {
                for (var y = 0; y < originalTopology.Height; y++)
                {
                    for (var x = 0; x < originalTopology.Width; x++)
                    {
                        var(newX, newY) = mapCoord(x, y);
                        newX           += offsetx;
                        newY           += offsety;
                        int  newIndex    = topology.GetIndex(newX, newY, z);
                        var  newValue    = original.Get(x, y, z);
                        bool hasNewValue = true;
                        if (tileRotate != null)
                        {
                            hasNewValue = tileRotate(newValue, out newValue);
                        }
                        values[newX, newY, z] = newValue;
                        mask[newIndex]        = hasNewValue && originalTopology.ContainsIndex(originalTopology.GetIndex(x, y, z));
                    }
                }
            }

            return(new TopoArray3D <T>(values, topology));
        }
Esempio n. 17
0
        public static ITopoArray <T> Rotate <T>(ITopoArray <T> original, int rotateCw, bool reflectX = false, TileRotate <T> tileRotate = null)
        {
            if (rotateCw == 0 && !reflectX)
            {
                return(original);
            }

            ValueTuple <int, int> MapCoord(int x, int y)
            {
                return(RotateVector(x, y, rotateCw, reflectX));
            }

            return(RotateInner(original, MapCoord, tileRotate));
        }
Esempio n. 18
0
        public static ITopoArray <T> SquareRotate <T>(ITopoArray <T> original, Rotation rotation, TileRotate <T> tileRotate = null)
        {
            if (rotation.IsIdentity)
            {
                return(original);
            }

            ValueTuple <int, int> MapCoord(int x, int y)
            {
                return(SquareRotateVector(x, y, rotation));
            }

            return(RotateInner(original, MapCoord, tileRotate));
        }
Esempio n. 19
0
        /// <summary>
        /// Converts from DeBroglie's array format back to Tessera's.
        /// </summary>
        internal IEnumerable <TesseraTileInstance> GetTesseraTileInstances(ITopoArray <ModelTile?> result)
        {
            var topology = result.Topology;
            var mask     = topology.Mask;

            var empty = mask.ToArray();

            for (var x = 0; x < topology.Width; x++)
            {
                for (var y = 0; y < topology.Height; y++)
                {
                    for (var z = 0; z < topology.Depth; z++)
                    {
                        var p = new Vector3Int(x, y, z);
                        // Skip if already filled
                        if (!empty[GetMaskIndex(p)])
                        {
                            continue;
                        }
                        var modelTile = result.Get(x, y, z);
                        if (modelTile == null)
                        {
                            continue;
                        }
                        var rot  = modelTile.Value.Rotation;
                        var tile = modelTile.Value.Tile;
                        if (tile == null)
                        {
                            continue;
                        }

                        var ti = GetTesseraTileInstance(x, y, z, modelTile.Value);

                        // Fill locations
                        foreach (var p2 in ti.Cells)
                        {
                            if (InBounds(p2))
                            {
                                empty[GetMaskIndex(p2)] = false;
                            }
                        }

                        if (ti != null)
                        {
                            yield return(ti);
                        }
                    }
                }
            }
        }
Esempio n. 20
0
        public void AddSample(ITopoArray <Tile> sample, TileRotation tileRotation = null)
        {
            if (sample.Topology.Depth == 1)
            {
                nz = 1;
            }

            var topology = sample.Topology.AsGridTopology();

            var periodicX = topology.PeriodicX;
            var periodicY = topology.PeriodicY;
            var periodicZ = topology.PeriodicZ;

            foreach (var s in OverlappingAnalysis.GetRotatedSamples(sample, tileRotation))
            {
                OverlappingAnalysis.GetPatterns(s, nx, ny, nz, periodicX, periodicY, periodicZ, patternIndices, patternArrays, frequencies);
            }

            // Update the model based on the collected data
            var directions = topology.Directions;

            // TODO: Don't regenerate this from scratch every time
            propagator = new List <HashSet <int>[]>(patternArrays.Count);
            for (var p = 0; p < patternArrays.Count; p++)
            {
                propagator.Add(new HashSet <int> [directions.Count]);
                for (var d = 0; d < directions.Count; d++)
                {
                    var l = new HashSet <int>();
                    for (var p2 = 0; p2 < patternArrays.Count; p2++)
                    {
                        var dx = directions.DX[d];
                        var dy = directions.DY[d];
                        var dz = directions.DZ[d];
                        if (Aggrees(patternArrays[p], patternArrays[p2], dx, dy, dz))
                        {
                            l.Add(p2);
                        }
                    }
                    propagator[p][d] = l;
                }
            }

            patternsToTiles = patternArrays
                              .Select((x, i) => new KeyValuePair <int, Tile>(i, x.Values[0, 0, 0]))
                              .ToDictionary(x => x.Key, x => x.Value);

            tilesToPatterns = patternsToTiles.ToLookup(x => x.Value, x => x.Key);
        }
Esempio n. 21
0
        /// <summary>
        /// Copies a <see cref="ITopoArray{T}"/> into a 2d array.
        /// </summary>
        public static T[,] ToArray2d <T>(this ITopoArray <T> topoArray)
        {
            var width   = topoArray.Topology.Width;
            var height  = topoArray.Topology.Height;
            var results = new T[width, height];

            for (var x = 0; x < width; x++)
            {
                for (var y = 0; y < height; y++)
                {
                    results[x, y] = topoArray.Get(x, y);
                }
            }
            return(results);
        }
Esempio n. 22
0
        private static List <T> SliceZ <T>(ITopoArray <T> topoArray, int z)
        {
            var l        = new List <T>();
            var topology = topoArray.Topology;

            for (var y = 0; y < topology.Height; y++)
            {
                for (var x = 0; x < topology.Width; x++)
                {
                    var i = topology.GetIndex(x, y, z);
                    l.Add(topology.ContainsIndex(i) ? topoArray.Get(i) : default(T));
                }
            }
            return(l);
        }
Esempio n. 23
0
        private static List <T> SliceY <T>(ITopoArray <T> topoArray, int y)
        {
            var l        = new List <T>();
            var topology = topoArray.Topology;

            for (var z = 0; z < topology.Depth; z++)
            {
                for (var x = 0; x < topology.Width; x++)
                {
                    var i = topology.GetIndex(x, y, z);
                    l.Add(topology.ContainsIndex(i) ? topoArray.Get(i) : default(T));
                }
            }
            return(l);
        }
Esempio n. 24
0
        public static void Save(Vox vox, ITopoArray <byte> topArray)
        {
            Size size = null;

            foreach (var chunk in vox.Chunks)
            {
                if (chunk is Size)
                {
                    size = (Size)chunk;
                }
                else if (chunk is Xyzi xyzi)
                {
                    Save(size, xyzi, topArray);
                    return;
                }
            }
        }
Esempio n. 25
0
        public static void GetPatterns(
            ITopoArray <Tile> sample,
            int nx,
            int ny,
            int nz,
            bool periodicX,
            bool periodicY,
            bool periodicZ,
            Dictionary <PatternArray, int> patternIndices,
            List <PatternArray> patternArrays,
            List <double> frequencies)
        {
            var width  = sample.Topology.Width;
            var height = sample.Topology.Height;
            var depth  = sample.Topology.Depth;
            var maxx   = periodicX ? width - 1 : width - nx;
            var maxy   = periodicY ? height - 1 : height - ny;
            var maxz   = periodicZ ? depth - 1 : depth - nz;

            for (var x = 0; x <= maxx; x++)
            {
                for (var y = 0; y <= maxy; y++)
                {
                    for (var z = 0; z <= maxz; z++)
                    {
                        PatternArray patternArray;
                        if (!TryExtract(sample, nx, ny, nz, x, y, z, out patternArray))
                        {
                            continue;
                        }
                        int pattern;
                        if (!patternIndices.TryGetValue(patternArray, out pattern))
                        {
                            pattern = patternIndices[patternArray] = patternIndices.Count;
                            patternArrays.Add(patternArray);
                            frequencies.Add(1);
                        }
                        else
                        {
                            frequencies[pattern] += 1;
                        }
                    }
                }
            }
        }
Esempio n. 26
0
        public static ITopoArray <T> Rotate <T>(ITopoArray <T> original, Rotation rotation, TileRotate <T> tileRotate = null)
        {
            var type = original.Topology.Directions.Type;

            if (type == DirectionSetType.Cartesian2d ||
                type == DirectionSetType.Cartesian3d)
            {
                return(SquareRotate(original, rotation, tileRotate));
            }
            else if (type == DirectionSetType.Hexagonal2d)
            {
                return(HexRotate(original, rotation, tileRotate));
            }
            else
            {
                throw new Exception($"Unknown directions type {type}");
            }
        }
Esempio n. 27
0
        public static ITopoArray <T> HexRotate <T>(ITopoArray <T> original, int rotateCw, bool reflectX, TileRotate <T> tileRotate = null)
        {
            if (rotateCw == 0 && !reflectX)
            {
                return(original);
            }

            var microRotate = rotateCw % 3;
            var rotate180   = rotateCw % 2 == 1;

            // Actually do a reflection/rotation
            ValueTuple <int, int> MapCoord(int x, int y)
            {
                return(HexRotateVector(x, y, microRotate, rotate180, reflectX));
            }

            return(RotateInner(original, MapCoord, tileRotate));
        }
Esempio n. 28
0
        public static IEnumerable <ITopoArray <Tile> > GetRotatedSamples(
            ITopoArray <Tile> sample,
            TileRotation tileRotation = null)
        {
            tileRotation = tileRotation ?? new TileRotation();

            foreach (var rotation in tileRotation.RotationGroup)
            {
                if (sample.Topology.Directions.Type == DirectionsType.Hexagonal2d)
                {
                    yield return(TopoArrayUtils.HexRotate(sample, rotation, tileRotation));
                }
                else
                {
                    yield return(TopoArrayUtils.Rotate(sample, rotation, tileRotation));
                }
            }
        }
Esempio n. 29
0
        public static ITopoArray <T> HexRotate <T>(ITopoArray <T> original, Rotation rotation, TileRotate <T> tileRotate = null)
        {
            if (rotation.IsIdentity)
            {
                return(original);
            }

            var microRotate = (rotation.RotateCw / 60) % 3;
            var rotate180   = (rotation.RotateCw / 60) % 2 == 1;

            // Actually do a reflection/rotation
            ValueTuple <int, int> MapCoord(int x, int y)
            {
                return(HexRotateVector(x, y, microRotate, rotate180, rotation.ReflectX));
            }

            return(RotateInner(original, MapCoord, tileRotate));
        }
Esempio n. 30
0
        /// <summary>
        /// Copies a <see cref="ITopoArray{T}"/> into a 3d array.
        /// </summary>
        public static T[,,] ToArray3d <T>(this ITopoArray <T> topoArray)
        {
            var width   = topoArray.Topology.Width;
            var height  = topoArray.Topology.Height;
            var depth   = topoArray.Topology.Depth;
            var results = new T[width, height, depth];

            for (var x = 0; x < width; x++)
            {
                for (var y = 0; y < height; y++)
                {
                    for (var z = 0; z < depth; z++)
                    {
                        results[x, y, z] = topoArray.Get(x, y, z);
                    }
                }
            }
            return(results);
        }