unit RenderST; interface uses Windows, Classes, Forms, Graphics, ImageMaker, Render, RenderTypes, Xform, ControlPoint; type TBatchProc = procedure of object; type TBaseSTRenderer = class(TBaseRenderer) protected PropTable: array[0..SUB_BATCH_SIZE] of TXform; finalXform: TXform; UseFinalXform: boolean; procedure Prepare; override; procedure SetPixels; override; procedure IterateBatch; virtual; abstract; procedure IterateBatchAngle; virtual; abstract; procedure IterateBatchFX; virtual; abstract; procedure IterateBatchAngleFX; virtual; abstract; end; implementation uses Math, Sysutils; { TBaseSTRenderer } /////////////////////////////////////////////////////////////////////////////// procedure TBaseSTRenderer.Prepare; var i, n: Integer; propsum: double; LoopValue: double; j: integer; TotValue: double; begin totValue := 0; n := fcp.NumXforms; assert(n > 0); finalXform := fcp.xform[n]; finalXform.Prepare; useFinalXform := fcp.FinalXformEnabled and fcp.HasFinalXform; for i := 0 to n - 1 do begin fcp.xform[i].Prepare; totValue := totValue + fcp.xform[i].density; end; LoopValue := 0; for i := 0 to PROP_TABLE_SIZE-1 do begin propsum := 0; j := -1; repeat inc(j); propsum := propsum + fcp.xform[j].density; until (propsum > LoopValue) or (j = n - 1); PropTable[i] := fcp.xform[j]; LoopValue := LoopValue + TotValue / PROP_TABLE_SIZE; end; end; /////////////////////////////////////////////////////////////////////////////// procedure TBaseSTRenderer.SetPixels; var i: integer; nsamples: int64; IterateBatchProc: procedure of object; begin if FNumSlices > 1 then TimeTrace(Format('Rendering slice #%d of %d...', [FSlice + 1, FNumSlices])) else TimeTrace('Rendering...'); Randomize; if FCP.FAngle = 0 then begin if UseFinalXform then IterateBatchProc := IterateBatchFX else IterateBatchProc := IterateBatch; end else begin if UseFinalXform then IterateBatchProc := IterateBatchAngleFX else IterateBatchProc := IterateBatchAngle; end; NSamples := Round(sample_density * NrSlices * bucketSize / (oversample * oversample)); FNumBatches := Round(nsamples / (fcp.nbatches * SUB_BATCH_SIZE)); if FNumBatches = 0 then FNumBatches := 1; FMinBatches := Round(FNumBatches * FMinDensity / fcp.sample_density); if FMinBatches = 0 then FMinBatches := 1; for i := 0 to FNumBatches-1 do begin if FStop <> 0 then begin // if (FStop <> 0) or (i >= FMinBatches) then begin //? fcp.actual_density := fcp.actual_density + fcp.sample_density * i / FNumBatches; // actual quality of incomplete render FNumBatches := i; exit; end; if ((i and $1F) = 0) then Progress(i / FNumBatches); IterateBatchProc; end; fcp.actual_density := fcp.actual_density + fcp.sample_density; Progress(1); end; end.