Added transform syncronization, an animation module and made the app work faster

This commit is contained in:
Alice Vital
2022-06-23 13:22:32 +03:00
parent 25a72c3c86
commit b1552d0ebc
98 changed files with 11657 additions and 7788 deletions

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -26,9 +26,13 @@ unit RndFlame;
interface
uses
ControlPoint, Xform;
ControlPoint;
function RandomFlame(SourceCP: TControlPoint= nil; algorithm: integer = 0): TControlPoint;
function RandomFlame(SourceCP: TControlPoint = nil; algorithm: integer = 0): TControlPoint;
// AV: made the following public to get rid of duplicated code
procedure SetVariation(cp: TControlPoint);
procedure RandomVariation(cp: TControlPoint);
implementation
@ -75,83 +79,6 @@ begin
end;
end; *)
function CreatePalette(strng: string): TColorMap;
{ Loads a palette from a gradient string }
var
Strings: TStringList;
index, i: integer;
Tokens: TStringList;
Indices, Colors: TStringList;
a, b: integer;
begin
Strings := TStringList.Create;
Tokens := TStringList.Create;
Indices := TStringList.Create;
Colors := TStringList.Create;
try
try
Strings.Text := strng;
if Pos('}', Strings.Text) = 0 then raise EFormatInvalid.Create('No closing brace');
if Pos('{', Strings[0]) = 0 then raise EFormatInvalid.Create('No opening brace.');
GetTokens(ReplaceTabs(strings.text), tokens);
Tokens.Text := Trim(Tokens.text);
i := 0;
while (Pos('}', Tokens[i]) = 0) and (Pos('opacity:', Lowercase(Tokens[i])) = 0) do
begin
if Pos('index=', LowerCase(Tokens[i])) <> 0 then
Indices.Add(GetVal(Tokens[i]))
else if Pos('color=', LowerCase(Tokens[i])) <> 0 then
Colors.Add(GetVal(Tokens[i]));
inc(i)
end;
for i := 0 to 255 do
begin
Result[i][0] := 0;
Result[i][1] := 0;
Result[i][2] := 0;
end;
if Indices.Count = 0 then raise EFormatInvalid.Create('No color info');
for i := 0 to Indices.Count - 1 do
begin
try
index := StrToInt(Indices[i]);
while index < 0 do inc(index, 400);
index := Round(Index * (255 / 399));
indices[i] := IntToStr(index);
assert(index>=0);
assert(index<256);
Result[index][0] := StrToInt(Colors[i]) mod 256;
Result[index][1] := trunc(StrToInt(Colors[i]) / 256) mod 256;
Result[index][2] := trunc(StrToInt(Colors[i]) / 65536);
except
end;
end;
i := 1;
repeat
a := StrToInt(Trim(Indices[i - 1]));
b := StrToInt(Trim(Indices[i]));
RGBBlend(a, b, Result);
inc(i);
until i = Indices.Count;
if (Indices[0] <> '0') or (Indices[Indices.Count - 1] <> '255') then
begin
a := StrToInt(Trim(Indices[Indices.Count - 1]));
b := StrToInt(Trim(Indices[0])) + 256;
RGBBlend(a, b, Result);
end;
except on EFormatInvalid do
begin
// Result := False;
end;
end;
finally
Tokens.Free;
Strings.Free;
Indices.Free;
Colors.Free;
end;
end;
procedure GetGradientFileGradientsNames(const filename: string; var NamesList: TStringList);
var
i, p: integer;
@ -225,7 +152,53 @@ begin
end;
end;
///////////////////////////////////////////////////////////////////////////////
{ ****************** Triangle transformations ******************************* }
function transform_affine(const t: TTriangle; const Triangles: TTriangles): boolean;
var
ra, rb, rc, a, b, c: double;
begin
Result := True;
ra := dist(Triangles[-1].y[0], Triangles[-1].x[0],
Triangles[-1].y[1], Triangles[-1].x[1]);
rb := dist(Triangles[-1].y[1], Triangles[-1].x[1],
Triangles[-1].y[2], Triangles[-1].x[2]);
rc := dist(Triangles[-1].y[2], Triangles[-1].x[2],
Triangles[-1].y[0], Triangles[-1].x[0]);
a := dist(t.y[0], t.x[0], t.y[1], t.x[1]);
b := dist(t.y[1], t.x[1], t.y[2], t.x[2]);
c := dist(t.y[2], t.x[2], t.y[0], t.x[0]);
if (a > ra) then
Result := False
else if (b > rb) then
Result := False
else if (c > rc) then
Result := False
else if ((a = ra) and (b = rb) and (c = rc)) then
Result := False;
end;
function triangle_area(t: TTriangle): double;
var
base, height: double;
begin
try
base := dist(t.x[0], t.y[0], t.x[1], t.y[1]);
height := line_dist(t.x[2], t.y[2], t.x[1], t.y[1],
t.x[0], t.y[0]);
if (base < 1.0) then
Result := height
else if (height < 1.0) then
Result := base
else
Result := 0.5 * base * height;
except on E: EMathError do
Result := 0;
end;
end;
{ ************************************************************************** }
procedure RandomVariation(cp: TControlPoint);
{ Randomise variation parameters }
var
@ -236,26 +209,23 @@ begin
RandSeed := MainSeed;
VarPossible := false;
for j := 0 to NRVAR - 1 do begin
VarPossible := VarPossible or Variations[j];
end;
for j := 0 to NRVAR - 1 do
if Variations[j] then begin // AV: make it faster!
VarPossible := True;
break;
end;
if not VarPossible then Variations[0] := True; // AV
for i := 0 to cp.NumXForms - 1 do begin
for j := 0 to NRVAR - 1 do
cp.xform[i].SetVariation(j, 0);
if VarPossible then begin
repeat
a := random(NRVAR);
until Variations[a];
repeat
b := random(NRVAR);
until Variations[b];
end else begin
a := 0;
b := 0;
end;
repeat
a := random(NRVAR);
until Variations[a];
repeat
b := random(NRVAR);
until Variations[b];
if (a = b) then begin
cp.xform[i].SetVariation(a, 1);
@ -278,7 +248,7 @@ begin
for i := 0 to cp.NumXForms - 1 do begin
for j := 0 to NRVAR - 1 do
cp.xform[i].SetVariation(j, 0);
cp.xform[i].SetVariation(integer(Variation), 1);
cp.xform[i].SetVariation(Variation, 1);
end;
end;
@ -414,16 +384,17 @@ begin
end;
///////////////////////////////////////////////////////////////////////////////
(*
procedure RandomWeights(var cp1: TControlPoint);
{ Randomizes xform weights }
var
i: integer;
begin
for i := 0 to Transforms - 1 do
for i := 0 to cp1.NumXForms - 1 do // AV: was Transforms - 1
cp1.xform[i].Density := random;
NormalizeWeights(cp1);
end;
*)
///////////////////////////////////////////////////////////////////////////////
function RandomFlame(SourceCP: TControlPoint; algorithm: integer): TControlPoint;
var
@ -444,22 +415,25 @@ begin
inc(MainSeed);
RandSeed := MainSeed;
transforms := random(Max - (Min - 1)) + Min;
repeat
try
inc(MainSeed);
RandSeed := MainSeed;
Result.clear;
Result.RandomCP(transforms, transforms, false);
Result.SetVariation(Variation);
inc(MainSeed);
RandSeed := MainSeed;
Result.Clear;
for i := 0 to Transforms - 1 do // AV: set starting non-zero weights...
Result.xform[i].density := 0.5;
// AV: we don't really need to randomize the same flame twice...
//Result.RandomCP(transforms, transforms, false);
//Result.SetVariation(Variation); // AV: deprecated!
SetVariation(Result); // AV: replaced old method from ControlPoint
case algorithm of
1: rnd := 0;
2: rnd := 7;
3: rnd := 9;
else
if (Variation = vLinear) or (Variation = vRandom) then
if (Variation = 0 {vLinear}) or (Variation = vRandom) then
rnd := random(10)
else
rnd := 9;
@ -479,11 +453,11 @@ begin
Result.xform[i].c[1, 1] := 1;
Result.xform[i].c[2, 0] := 0;
Result.xform[i].c[2, 1] := 0;
Result.xform[i].color := 0; }
Result.xform[i].symmetry := 0;
Result.xform[i].color := 0;
// AV: this will be done with SetVariation method!
Result.xform[i].SetVariation(0, 1);
for j := 1 to NRVAR - 1 do
Result.xform[i].SetVariation(j, 0);
Result.xform[i].SetVariation(j, 0); }
// AV: hundred of useless calculations
{Result.xform[i].Translate(random * 2 - 1, random * 2 - 1);
Result.xform[i].Rotate(random * 360);
@ -491,6 +465,7 @@ begin
Result.xform[i].Scale(random * 0.8 + 0.2)
else
Result.xform[i].Scale(random * 0.4 + 0.6); }
Result.xform[i].symmetry := 0;
if i > 0 then
s := random * 0.8 + 0.2
else
@ -512,7 +487,8 @@ begin
Result.xform[i].c[2, 0] := random * 2 - 1;
Result.xform[i].c[2, 1] := random * 2 - 1;
if Random(2) = 0 then
Result.xform[i].Multiply(1, random - 0.5, random - 0.5, 1);
Result.xform[i].Multiply(Result.xform[i].c,
1, random - 0.5, random - 0.5, 1);
if Random(2) = 1 then
begin
@ -529,7 +505,7 @@ begin
Result.xform[i].p[2,1] := random * 2 - 1;
end;
end;
SetVariation(Result);
//SetVariation(Result);
end;
7, 8:
begin
@ -559,20 +535,31 @@ begin
Result.xform[i].c[2][0] := random * 2 - 1;
Result.xform[i].c[2][1] := random * 2 - 1;
end;
{ // AV: the following was (or will be) done!
for i := 0 to NXFORMS-1 do
Result.xform[i].density := 0;
for i := 0 to Transforms - 1 do
Result.xform[i].density := 1 / Transforms;
SetVariation(Result);
}
end;
9: begin
for i := 0 to NXFORMS-1 do
{ // AV: the following was (or will be) done!
for i := 0 to NXFORMS-1 do
Result.xform[i].density := 0;
for i := 0 to Transforms - 1 do
Result.xform[i].density := 1 / Transforms;
}
for i := 0 to Transforms - 1 do begin // AV
Result.xform[i].RandomizeCoefs(Result.xform[i].c);
if Random(4) = 1 then
Result.xform[i].RandomizeCoefs(Result.xform[i].p);
end;
end;
end; // case
Result.TrianglesFromCp(Triangles);
if Random(2) > 0 then
ComputeWeights(Result, Triangles, transforms)
else
@ -628,8 +615,6 @@ begin
Result.background[2] := 0;
end;
Result.zoom := 0;
//Result.Nick := SheepNick;
//Result.URl := SheepURL;
Result.xform[Result.NumXForms].Clear;
Result.xform[Result.NumXForms].symmetry := 1;

View File

@ -5,7 +5,7 @@
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -31,8 +31,7 @@ unit XForm;
interface
uses
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
AsmRandom,
{$endif}
XFormMan, BaseVariation, Classes;
@ -60,27 +59,33 @@ type
end;
PXYpoint = ^TXYpoint;
{
T2Cpoint = record
x, y, c1, c2: double;
end;
P2Cpoint = ^T2Cpoint;
TMatrix = array[0..2, 0..2] of double;
}
{$ifdef Apo7X64}
{$else}
// AV: rewrote all asm-code from Apo7X to make it work properly again
{$ifdef CPUX86}
{$define _ASM_}
{$endif}
type
TCoefsArray = array[0..2, 0..1] of double; // AV: moved from ControlPoint
//pCoefsArray = ^TCoefsArray;
TXForm = class
public
c: array[0..2, 0..1] of double; // the coefs to the affine part of the function
p: array[0..2, 0..1] of double; // post-transform coefs!
density: double; // prob is this function is chosen
color: double; // color coord for this function. 0 - 1
color2: double; // Second color coord for this function. 0 - 1
vc: double; // Calculated color to be passed to the plugin
c: TCoefsArray; // the coefs to the affine part of the function
p: TCoefsArray; // post-transform coefs!
density: double; // prob is this function is chosen
color: double; // color coord for this function. 0 - 1
color2: double; // Second color coord for this function. 0 - 1
vc: double; // Calculated color to be passed to the plugin
symmetry: double;
c00, c01, c10, c11, c20, c21: double; // unnecessary duplicated variables
p00, p01, p10, p11, p20, p21: double; // :-)
@ -104,7 +109,6 @@ type
FTx, FTy: double; // must remain in this order
FPx, FPy: double; // some asm code relies on this
FTz, FPz: double; // 3d hack
FAngle: double;
@ -153,7 +157,7 @@ type
procedure Blur3D; // vars[18]
procedure PreBlur; // vars[19]
procedure PreZScale; // vars[2]
procedure PreZScale; // vars[20]
procedure PreZTranslate; // vars[21]
procedure PreRotateX; // vars[22]
procedure PreRotateY; // vars[23]
@ -175,8 +179,8 @@ type
procedure Pyramid; // vars[34]
procedure Polar2; // vars[35]
function Mul33(const M1, M2: TMatrix): TMatrix;
function Identity: TMatrix;
//function Mul33(const M1, M2: TMatrix): TMatrix;
//function Identity: TMatrix;
procedure BuildFunctionlist;
procedure AddRegVariations;
@ -193,12 +197,16 @@ type
procedure NextPoint(var CPpoint: TCPpoint);
procedure NextPointTo(var CPpoint, ToPoint: TCPpoint);
procedure NextPointXY(var px, py: double);
procedure NextPoint2C(var p: T2CPoint);
//procedure NextPoint2C(var p: T2CPoint);
procedure Rotate(const degrees: double);
procedure Translate(const x, y: double);
procedure Multiply(const a, b, c, d: double);
procedure Scale(const s: double);
// AV: extended all following methods for post-coefs support
procedure Rotate(var t: TCoefsArray; const degrees: double);
procedure Translate(var t: TCoefsArray; const x, y: double);
procedure Multiply(var t: TCoefsArray; const k, l, m, n: double);
procedure Scale(var t: TCoefsArray; const s: double);
procedure RandomizeCoefs(var t: TCoefsArray); // AV: for random flames
function detC: double; inline;
function detP: double; inline;
procedure GetVariable(const name: string; var Value: double);
procedure SetVariable(const name: string; var Value: double);
@ -254,7 +262,7 @@ var i: Integer;
begin
AddRegVariations;
BuildFunctionlist;
SetLength(vars, NRLOCVAR + Length(FRegVariations));
SetLength(vars, NrVar); // <-- AV // NRLOCVAR + Length(FRegVariations));
// AV: set default variations order
ifs := TStringList.Create;
for i := 0 to NrVar-1 do ifs.Add(Varnames(i));
@ -308,6 +316,7 @@ var
CalculateAngle, CalculateSinCos, CalculateLength: boolean;
mode: double;
vn: string;
UsedVars: TStringList;
begin
c00 := c[0][0];
c01 := c[0][1];
@ -347,31 +356,33 @@ begin
// CalculateLength := False;
CalculateSinCos := (vars[8] <> 0.0) or (vars[10] <> 0.0);
UsedVars := TStringList.Create;
// Pre- variations
for i := 0 to NrVar - 1 do
for vn in ifs do
begin
v := GetVariationIndex(vn);
if (vars[v] <> 0.0) then
begin
v := GetVariationIndex(ifs[i]);
if (vars[v] <> 0.0) then
UsedVars.Add(vn); // AV: remember all used variations in the right order
if (LeftStr(vn, 4) = 'pre_') or (vn = 'flatten') then // AV: flatten became pre_
begin
vn := ifs[i];
if (LeftStr(vn, 4) = 'pre_') or (vn = 'flatten') then // AV: flatten became pre_
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
Inc(FNrFunctions);
end
// AV: added some universal variations
else if (vn = 'affine3D') or (vn = 'trianglecrop') or (vn = 'projective')
or (vn = 'spherecrop') then
begin
GetVariable(vn + '_mode', mode);
if (mode = 0) then
begin
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
Inc(FNrFunctions);
end
// AV: added some universal variations
else if (vn = 'affine3D') or (vn = 'trianglecrop')
or (vn = 'projective') or (vn = 'spherecrop') then
begin
GetVariable(vn + '_mode', mode);
if (mode = 0) then
begin
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
Inc(FNrFunctions);
end;
end;
end;
end;
end;
// Precalc must be called after pre- vars
if CalculateAngle or CalculateSinCos then
@ -386,53 +397,47 @@ begin
end;
// Normal variations
for i := 0 to NrVar - 1 do
for vn in UsedVars do // AV: iterate through used variations only
begin
v := GetVariationIndex(ifs[i]);
if (vars[v] <> 0.0) then
if (LeftStr(vn, 4) = 'pre_') or (LeftStr(vn, 5) = 'post_') or (vn = 'flatten')
then continue
else if (vn = 'affine3D') or (vn = 'trianglecrop') or (vn = 'projective')
or (vn = 'spherecrop') then
begin
vn := ifs[i];
if (LeftStr(vn, 4) = 'pre_') or
(LeftStr(vn, 5) = 'post_') or
(vn = 'flatten') then continue;
if (vn = 'affine3D') or (vn = 'trianglecrop')
or (vn = 'projective') or (vn = 'spherecrop') then
begin
GetVariable(vn + '_mode', mode);
if (mode <> 1) then continue;
end;
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
Inc(FNrFunctions);
GetVariable(vn + '_mode', mode);
if (mode <> 1) then continue;
end;
v := GetVariationIndex(vn);
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
Inc(FNrFunctions);
end;
// Post- variations
for i := 0 to NrVar - 1 do
for vn in UsedVars do // AV: iterate through used variations only
begin
v := GetVariationIndex(ifs[i]);
if (vars[v] <> 0.0) then
if (LeftStr(vn, 5) = 'post_') then
begin
v := GetVariationIndex(vn);
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
Inc(FNrFunctions);
end
// AV: added some universal variations
else if (vn = 'affine3D') or (vn = 'trianglecrop') or (vn = 'projective')
or (vn = 'spherecrop') then
begin
GetVariable(vn + '_mode', mode);
if (mode = 2) then
begin
vn := ifs[i];
if (LeftStr(vn, 5) = 'post_') then
begin
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
Inc(FNrFunctions);
end
// AV: added some universal variations
else if (vn = 'affine3D') or (vn = 'trianglecrop')
or (vn = 'projective') or (vn = 'spherecrop') then
begin
GetVariable(ifs[i] + '_mode', mode);
if (mode = 2) then
begin
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
Inc(FNrFunctions);
end;
end;
v := GetVariationIndex(vn);
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
Inc(FNrFunctions);
end;
end;
end;
UsedVars.Free;
polar_vpi := vars[6]/pi;
disc_vpi := vars[7]/pi;
polar2_vpi := vars[35]/pi;
@ -624,7 +629,7 @@ end;
procedure TXForm.Flatten;
begin
// FPz := 0;
// AV: changed to pre_mode
// AV: changed to pre_mode for compatibility with "3D-Hack" flames
FTz := 0;
end;
@ -1607,10 +1612,11 @@ begin
ToPoint.c := ToPoint.c + pluginColor * (vc - ToPoint.c);
ToPoint.x := FPx;
ToPoint.y := FPy;
ToPoint.z := FPz; //?
ToPoint.z := FPz;
end;
///////////////////////////////////////////////////////////////////////////////
(*
procedure TXForm.NextPoint2C(var p: T2CPoint);
var
i: Integer;
@ -1631,7 +1637,7 @@ begin
p.x := FPx;
p.y := FPy;
end;
*)
///////////////////////////////////////////////////////////////////////////////
procedure TXForm.NextPointXY(var px, py: double);
var
@ -1651,6 +1657,75 @@ begin
py := FPy;
end;
//************ Math utils ***************************************//
function TXForm.detC;
begin
Result := c[0,0] * c[1,1] - c[0,1] * c[1,0];
end;
function TXForm.detP;
begin
Result := p[0,0] * p[1,1] - p[0,1] * p[1,0];
end;
//************ Matrix multiplication ***************************************//
procedure TXForm.Multiply(var t: TCoefsArray; const k, l, m, n: double); // AV
var
ta, tb, tc, td: double;
begin
ta := t[0, 0];
tb := -t[1, 0];
tc := -t[0, 1];
td := t[1, 1];
{
[a, b][e ,f] [a*e+b*g, a*f+b*h]
[ ][ ] = [ ]
[c, d][g, h] [c*e+d*g, c*f+d*h]
}
t[0, 0] := ta * k + tc * l;
t[0, 1] := -(ta * m + tc * n);
t[1, 0] := -(tb * k + td * l);
t[1, 1] := tb * m + td * n;
end;
procedure TXForm.Rotate(var t: TCoefsArray; const degrees: double); // AV
var
v, sv, cv: double;
begin
v := DegToRad(degrees);
SinCos(v, sv, cv);
Multiply(t, cv, -sv, sv, cv);
end;
procedure TXForm.Scale(var t: TCoefsArray; const s: double);
begin
t[0, 0] := t[0, 0] * s;
t[0, 1] := t[0, 1] * s;
t[1, 0] := t[1, 0] * s;
t[1, 1] := t[1, 1] * s;
end;
procedure TXForm.Translate(var t: TCoefsArray; const x, y: double);
begin
t[2,0] := t[2,0] + x;
t[2,1] := t[2,1] - y; // AV: notice the sign here
end;
procedure TXForm.RandomizeCoefs(var t: TCoefsArray); // AV
begin
t[0][0] := 2 * random - 1;
t[0][1] := 2 * random - 1;
t[1][0] := 2 * random - 1;
t[1][1] := 2 * random - 1;
t[2][0] := 4 * random - 2;
t[2][1] := 4 * random - 2;
end;
(*
///////////////////////////////////////////////////////////////////////////////
{
@ -1676,7 +1751,6 @@ begin
result[2, 2] := M1[2][0] * M2[0][2] + M1[2][1] * M2[1][2] + M1[2][2] * M2[2][2]; // AV: fixed indices
end;
///////////////////////////////////////////////////////////////////////////////
function TXForm.Identity: TMatrix;
var
i, j: integer;
@ -1690,6 +1764,7 @@ begin
end;
///////////////////////////////////////////////////////////////////////////////
procedure TXForm.Rotate(const degrees: double);
var
r: double;
@ -1718,7 +1793,6 @@ begin
c[2, 1] := Matrix[1][2];
end;
///////////////////////////////////////////////////////////////////////////////
procedure TXForm.Translate(const x, y: double);
var
Matrix, M1: TMatrix;
@ -1743,7 +1817,6 @@ begin
c[2, 1] := Matrix[1][2];
end;
///////////////////////////////////////////////////////////////////////////////
procedure TXForm.Multiply(const a, b, c, d: double);
var
Matrix, M1: TMatrix;
@ -1769,7 +1842,6 @@ begin
Self.c[2, 1] := Matrix[1][2];
end;
///////////////////////////////////////////////////////////////////////////////
procedure TXForm.Scale(const s: double);
var
Matrix, M1: TMatrix;
@ -1792,7 +1864,7 @@ begin
c[2, 0] := Matrix[0][2];
c[2, 1] := Matrix[1][2];
end;
*)
///////////////////////////////////////////////////////////////////////////////
destructor TXForm.Destroy;
var
@ -1811,7 +1883,9 @@ end;
///////////////////////////////////////////////////////////////////////////////
procedure TXForm.BuildFunctionlist;
begin
SetLength(FFunctionList, NrVar + Length(FRegVariations));
// AV: why NRVAR is used here? maybe NRLOCVAR instead?
//SetLength(FFunctionList, NrVar + Length(FRegVariations));
SetLength(FFunctionList, NrVar); // <-- AV: reduced the length to actually used
//fixed
FFunctionList[0] := Linear3D;
@ -1835,7 +1909,7 @@ begin
FFunctionList[18] := Blur3D;
FFunctionList[19] := PreBlur;
FFunctionList[20] := PreZScale; // AV: index 20 is used by auto_pre_zscale option
FFunctionList[20] := PreZScale; // AV: index is used by auto-pre_zscale option
FFunctionList[21] := PreZTranslate;
FFunctionList[22] := PreRotateX;
FFunctionList[23] := PreRotateY;
@ -1922,11 +1996,11 @@ begin
result := Format(' <xform weight="%g" color="%g" ', [density, color]);
if symmetry <> 0 then result := result + format('symmetry="%g" ', [symmetry]);
////// AV: write variation order
// AV: write variation order
strvar := '';
for i := 0 to nrvar - 1 do begin
if vars[GetVariationIndex(ifs[i])] <> 0 then
strvar := strvar + ifs[i] + #32;
for Name in ifs do begin
if vars[GetVariationIndex(Name)] <> 0 then
strvar := strvar + Name + #32;
end;
if (strvar <> '') and (pos(#32, strvar) < length(strvar)) then
Result := Result + format('var_order="%s" ', [strvar]);
@ -1937,9 +2011,8 @@ begin
Result := Result + varnames(i) + format('="%g" ', [vars[i]]);
end;
*)
for i := 0 to nrvar - 1 do // AV: write in correct order
for Name in ifs do // AV: write in correct order
begin
Name := ifs[i];
Value := vars[GetVariationIndex(Name)];
if Value <> 0 then
Result := Result + Name + format('="%g" ', [Value]);
@ -1993,11 +2066,11 @@ begin
result := Format(' <finalxform color="%g" ', [color]);
if symmetry <> 0 then result := result + format('symmetry="%g" ', [symmetry]);
////// AV: write variation order
// AV: write variation order
strvar := '';
for i := 0 to nrvar - 1 do begin
if vars[GetVariationIndex(ifs[i])] <> 0 then
strvar := strvar + ifs[i] + #32;
for Name in ifs do begin
if vars[GetVariationIndex(Name)] <> 0 then
strvar := strvar + Name + #32;
end;
if (strvar <> '') and (pos(#32, strvar) < length(strvar)) then
Result := Result + format('var_order="%s" ', [strvar]);
@ -2008,9 +2081,8 @@ begin
Result := Result + varnames(i) + format('="%g" ', [vars[i]]);
end;
*)
for i := 0 to nrvar - 1 do // AV: write in correct order
for Name in ifs do // AV: write in correct order
begin
Name := ifs[i];
Value := vars[GetVariationIndex(Name)];
if Value <> 0 then
Result := Result + Name + format('="%g" ', [Value]);