2006-08-22 09:39:27 -04:00
|
|
|
unit RenderST;
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
|
|
|
Windows, Classes, Forms, Graphics, ImageMaker,
|
|
|
|
Render, RenderTypes, Xform, ControlPoint;
|
|
|
|
|
|
|
|
type
|
|
|
|
TBatchProc = procedure of object;
|
|
|
|
|
|
|
|
type
|
|
|
|
TBaseSTRenderer = class(TBaseRenderer)
|
|
|
|
|
|
|
|
protected
|
2006-12-09 03:39:22 -05:00
|
|
|
PropTable: array[0..PROP_TABLE_SIZE] of TXform;
|
2006-08-22 09:39:27 -04:00
|
|
|
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
|
2006-09-06 08:34:00 -04:00
|
|
|
if FNumSlices > 1 then
|
|
|
|
TimeTrace(Format('Rendering slice #%d of %d...', [FSlice + 1, FNumSlices]))
|
|
|
|
else
|
|
|
|
TimeTrace('Rendering...');
|
2006-08-22 09:39:27 -04:00
|
|
|
|
|
|
|
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
|
2006-09-06 08:34:00 -04:00
|
|
|
// if (FStop <> 0) or (i >= FMinBatches) then begin //?
|
2006-08-22 09:39:27 -04:00
|
|
|
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.
|