Beispiel #1
0
        private void CreateWangTileThreaded(object obj)
        {
            createWangTileParam_t param = (createWangTileParam_t)obj;

            param.tileArray[param.tileIndex] = new WangTile(param.tileBaseDistribution, param.neighbours);
            param.autoResetEvent.Set();
        }
Beispiel #2
0
        public void Generate(int numColors, int samplesPerTile, int numThreads )
        {
            random = new Random();
            this.numColors = numColors;
            tiles = new List<WangTile>();

            const int numEdges = 4;
            int numTiles = (int)Math.Pow(numColors, numEdges);

            #region generate Poisson distributions
            List<PoissonSample>[] distributions = new List<PoissonSample>[numTiles];
            generatePoissonDistParam_t[] threadParams = new generatePoissonDistParam_t[numThreads];
            PoissonDistribution[] generators = new PoissonDistribution[numThreads];
            AutoResetEvent[] waitHandles = new AutoResetEvent[numThreads];

            for (int i = 0; i < numThreads; i++)
            {
                threadParams[i].dist = new PoissonDistribution();
                threadParams[i].numSamples = samplesPerTile;
                waitHandles[i] = new AutoResetEvent(false);
                threadParams[i].autoResetEvent = waitHandles[i];
            }
            int t = 0;
            Queue<int> availableThreads = new Queue<int>();
            for (int i = 0; i < numThreads; i++) availableThreads.Enqueue(i);

            if (OnConsoleMessage != null) OnConsoleMessage("Generating " + numTiles + " source Poisson Distributions with " + samplesPerTile + " samples each...");

            Image debugImage = null;
            if (OnDebugStep != null) debugImage = new Bitmap(800, 800);

            while (t < numTiles || availableThreads.Count < numThreads)
            {
                while (availableThreads.Count > 0 && t < numTiles)
                {
                    int i = availableThreads.Dequeue();
                    if (OnProgressReport != null) OnProgressReport((float)(t + 1) / numTiles);
                    distributions[t] = new List<PoissonSample>(samplesPerTile);
                    threadParams[i].result = distributions[t];
                    ThreadPool.QueueUserWorkItem(new WaitCallback(GeneratePoissonDistThreaded), threadParams[i]);
                    t++;
                }
                int index = WaitHandle.WaitAny(waitHandles);
                if (debugImage != null)
                {
                    PoissonDistribution.ToImage( threadParams[index].dist.Samples, Color.Black, debugImage, 1);
                    OnDebugStep(debugImage, "Poisson Distribution " + t);
                }
                availableThreads.Enqueue(index);
            }

            #endregion

            #region generate seam tiles
            List<SourceTile> seamTiles = new List<SourceTile>();
            #if DEBUG
            Color[] colors = new Color[numColors];
            for( int i = 0; i < numColors; i++ ) colors[i] = Color.FromArgb(random.Next(256), random.Next(256), random.Next(256));
            #endif
            for (int i = 0; i < numColors; i++)
            {
                PoissonDistribution distribution = new PoissonDistribution();
                distribution.Generate(samplesPerTile);
            #if DEBUG
                foreach (PoissonSample p in distribution.Samples) p.color = colors[i];
            #endif
                seamTiles.Add(new SourceTile(distribution.Samples, i));
            }
            #endregion

            #region generate all edge permutations
            /*
             * 0000 0001 0002 ... 000n
             * 0010 0011 0012 ... 001n
             * 0020 0021 0022 ... 002n
             * ...
             * 00n0 00n1 00n2 ... 00nn
             *
             * 0100 0101 0102 ... 010n
             * 0110 0111 0112 ... 011n
             * ...
             * 01n0 01n1 01n2 ... 01nn
             *
             * ...
             *
             * nnn0 nnn1 nnn2 ... nnnn
             */
            int[,] edgeCol = new int[numTiles,numEdges];
            for (int i = 0; i < numEdges; i++) edgeCol[0, i] = 0;
            for (int i = 1; i < numTiles; i++)
            {
                for (int j = 0; j < numEdges; j++)
                {
                    edgeCol[i,j] = (edgeCol[i-1,j] + (i % (int)Math.Pow(numColors, j) == 0 ? 1 : 0)) % numColors;
                }
            }
            #endregion

            #region generate wang tiles
            WangTile[] tileArray = new WangTile[numTiles];
            t = 0;
            availableThreads.Clear();
            createWangTileParam_t[] createWangTileParams = new createWangTileParam_t[numThreads];
            for (int i = 0; i < numThreads; i++)
            {
                availableThreads.Enqueue(i);
                createWangTileParams[i] = new createWangTileParam_t();
                createWangTileParams[i].autoResetEvent = waitHandles[i];
                createWangTileParams[i].autoResetEvent.Reset();
                createWangTileParams[i].tileArray = tileArray;
            }

            if (OnConsoleMessage != null) OnConsoleMessage("Merging distributions to generate Wang Tiles..." );

            while (t < numTiles || availableThreads.Count < numThreads)
            {
                while (availableThreads.Count > 0 && t < numTiles)
                {
                    int i = availableThreads.Dequeue();
                    if (OnProgressReport != null) OnProgressReport((float)( t + 1 ) / numTiles);

                    createWangTileParams[i].tileBaseDistribution = distributions[t];
                    createWangTileParams[i].neighbours = new List<SourceTile>();
                    createWangTileParams[i].tileIndex = t;
                    if (numColors > 1)
                    {
                        for (int j = 0; j < numEdges; j++)
                            createWangTileParams[i].neighbours.Add(seamTiles[edgeCol[t, j]]);
                    }
                    ThreadPool.QueueUserWorkItem(new WaitCallback(CreateWangTileThreaded), createWangTileParams[i]);
                    t++;
                }
                int index = WaitHandle.WaitAny(waitHandles);
                availableThreads.Enqueue(index);
            }
            tiles = tileArray.ToList();

            SortTiles();
            MakeRecursive();

            if (OnDebugStep != null)
            {
                ToColorTiles(debugImage, new Size(8, 8));
                OnDebugStep(debugImage, "Sample coverage of the generated Wang Tiles" );
            }

            #endregion
        }
Beispiel #3
0
        public void Generate(int numColors, int samplesPerTile, int numThreads)
        {
            random         = new Random();
            this.numColors = numColors;
            tiles          = new List <WangTile>();

            const int numEdges = 4;
            int       numTiles = (int)Math.Pow(numColors, numEdges);

            #region generate Poisson distributions
            List <PoissonSample>[]       distributions = new List <PoissonSample> [numTiles];
            generatePoissonDistParam_t[] threadParams  = new generatePoissonDistParam_t[numThreads];
            PoissonDistribution[]        generators    = new PoissonDistribution[numThreads];
            AutoResetEvent[]             waitHandles   = new AutoResetEvent[numThreads];

            for (int i = 0; i < numThreads; i++)
            {
                threadParams[i].dist           = new PoissonDistribution();
                threadParams[i].numSamples     = samplesPerTile;
                waitHandles[i]                 = new AutoResetEvent(false);
                threadParams[i].autoResetEvent = waitHandles[i];
            }
            int         t = 0;
            Queue <int> availableThreads = new Queue <int>();
            for (int i = 0; i < numThreads; i++)
            {
                availableThreads.Enqueue(i);
            }

            if (OnConsoleMessage != null)
            {
                OnConsoleMessage("Generating " + numTiles + " source Poisson Distributions with " + samplesPerTile + " samples each...");
            }

            Image debugImage = null;
            if (OnDebugStep != null)
            {
                debugImage = new Bitmap(800, 800);
            }

            while (t < numTiles || availableThreads.Count < numThreads)
            {
                while (availableThreads.Count > 0 && t < numTiles)
                {
                    int i = availableThreads.Dequeue();
                    if (OnProgressReport != null)
                    {
                        OnProgressReport((float)(t + 1) / numTiles);
                    }
                    distributions[t]       = new List <PoissonSample>(samplesPerTile);
                    threadParams[i].result = distributions[t];
                    ThreadPool.QueueUserWorkItem(new WaitCallback(GeneratePoissonDistThreaded), threadParams[i]);
                    t++;
                }
                int index = WaitHandle.WaitAny(waitHandles);
                if (debugImage != null)
                {
                    PoissonDistribution.ToImage(threadParams[index].dist.Samples, Color.Black, debugImage, 1);
                    OnDebugStep(debugImage, "Poisson Distribution " + t);
                }
                availableThreads.Enqueue(index);
            }

            #endregion

            #region generate seam tiles
            List <SourceTile> seamTiles = new List <SourceTile>();
#if DEBUG
            Color[] colors = new Color[numColors];
            for (int i = 0; i < numColors; i++)
            {
                colors[i] = Color.FromArgb(random.Next(256), random.Next(256), random.Next(256));
            }
#endif
            for (int i = 0; i < numColors; i++)
            {
                PoissonDistribution distribution = new PoissonDistribution();
                distribution.Generate(samplesPerTile);
#if DEBUG
                foreach (PoissonSample p in distribution.Samples)
                {
                    p.color = colors[i];
                }
#endif
                seamTiles.Add(new SourceTile(distribution.Samples, i));
            }
            #endregion

            #region generate all edge permutations

            /*
             * 0000 0001 0002 ... 000n
             * 0010 0011 0012 ... 001n
             * 0020 0021 0022 ... 002n
             * ...
             * 00n0 00n1 00n2 ... 00nn
             *
             * 0100 0101 0102 ... 010n
             * 0110 0111 0112 ... 011n
             * ...
             * 01n0 01n1 01n2 ... 01nn
             *
             * ...
             *
             * nnn0 nnn1 nnn2 ... nnnn
             */
            int[,] edgeCol = new int[numTiles, numEdges];
            for (int i = 0; i < numEdges; i++)
            {
                edgeCol[0, i] = 0;
            }
            for (int i = 1; i < numTiles; i++)
            {
                for (int j = 0; j < numEdges; j++)
                {
                    edgeCol[i, j] = (edgeCol[i - 1, j] + (i % (int)Math.Pow(numColors, j) == 0 ? 1 : 0)) % numColors;
                }
            }
            #endregion

            #region generate wang tiles
            WangTile[] tileArray = new WangTile[numTiles];
            t = 0;
            availableThreads.Clear();
            createWangTileParam_t[] createWangTileParams = new createWangTileParam_t[numThreads];
            for (int i = 0; i < numThreads; i++)
            {
                availableThreads.Enqueue(i);
                createWangTileParams[i] = new createWangTileParam_t();
                createWangTileParams[i].autoResetEvent = waitHandles[i];
                createWangTileParams[i].autoResetEvent.Reset();
                createWangTileParams[i].tileArray = tileArray;
            }

            if (OnConsoleMessage != null)
            {
                OnConsoleMessage("Merging distributions to generate Wang Tiles...");
            }

            while (t < numTiles || availableThreads.Count < numThreads)
            {
                while (availableThreads.Count > 0 && t < numTiles)
                {
                    int i = availableThreads.Dequeue();
                    if (OnProgressReport != null)
                    {
                        OnProgressReport((float)(t + 1) / numTiles);
                    }

                    createWangTileParams[i].tileBaseDistribution = distributions[t];
                    createWangTileParams[i].neighbours           = new List <SourceTile>();
                    createWangTileParams[i].tileIndex            = t;
                    if (numColors > 1)
                    {
                        for (int j = 0; j < numEdges; j++)
                        {
                            createWangTileParams[i].neighbours.Add(seamTiles[edgeCol[t, j]]);
                        }
                    }
                    ThreadPool.QueueUserWorkItem(new WaitCallback(CreateWangTileThreaded), createWangTileParams[i]);
                    t++;
                }
                int index = WaitHandle.WaitAny(waitHandles);
                availableThreads.Enqueue(index);
            }
            tiles = tileArray.ToList();

            SortTiles();
            MakeRecursive();

            if (OnDebugStep != null)
            {
                ToColorTiles(debugImage, new Size(8, 8));
                OnDebugStep(debugImage, "Sample coverage of the generated Wang Tiles");
            }

            #endregion
        }