// For time visualisation - each step is added to the timelapse
        void AddCurrentFrameToHistory(WaveCollapseHistory timelapse)
        {
            var timeFrameToPoints    = OutputObservations();
            var timeFrameUncollapsed = wave.GetPossibleTileTypes();
            var patternOccurence     = wave.GetCollapsedPatternsCounts();

            var timeFrameElement = new WaveCollapseHistoryElement(timeFrameToPoints.Item1,
                                                                  timeFrameToPoints.Item2, timeFrameToPoints.Item3, wave.superpositions, timeFrameUncollapsed, patternOccurence,
                                                                  wave.entropies);

            timelapse.AddTimeFrame(timeFrameElement);
        }
示例#2
0
 public GH_WaveCollapseHistory()
 {
     Value = new WaveCollapseHistory();
 }
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // Get wave function collapse data
            GH_PatternsFromSample gh_patterns = new GH_PatternsFromSample();

            DA.GetData <GH_PatternsFromSample>(0, ref gh_patterns);

            List <Point3d> wavePoints = new List <Point3d>();

            DA.GetDataList <Point3d>(1, wavePoints);

            bool backtrack = false;

            DA.GetData <bool>(2, ref backtrack);

            double iterations = 0;

            DA.GetData <double>(3, ref iterations);

            // Get image data.
            GH_Image inputImage = new GH_Image();

            DA.GetData(4, ref inputImage);

            List <double> newWeights = new List <double>();

            DA.GetDataList(5, newWeights);

            bool applyWeights = false;

            DA.GetData(6, ref applyWeights);

            // Extract parameters to run Wave Function Collapse.
            var patterns = gh_patterns.Value.Patterns;
            var weights  = gh_patterns.Value.TilesWeights;
            var N        = gh_patterns.Value.N;

            int width  = Utils.GetNumberofPointsInOneDimension(wavePoints[0].X, wavePoints[wavePoints.Count - 1].X);
            int height = Utils.GetNumberofPointsInOneDimension(wavePoints[0].Y, wavePoints[wavePoints.Count - 1].Y);

            // Prepare image data.
            //var image = convertImageListToArray(rawImage, width, height);
            //var image = Utils.generateRandomImage(width, height);
            var image = inputImage.Value.Brightness;

            // Run Wave Function Collapse.
            var wfc     = new WaveFunctionCollapseRunner();
            var history = new WaveCollapseHistory();

            if (applyWeights)
            {
                history = wfc.Run(patterns, N, width, height, weights, (int)iterations, backtrack, image, newWeights);
            }
            else
            {
                history = wfc.Run(patterns, N, width, height, weights, (int)iterations, backtrack, image);
            }
            var return_value = new GH_WaveCollapseHistory(history);

            DA.SetData(0, return_value);
        }
        // Input new weights!!!!
        public WaveCollapseHistory Run(List <Pattern> patterns, int N, int width, int height,
                                       float[] weights, int iterations, bool backtrack,
                                       double[,] image, List <double> newWeights)
        {
            WaveCollapseHistory timelapse = new WaveCollapseHistory();

            var counter             = 0;
            var sumOfCollapsedSteps = 0;

            while (counter < iterations)
            {
                counter++;
                int steps = 0;

                wave = new Wave(width, height, patterns, N, image);
                //SeedByImage(image, patterns);
                //AddCurrentFrameToHistory(timelapse);

                while (!wave.IsCollapsed())
                {
                    if (wave.Contradiction())
                    {
                        break;
                    }

                    var observed = wave.ObserveWithImageAndWeights(image, newWeights);

                    if (backtrack)
                    {
                        var canPropagate = wave.CheckIfPropagateWithoutContradictionWithRecalculatedWeights
                                               (observed.Item1, observed.Item2, observed.Item3, observed.Item4);
                        int repeatedObservations = 0;

                        while (!canPropagate)
                        {
                            observed = wave.ObserveWithImageAndWeights(image, newWeights);

                            if (observed.Item3 == null)
                            {
                                throw new Exception("Null pattern selected");
                            }
                            canPropagate = wave.CheckIfPropagateWithoutContradictionWithRecalculatedWeights
                                               (observed.Item1, observed.Item2, observed.Item3, observed.Item4);
                            repeatedObservations++;

                            if (repeatedObservations > (int)(patterns.Count / 2))
                            {
                                break;
                            }
                        }

                        wave.PropagateByUpdatingSuperposition(observed.Item1, observed.Item2, patterns[observed.Item4]);
                    }
                    else
                    {
                        observed = wave.ObserveWithImageAndWeights(image, newWeights);
                        try  { wave.PropagateByUpdatingSuperposition(observed.Item1, observed.Item2, patterns[observed.Item4]); }
                        catch (DataMisalignedException ex)  { break; }
                    }

                    AddCurrentFrameToHistory(timelapse);
                    steps++;
                }


                if (wave.Contradiction())
                {
                    double percentage = steps / (width * height * 1.0);
                    System.Diagnostics.Debug.WriteLine("Contradiction on " + steps + " th step of " + width * height +
                                                       ", which is " + percentage + " of the whole wave");

                    sumOfCollapsedSteps += steps;

                    timelapse.Clear();
                    continue;
                }
                else
                {
                    averageCollapseStep = sumOfCollapsedSteps / counter;
                    System.Diagnostics.Debug.WriteLine("Average collapse step is: " + averageCollapseStep + " for " + width * height + " steps");
                    break;
                }
            }

            averageCollapseStep = sumOfCollapsedSteps / counter;
            System.Diagnostics.Debug.WriteLine("Average collapse step is: " + averageCollapseStep + " for " + width * height + " steps");
            return(timelapse);
        }
        public WaveCollapseHistory Run(List <Pattern> patterns, int N, int width, int height, float[] weights, bool backtrack, int iterations)
        {
            WaveCollapseHistory timelapse = new WaveCollapseHistory();

            var counter             = 0;
            var sumOfCollapsedSteps = 0;

            while (counter < iterations)
            {
                counter++;
                int steps = 0;

                wave = new Wave(width, height, patterns, N);

                // Start with random seed
                SeedRandom(width, height, patterns);
                AddCurrentFrameToHistory(timelapse);

                // Break if contracition, otherwise run observations until it is not completaly observed
                while (!wave.IsCollapsed())
                {
                    if (wave.Contradiction())
                    {
                        break;
                    }

                    var observed = wave.Observe();

                    if (backtrack)
                    {
                        // Backtracking: working version with one step backtracking
                        var canPropagate         = wave.CheckIfPropagateWithoutContradiction(observed.Item1, observed.Item2, observed.Item3);
                        int repeatedObservations = 0;

                        while (!canPropagate)
                        {
                            observed     = wave.Observe();
                            canPropagate = wave.CheckIfPropagateWithoutContradiction(observed.Item1, observed.Item2, observed.Item3);
                            repeatedObservations++;

                            if (repeatedObservations > (int)(patterns.Count / 2))
                            {
                                break;
                            }
                        }

                        wave.PropagateByUpdatingSuperposition(observed.Item1, observed.Item2, observed.Item3);
                    }
                    else
                    {
                        // No backtracking: working version without backtracking
                        observed = wave.Observe();
                        try
                        {
                            wave.PropagateByUpdatingSuperposition(observed.Item1, observed.Item2, observed.Item3);
                        }
                        catch (DataMisalignedException ex)
                        {
                            break;
                        }
                    }

                    AddCurrentFrameToHistory(timelapse);
                    steps++;
                }


                if (wave.Contradiction())
                {
                    double percentage = steps / (width * height * 1.0);
                    System.Diagnostics.Debug.WriteLine("Contradiction on " + steps + " th step of " + width * height +
                                                       ", which is " + percentage + " of the whole wave");

                    sumOfCollapsedSteps += steps;

                    timelapse.Clear();
                    continue;
                }
                else
                {
                    averageCollapseStep = sumOfCollapsedSteps / counter;
                    System.Diagnostics.Debug.WriteLine("Average collapse step is: " + averageCollapseStep + " for " + width * height + " steps");
                    break;
                }
            }

            averageCollapseStep = sumOfCollapsedSteps / counter;
            System.Diagnostics.Debug.WriteLine("Average collapse step is: " + averageCollapseStep + " for " + width * height + " steps");
            return(timelapse);
        }