Exemplo n.º 1
0
        public Sample GetSample(Sample prevSample)
        {

            TotalSamples++;

            if (!warmUpcomplete)
            {
                var wmsample = new Sample(this);
                var rx = wmsample.GetLazyValue();
                var ry = wmsample.GetLazyValue();
                wmsample.imageX = rx * screenWidth;
                wmsample.imageY = ry * screenHeight;


                warmUpcomplete = TotalSamples >= screenWidth * screenHeight * WarmupPasses;

                return wmsample;
            }
#if VERBOSE
            if (TotalSamples == screenWidth * screenHeight * WarmupPasses+1)
            {
                Tracer.TraceLine("T{0} Warmup complete", tIdx);
                var sampleBlocks = new HashSet<SampleBlock>();
                foreach (var sampleBlock in blocks)
                {
                    if (!sampleBlocks.Contains(sampleBlock) && (sampleBlock.BlockError(Film) > ErrorStop))
                    {
                        sampleBlock.CachedError = sampleBlock.BlockError(Film);
                        sampleBlocks.Add(sampleBlock);
                    }
                }

                this.blocks = sampleBlocks.ToList();
                Tracer.TraceLine("T{0} duplicate removal complete", tIdx);

                Classify(blocks);
                Tracer.TraceLine("T{0} classification complete", tIdx);

            }
#endif
            CurrentBlock.TotalSamples++;


            if (blocks.Count == 0)
            {
                this.Init(Width, Height);
                Tracer.TraceLine("Adaptive sampling complete! Start another iteration");
                return null;
            }
            currentBlockSample++;

            if (currentBlockSample >= CurrentBlock.SamplesInBlock(ImportantBlockSamples))
            {
                blockIndex++;
                currentBlockSample= 0;
            }

            if (blockIndex >= blocks.Count)
            {
                blockIndex = Math.Min(tIdx, blocks.Count - 1);
            }
            CurrentBlock = blocks[blockIndex];
            if (CurrentBlock.TotalSamples >= CurrentBlock.SamplesPerIteration * CurrentBlock.BlockWidth * CurrentBlock.BlockHeight)
            {
                var blockError = CurrentBlock.BlockError(this.Film);

                if (blockError > ErrorSplit)
                {
                    this.SplitBlock(CurrentBlock);
                }
                else if (blockError < ErrorStop)
                {
#if VERBOSE
                    Tracer.TraceLine("{0} Block is ready", blockIndex);
                    Tracer.TraceLine("Rem block {0} block error {1} ", blocks[blockIndex].ToString(), blockError,
                                     blocks[blockIndex].BlockWidth, blocks[blockIndex].BlockHeight);
#endif
                    this.TotalSamples += this.CurrentBlock.SamplerPerBlock;
#if VERBOSE
                    Tracer.TraceLine("Block Count " + blocks.Count);
#endif
                }
                else if (subBlocks.Count < 65535)
                {

                    foreach (var block in blocks)
                    {
                        var proposalB = block.Split(block.SamplesPerIteration);
                        foreach (var proposalBlock in proposalB)
                        {
                            if (proposalBlock.BlockError(Film) > block.BlockError(Film))
                            {
                                //this.blocks.AddRange(proposalBlock.Split(CurrentBlock.SamplesPerIteration));
                                subBlocks.Add(proposalBlock);
                            }
                            else
                            {
                                //this.blocks.Add(proposalBlock);
                                //this.blocks.AddRange(proposalBlock.Split(proposalBlock.SamplesPerIteration * 2));
                                subBlocks.AddRange(proposalBlock.Split(proposalBlock.SamplesPerIteration));
                                //foreach (var block in blocks)
                                //{
                                //    Film.StatsRect(block.Xstart, block.Ystart, block.BlockWidth, block.BlockHeight, blockIndex);
                                //}
                            }
                        }
                    }
                }

#if VERBOSE
                //Tracer.TraceLine("T{4}- Removing {2}/{3} block {1} error {0}", blockError, CurrentBlock.ToString(), blocks.Count, blockIndex, tIdx);

#endif
                this.blocks.Remove(CurrentBlock);

                if (blocks.Count == 0 && this.subBlocks.Count > 0)
                {
                    Tracer.TraceLine("T{0} Dicing", tIdx);

                    generation++;
                    this.blocks = this.subBlocks.ToList();
                    this.subBlocks.Clear();

                    var sampleBlocks = new HashSet<SampleBlock>();
                    foreach (var sampleBlock in blocks)
                    {
                        if (!sampleBlocks.Contains(sampleBlock) && (sampleBlock.BlockError(Film) > ErrorStop))
                        {
                            sampleBlock.CachedError = sampleBlock.BlockError(Film);
                            sampleBlocks.Add(sampleBlock);
                        }
                    }


#if VERBOSE
                    Tracer.TraceLine("Removing {0} duplicates", this.blocks.Count - sampleBlocks.Count);

                    Tracer.TraceLine("T{0} Generation {1} sampling", tIdx, generation);



#endif
                   Classify(blocks);
                }

                if (blockIndex >= this.blocks.Count)
                {
                    this.blockIndex = 0;
                }

                this.CurrentBlock = this.blocks[blockIndex];
                this.EvalCurrentBlock();
                pass += CurrentBlock.SamplesPerIteration;


#if VERBOSE2
                for (int index = 0; index < blocks.Count; index++)
                {
                    var block = blocks[index];
                    //bool remove = false;
                    //if ((block.Xstart + block.BlockWidth) > screenWidth)
                    //{
                    //    Tracer.TraceLine("Invalid block Width " + (block.Xstart + block.BlockWidth));
                    //    remove = true;
                    //}
                    //if ((block.Ystart + block.BlockHeight) > screenHeight)
                    //{
                    //    Tracer.TraceLine("Invalid block Height " + (block.Ystart + block.BlockHeight));
                    //    remove = true;
                    //}
                    Film.StatsRect(block.Xstart, block.Ystart, block.BlockWidth, block.BlockHeight, blockIndex);
                    //if (remove)
                    //{
                    //    blocks.RemoveAt(index);
                    //    Tracer.TraceLine("Removing invalid block {0} block size {2}x{3}", blockIndex, blockError, blocks[blockIndex].BlockWidth, blocks[blockIndex].BlockHeight);

                    //}
                }

#endif
            }

            CurrentBlock = blocks[blockIndex];
            Sample sample = CurrentBlock.GetSample(this);

            return sample;
        }