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; }