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

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
@ -94,7 +94,7 @@ const
PI_2 = 1.5707963267948966192313216916398; // AV
function fmod(x, y: double) : double;
procedure SinhCosh(const v: double; var sh, ch: double); // AV
procedure SinhCosh(const v: double; var sh, ch: double); inline; // AV
implementation

View File

@ -24,6 +24,7 @@ procedure BezierSolve(t: double; src: BezierPoints; w: BezierWeights; var soluti
function BezierFunc(t: double; src: BezierPoints; w: BezierWeights): double;
implementation
procedure BezierCopy(src: BezierPoints; var tgt: BezierPoints);
var
i, n: integer;
@ -32,6 +33,7 @@ implementation
for i := 0 to n - 1 do
tgt[i] := src[i];
end;
procedure BezierSetRect(var points: BezierPoints; flip: boolean; rect: BezierRect);
var
i, n: integer;
@ -47,6 +49,7 @@ implementation
points[i].y := f * (rect.y1 - rect.y0) + rect.y0;
end;
end;
procedure BezierUnsetRect(var points: BezierPoints; flip: boolean; rect: BezierRect);
var
i, n: integer;
@ -84,6 +87,7 @@ implementation
solution.x := nom_x / denom;
solution.y := nom_y / denom;
end;
function BezierFunc(t: double; src: BezierPoints; w: BezierWeights): double;
var
p: BezierPoint;

View File

@ -2,8 +2,11 @@ unit Chaotica;
interface
uses Global, RegularExpressionsCore, RegexHelper, Classes, SysUtils, XFormMan, Windows,
ShellAPI, Forms, ControlPoint, Translation;
uses Global, RegularExpressionsCore, RegexHelper, Classes, SysUtils,
Windows, ShellAPI, ControlPoint, Translation;
const
export_flame = 'chaotica_export.flame';
function C_GetPathOf(filename: string; usex64: boolean): string;
function C_SupportsDllPlugins(usex64: boolean): boolean;
@ -12,13 +15,11 @@ function C_IsVariationNative(name: string; usex64: boolean): boolean;
function C_IsDllPluginInstalled(filename: string): boolean;
procedure C_SyncDllPlugins;
procedure C_InstallVariation(name: string);
procedure C_ExecuteChaotica(flamexml: string; plugins: TStringList; usex64: boolean);
//procedure C_InstallVariation(name: string);
implementation
uses Main;
(* // AV: rewrote and moved to Global unit
function CheckX64: Boolean;
var
@ -99,19 +100,19 @@ begin
blacklist := TStringList.Create;
if not FileExists(ChaoticaPath + '\plugin_dll_blacklist.txt') then
begin
blacklist.Add('avMobius.dll');
blacklist.Add('Cross.dll');
blacklist.Add('Epispiral.dll');
blacklist.Add('EpispiralVariationPlugin.dll');
blacklist.Add('FlowerVariationPlugin.dll');
blacklist.Add('Lissajous.dll');
blacklist.Add('Mandelbrot.dll');
blacklist.Add('ShapeVariationPlugin.dll');
blacklist.Add('slinky.dll');
blacklist.Add('Spirograph.dll');
blacklist.Add('Square.dll');
blacklist.Add('Stretchy Pants.dll');
blacklist.Add('Waffle.dll');
blacklist.Add('avMobius.dll');
blacklist.Add('Cross.dll');
blacklist.Add('Epispiral.dll');
blacklist.Add('EpispiralVariationPlugin.dll');
blacklist.Add('FlowerVariationPlugin.dll');
blacklist.Add('Lissajous.dll');
blacklist.Add('Mandelbrot.dll');
blacklist.Add('ShapeVariationPlugin.dll');
blacklist.Add('slinky.dll');
blacklist.Add('Spirograph.dll');
blacklist.Add('Square.dll');
blacklist.Add('Stretchy Pants.dll');
blacklist.Add('Waffle.dll');
blacklist.SaveToFile(ChaoticaPath + '\plugin_dll_blacklist.txt');
end;
@ -182,7 +183,7 @@ begin
end;
////////////////////////////////////////////////////////////////////
(*
procedure C_InstallVariation(name: string);
var
filename: string;
@ -195,6 +196,7 @@ begin
CopyFile(PCHAR(filename), PCHAR(C_GetPathOf('plugins\' +
ExtractFileName(filename), false)), false);
end;
*)
procedure C_SyncDllPlugins;
var
@ -243,19 +245,17 @@ var
begin
fails := TStringList.Create;
{$ifdef Apo7X64}
{$ifdef CPUX64}
fin_usex64 := true;
{$else}
fin_usex64 := usex64 and CheckX64; // currently useless...
fin_usex64 := usex64; // currently useless...
for i := 0 to plugins.Count - 1 do begin
name := GetFileNameOfVariation(plugins.Strings[i]);
if (name = '') then name := plugins.Strings[i];
name := plugins.Strings[i];
fin_usex64 := fin_usex64 and C_IsVariationNative(name, usex64);
end;
for i := 0 to plugins.Count - 1 do begin
name := GetFileNameOfVariation(plugins.Strings[i]);
if (name = '') then name := plugins.Strings[i]; // assume built-in
name := plugins.Strings[i]; // assume built-in
if not C_IsVariationNative(name, fin_usex64) then begin // not native -> try install
if C_SupportsDllPlugins(fin_usex64) then // dll unsupported -> fail
@ -271,17 +271,18 @@ begin
name := C_GetPathOf('chaotica.exe', fin_usex64);
if (not FileExists(name)) then begin
messagebox(0, PCHAR(TextByKey('main-status-nochaotica')),
PCHAR('Apophysis AV'), MB_ICONHAND);
'Apophysis AV', MB_ICONHAND);
fails.Free; // AV: fixed possible memory leak
Exit;
end;
if (fails.Count > 0) then begin
messagebox(0, PCHAR(TextByKey('main-status-oldchaotica')),
PCHAR('Apophysis AV'), MB_ICONHAND or MB_OK);
'Apophysis AV', MB_ICONHAND or MB_OK);
end;
// TODO: add directory cleaning
fname := GetEnvironmentVariable('TEMP') + '\chaotica_export.flame';
// TODO: add directory cleaning // <-- AV: done
fname := APPDATA + export_flame; // AV: moved into app folder
txt := TStringList.Create;
txt.Text := flamexml;
@ -290,11 +291,8 @@ begin
txt.Free;
fails.Free;
//if fin_usex64 then MessageBox(0, PCHAR('DBG:x64'), PCHAR(''), MB_OK)
//else MessageBox(0, PCHAR('DBG:x86'), PCHAR(''), MB_OK) ;
ShellExecute(application.handle, PChar('open'), pchar(name),
PChar('"' + fname + '"'), PChar(ExtractFilePath(name)), SW_SHOWNORMAL);
ShellExecute(0, PChar('open'), pchar(name), PChar('"' + fname + '"'),
PChar(ExtractFilePath(name)), SW_SHOWNORMAL);
end;
end.

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
@ -28,29 +28,12 @@ interface
uses
Windows, SysUtils, Classes, SyncObjs, Controls, Graphics, Math,
cmap, ControlPoint, Xform, CommDlg;
cmap, Xform, CommDlg;
type
EFormatInvalid = class(Exception);
// AV: chanded the name to avoid conflicts with XForm
TMatrix2 = array[0..1, 0..1] of double;
TFileType = (ftApo, ftXML); // AV: moved here from ControlPoint
{ Weight manipulation }
{ Triangle transformations }
function triangle_area(t: TTriangle): double;
function transform_affine(const t: TTriangle; const Triangles: TTriangles): boolean;
function line_dist(x, y, x1, y1, x2, y2: double): double;
function dist(x1, y1, x2, y2: double): double;
procedure MultMatrix(var s: TMatrix2; const m: TMatrix2);
{ Parsing functions }
function GetVal(token: string): string;
function ReplaceTabs(str: string): string;
{ Palette and gradient functions }
//function GetGradient(FileName, Entry: string): string;
{ Misc }
function det(a, b, c, d: double): double;
function solve3(x1, x2, x1h, y1, y2, y1h, z1, z2, z1h: double;
var a, b, e: double): double;
function OpenSaveFileDialog(Parent: TWinControl;
const DefExt,
Filter,
@ -63,66 +46,53 @@ function OpenSaveFileDialog(Parent: TWinControl;
DoOpen: Boolean): Boolean;
procedure LoadThumbnailPlaceholder(ThumbnailSize : integer);
function GetEnvVarValue(const VarName: string): string;
function Round6(x: double): double;
function Round6(x: double): double; inline;
function MiddleColor(const clOne, clTwo: TColor): TColor; // AV
function CheckX64: Boolean; // AV
const
APP_NAME: string = 'Apophysis AV';
APP_VERSION: string = 'Phoenix Edition';
{$ifdef Apo7X64}
{$ifdef CPUX64}
APP_BUILD: string = ' - 64 bit';
{$else}
APP_BUILD: string = ' - 32 bit';
{$endif}
MAX_TRANSFORMS: integer = 100;
prefilter_white: integer = 1024;
eps: double = 1E-10;
White_level = 200;
FT_BMP = 1; FT_PNG = 2; FT_JPG = 3;
//clyellow1 = TColor($17FCFF);
//clplum2 = TColor($ECA9E6);
//clSlateGray = TColor($837365);
// MAX_TRANSFORMS: integer = 100; // AV: why if we have NXFORMS?
// eps: double = 1E-10; // AV: this one is used nowhere
prefilter_white: integer = 1024;
White_level = 200;
//FT_BMP = 1; FT_PNG = 2; FT_JPG = 3;
const
crEditArrow = 20;
crEditMove = 21;
crEditRotate = 22;
crEditScale = 23;
const
SingleBuffer : boolean =
{$ifdef Apo7X64}
false
{$else}
true
{$endif};
var
MainSeed: integer;
MainTriangles: TTriangles; // ControlPoint.TTriangles;
Transforms: integer; // Count of Tranforms
Transforms: smallint; // Count of Tranforms
EnableFinalXform: boolean;
AppPath: string; // Path of application file
AppPath, AppData: string; // Path of application file
OpenFile: string; // Name of currently open file
CanDrawOnResize: boolean;
PreserveWeights: boolean;
CanDrawOnResize: boolean;
AlwaysCreateBlankFlame : boolean;
// StartupCheckForUpdates : boolean;
TBWidth1 : integer;
TBWidth2 : integer;
TBWidth3 : integer;
TBWidth4 : integer;
TBWidth5 : integer;
ThumbnailPlaceholder : TBitmap;
WarnOnMissingPlugin : boolean;
EmbedThumbnails : boolean;
RandomizeTemplates: boolean;
LanguageFile : string;
AvailableLanguages : TStringList;
PluginPath : string;
(*
PreserveWeights: boolean;
StartupCheckForUpdates : boolean;
EmbedThumbnails : boolean;
*)
// AV: GUI Theme Stuff
{ AV: GUI Theme Stuff }
CurrentStyle: string;
// theme-aware system colors
WinColor, BrightColor, MidColor, TextColor: TColor;
@ -132,7 +102,7 @@ var
UPRSampleDensity: integer;
UPRFilterRadius: double;
UPROversample: integer;
UPROversample: byte;
UPRAdjustDensity: boolean;
UPRColoringIdent: string;
UPRColoringFile: string;
@ -140,59 +110,58 @@ var
UPRFormulaFile: string;
UPRWidth: Integer;
UPRHeight: Integer;
ImageFolder: string;
UPRPath: string; // Name and folder of last UPR file
cmap_index: integer; // Index to current gradient
Variation: TVariation; // Current variation // ControlPoint.TVariation;
NumTries, TryLength: integer; // Settings for smooth palette
SmoothPaletteFile: string;
{ Editor }
UseFlameBackground, UseTransformColors: boolean;
HelpersEnabled: boolean;
EditorBkgColor, ReferenceTriangleColor: integer;
GridColor1, GridColor2, HelpersColor, FlipColor: integer;
EditorBkgColor, ReferenceTriangleColor: TColor;
GridColor1, GridColor2, HelpersColor, FlipColor: TColor;
ExtEditEnabled, TransformAxisLock, RebuildXaosLinks: boolean;
ShowAllXforms: boolean;
EditorPreviewTransparency: integer;
EnableEditorPreview: boolean;
AllowResetCoefs, AllowResetLinear: boolean; // AV
AllowResetCoefs, AllowResetLinear, UseTriangleSync: boolean; // AV
{ Display }
defSampleDensity, defPreviewDensity: Double;
defSampleDensity: Double;
defGamma, defBrightness, defVibrancy, defContrast, // AV
defFilterRadius, defGammaThreshold: Double;
defOversample: integer;
defOversample: byte; // integer;
FUSE: byte; // AV: moved from ControlPoint and changed to variable
RhombTR, SquareTR, HexTR: single; // AV: tile radii
cmap_index: integer; // Index to current gradient
{ Render }
renderDensity, renderFilterRadius: double;
renderOversample, renderWidth, renderHeight: integer;
// renderBitsPerSample: integer;
renderPath: string;
JPEGQuality: integer;
renderFileFormat: integer;
InternalBitsPerSample: integer;
renderFileFormat: byte; // integer;
EmbedFlame, SaveInFlame: boolean; // AV
NrTreads: Integer;
UseNrThreads: byte; // AV: currently holds Nr CPU cores
NrTreads: smallint;
UseNrThreads: smallint; // AV: currently holds Nr CPU cores
PNGTransparency: integer;
JPEGQuality: smallint;
PNGTransparency: byte; // integer;
ShowTransparency: boolean;
MainPreviewScale: double;
ExtendMainPreview: boolean;
(*
(*
renderBitsPerSample: integer;
InternalBitsPerSample: integer;
StoreEXIF : boolean;
StoreParamsEXIF : boolean;
ExifAuthor : string;
*)
*)
{ Defaults }
@ -203,27 +172,23 @@ var
ClassicListMode: boolean;
ConfirmDelete: boolean; // Flag confirmation of entry deletion
OldPaletteFormat: boolean;
ConfirmExit: boolean;
ConfirmStopRender: boolean;
ConfirmClearScript: boolean;
ConfirmExit, ConfirmStopRender: boolean;
ConfirmClearScript, ConfirmResetUndo: boolean; // AV
SavePath, SmoothPalettePath: string;
RandomPrefix, RandomDate: string;
RandomIndex: integer;
FlameFile, GradientFile, GradientEntry, FlameEntry: string;
ParamFolder: string;
prevLowQuality, prevMediumQuality, prevHighQuality: double;
defSmoothPaletteFile: string;
{ Settings for smooth palette }
SmoothPaletteFile, defSmoothPaletteFile: string;
NumTries, TryLength: integer;
ImageFolder: string;
BrowserPath: string; // Stored path of browser open dialog
EditPrevQual, MutatePrevQual, AdjustPrevQual: byte; // Integer;
ThumbPrevQual: byte; // AV
randMinTransforms, randMaxTransforms: integer;
mutantMinTransforms, mutantMaxTransforms: integer;
KeepBackground: boolean;
RandBackColor: integer; // AV
randGradient: Integer;
randGradientFile: string;
randColorBlend: byte; // AV
EqualStripes: boolean;
EditPrevQual, MutatePrevQual, AdjustPrevQual: byte; // AV: menu item index
ThumbPrevQual, AnimPrevQual: byte; // AV
defFlameFile: string;
defScriptFile: string; // AV
SetEngLayout: boolean; // AV
@ -237,9 +202,15 @@ var
ShowRenderStats, ShowRenderImage: boolean;
LowerRenderPriority: boolean;
SymmetryType: integer;
SymmetryOrder: integer;
SymmetryNVars: integer;
{ AV: Animation parameters }
AnimFPS: word;
defAnimPrefix: string;
defFrameExt: shortint;
CreateAnimFolder: boolean;
SymmetryType: shortint;
SymmetryOrder: smallint;
SymmetryNVars: word;
Variations: array of boolean;
FavouriteVariations: array of boolean;
@ -248,23 +219,38 @@ var
FlameEnumMode: byte; // AV
{ For random gradients }
MinNodes, MaxNodes, MinHue, MaxHue, MinSat, MaxSat, MinLum, MaxLum: integer;
//ReferenceMode: integer;
randGradient: shortint;
randGradientFile: string;
randColorBlend: byte; // AV
EqualStripes: boolean;
BatchSize: Integer;
// Compatibility: integer; //0 = original, 1 = Drave's
randMinTransforms, randMaxTransforms: smallint;
mutantMinTransforms, mutantMaxTransforms: smallint;
KeepBackground: boolean;
RandBackColor: TColor; // AV
{ Scripting }
Favorites: TStringList;
Script: string;
ScriptPath: string;
// SheepServer, SheepNick, SheepURL, SheepPW,
flam3Path, helpPath: string;
ExportBatches, ExportOversample, ExportWidth, ExportHeight, ExportFileFormat: Integer;
ExportFilter, ExportDensity: Double;
ExportWidth, ExportHeight: Integer;
ExportOversample, ExportFileFormat: byte; // AV
ExportFilter, ExportDensity, ExportGammaTreshold: Double;
ExportEstimator, ExportEstimatorMin, ExportEstimatorCurve: double;
ExportJitters: integer;
ExportGammaTreshold: double;
(* // AV: user cannot change them, anyway
ReferenceMode: integer;
Compatibility: integer; //0 = original, 1 = Drave's
SheepServer, SheepNick, SheepURL, SheepPW: string;
ExportBatches, ExportJitters: byte;
ResizeOnLoad: Boolean;
*)
OpenFileType: TFileType;
// ResizeOnLoad: Boolean;
ShowProgress: Boolean;
defLibrary: string;
LimitVibrancy: Boolean;
@ -275,12 +261,10 @@ var
AutoOpenLog: Boolean;
AutoSaveEnabled: Boolean;
AutoSaveFreq: integer;
AutoSaveFreq: byte;
AutoSavePath: string;
LineCenterColor : integer;
LineThirdsColor : integer;
LineGRColor : integer;
LineCenterColor, LineThirdsColor, LineGRColor : TColor;
EnableGuides : boolean;
implementation
@ -290,14 +274,12 @@ var
BufSize: Integer; // buffer size required for value
begin
// Get required buffer size (inc. terminal #0)
BufSize := GetEnvironmentVariable(
PChar(VarName), nil, 0);
BufSize := GetEnvironmentVariable(PChar(VarName), nil, 0);
if BufSize > 0 then
begin
// Read env var value into result string
SetLength(Result, BufSize - 1);
GetEnvironmentVariable(PChar(VarName),
PChar(Result), BufSize);
GetEnvironmentVariable(PChar(VarName), PChar(Result), BufSize);
end
else
// No such environment variable
@ -322,7 +304,8 @@ begin
with ThumbnailPlaceholder.Canvas do begin
Brush.Color := $000000;
FillRect(Rect(0, 0, ThumbnailPlaceholder.Width, ThumbnailPlaceholder.Height));
Draw(round(ThumbnailSize / 2 - pi_width / 2), round(ThumbnailSize / 2 - pi_height / 2), placeholderIcon);
Draw((ThumbnailSize - pi_width) shr 1, (ThumbnailSize - pi_height) shr 1,
placeholderIcon);
end;
placeholderIcon.Free;
@ -335,13 +318,6 @@ begin
((((clOne shr 16) and $ff) + ((clTwo shr 16) and $ff)) shr 1 ) shl 16;
end;
{ IFS }
function det(a, b, c, d: double): double;
begin
Result := (a * d - b * c);
end;
function Round6(x: double): double;
// Really ugly, but it works
begin
@ -351,281 +327,15 @@ begin
Result := RoundTo(x, -6);
end;
procedure MultMatrix(var s: TMatrix2; const m: TMatrix2); // AV: moved from Main
var
a, b, c, d, e, f, g, h: double;
begin
a := s[0, 0];
b := s[0, 1];
c := s[1, 0];
d := s[1, 1];
e := m[0, 0];
f := m[0, 1];
g := m[1, 0];
h := m[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]
}
s[0, 0] := a * e + b * g;
s[0, 1] := a * f + b * h;
s[1, 0] := c * e + d * g;
s[1, 1] := c * f + d * h;
end;
function solve3(x1, x2, x1h, y1, y2, y1h, z1, z2, z1h: double;
var a, b, e: double): double;
var
det1: double;
begin
det1 := x1 * det(y2, 1.0, z2, 1.0) - x2 * det(y1, 1.0, z1, 1.0)
+ 1 * det(y1, y2, z1, z2);
if (det1 = 0.0) then
begin
Result := det1;
EXIT;
end
else
begin
a := (x1h * det(y2, 1.0, z2, 1.0) - x2 * det(y1h, 1.0, z1h, 1.0)
+ 1 * det(y1h, y2, z1h, z2)) / det1;
b := (x1 * det(y1h, 1.0, z1h, 1.0) - x1h * det(y1, 1.0, z1, 1.0)
+ 1 * det(y1, y1h, z1, z1h)) / det1;
e := (x1 * det(y2, y1h, z2, z1h) - x2 * det(y1, y1h, z1, z1h)
+ x1h * det(y1, y2, z1, z2)) / det1;
a := Round6(a);
b := Round6(b);
e := Round6(e);
Result := det1;
end;
end;
function dist(x1, y1, x2, y2: double): double;
//var
// d2: double;
begin
(*
{ From FDesign source
{ float pt_pt_distance(float x1, float y1, float x2, float y2) }
d2 := (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
if (d2 = 0.0) then
begin
Result := 0.0;
exit;
end
else
Result := sqrt(d2);
*)
// --Z-- This is just amazing... :-\
// Someone needed an 'FDesign source' - to compute distance between two points??!?
Result := Hypot(x2-x1, y2-y1);
end;
function line_dist(x, y, x1, y1, x2, y2: double): double;
var
a, b, e, c: double;
begin
if ((x = x1) and (y = y1)) then
a := 0.0
else
a := sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
if ((x = x2) and (y = y2)) then
b := 0.0
else
b := sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));
if ((x1 = x2) and (y1 = y2)) then
e := 0.0
else
e := sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
if ((a * a + e * e) < (b * b)) then
Result := a
else if ((b * b + e * e) < (a * a)) then
Result := b
else if (e <> 0.0) then
begin
c := (b * b - a * a - e * e) / (-2 * e);
if ((a * a - c * c) < 0.0) then
Result := 0.0
else
Result := sqrt(a * a - c * c);
end
else
Result := a;
end;
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;
{ Parse }
function GetVal(token: string): string;
var
p: integer;
begin
p := Pos('=', token);
Delete(Token, 1, p);
Result := Token;
end;
function ReplaceTabs(str: string): string;
{Changes tab characters in a string to spaces}
var
i: integer;
begin
for i := 1 to Length(str) do
begin
if str[i] = #9 then
begin
Delete(str, i, 1);
Insert(#32, str, i);
end;
end;
Result := str;
end;
(*
{ Palette and gradient functions }
function RGBToColor(Pal: TMapPalette; index: integer): Tcolor;
begin
{ Converts the RGB values from a palette index to the TColor type ...
could maybe change it to SHLs }
Result := (Pal.Blue[index] * 65536) + (Pal.Green[index] * 256)
+ Pal.Red[index];
end;
procedure rgb2hsv(const rgb: array of double; out hsv: array of double);
var
maxval, minval: double;
del: double;
begin
Maxval := Max(rgb[0], Max(rgb[1], rgb[2]));
Minval := Min(rgb[0], Min(rgb[1], rgb[2]));
hsv[2] := maxval; // v
if (Maxval > 0) and (maxval <> minval) then begin
del := maxval - minval;
hsv[1] := del / Maxval; //s
hsv[0] := 0;
if (rgb[0] > rgb[1]) and (rgb[0] > rgb[2]) then begin
hsv[0] := (rgb[1] - rgb[2]) / del;
end else if (rgb[1] > rgb[2]) then begin
hsv[0] := 2 + (rgb[2] - rgb[0]) / del;
end else begin
hsv[0] := 4 + (rgb[0] - rgb[1]) / del;
end;
if hsv[0] < 0 then
hsv[0] := hsv[0] + 6;
end else begin
hsv[0] := 0;
hsv[1] := 0;
end;
end;
procedure hsv2rgb(const hsv: array of double; out rgb: array of double);
var
j: integer;
f, p, q, t, v: double;
begin
j := floor(hsv[0]);
f := hsv[0] - j;
v := hsv[2];
p := hsv[2] * (1 - hsv[1]);
q := hsv[2] * (1 - hsv[1] * f);
t := hsv[2] * (1 - hsv[1] * (1 - f));
case j of
0: begin rgb[0] := v; rgb[1] := t; rgb[2] := p; end;
1: begin rgb[0] := q; rgb[1] := v; rgb[2] := p; end;
2: begin rgb[0] := p; rgb[1] := v; rgb[2] := t; end;
3: begin rgb[0] := p; rgb[1] := q; rgb[2] := v; end;
4: begin rgb[0] := t; rgb[1] := p; rgb[2] := v; end;
5: begin rgb[0] := v; rgb[1] := p; rgb[2] := t; end;
end;
end;
function GetGradient(FileName, Entry: string): string;
var
FileStrings: TStringList;
GradStrings: TStringList;
i: integer;
begin
FileStrings := TStringList.Create;
GradStrings := TStringList.Create;
try
try
FileStrings.LoadFromFile(FileName);
for i := 0 to FileStrings.count - 1 do
if Pos(Entry + ' ', Trim(FileStrings[i])) = 1 then break;
GradStrings.Add(FileStrings[i]);
repeat
inc(i);
GradStrings.Add(FileStrings[i]);
until Pos('}', FileStrings[i]) <> 0;
GetGradient := GradStrings.Text;
except on exception do
Result := '';
end;
finally
GradStrings.Free;
FileStrings.Free;
end;
end;
*)
function CheckX64: Boolean; // AV
var
IsWow64Process:
function(hProcess: THandle; out Wow64Process: boolean): boolean; stdcall;
Wow64Process: boolean;
begin
{$ifdef CPUX64}
Result := True;
{$else}
IsWow64Process := GetProcAddress(GetModuleHandle('kernel32.dll'), 'IsWow64Process');
Wow64Process := False;
@ -633,6 +343,7 @@ begin
Wow64Process := IsWow64Process(GetCurrentProcess, Wow64Process) and Wow64Process;
Result := Wow64Process;
{$endif}
end;
function ReplaceStr(Str, SearchStr, ReplaceStr: string): string;
@ -650,36 +361,36 @@ var vI: Integer;
vBuffer: String;
vOn: Boolean;
begin
Result:= TStringList.Create;
vBuffer:='';
vOn:=true;
for vI:=1 to Length(fText) do
Result := TStringList.Create;
vBuffer := '';
vOn := true;
for vI := 1 to Length(fText) do
begin
if (fQuotes and(fText[vI]=fSep)and vOn)or(Not(fQuotes) and (fText[vI]=fSep)) then
if (fQuotes and(fText[vI] = fSep)and vOn)or(Not(fQuotes) and (fText[vI] = fSep)) then
begin
if fTrim then vBuffer:=Trim(vBuffer);
if vBuffer='' then vBuffer:=fSep; // !!! e.g. split(',**',',')...
if vBuffer[1]=fSep then
vBuffer:=Copy(vBuffer,2,Length(vBuffer));
if fTrim then vBuffer := Trim(vBuffer);
if vBuffer = '' then vBuffer := fSep; // !!! e.g. split(',**',',')...
if vBuffer[1] = fSep then
vBuffer := Copy(vBuffer, 2, Length(vBuffer));
Result.Add(vBuffer);
vBuffer:='';
vBuffer := '';
end;
if fQuotes then
begin
if fText[vI]='"' then
if fText[vI] = '"' then
begin
vOn:=Not(vOn);
vOn := Not(vOn);
Continue;
end;
if (fText[vI]<>fSep)or((fText[vI]=fSep)and(vOn=false)) then
vBuffer:=vBuffer+fText[vI];
if (fText[vI] <> fSep)or((fText[vI] = fSep)and(vOn = false)) then
vBuffer := vBuffer + fText[vI];
end else
if fText[vI]<>fSep then
vBuffer:=vBuffer+fText[vI];
if fText[vI] <> fSep then
vBuffer := vBuffer + fText[vI];
end;
if vBuffer<>'' then
if vBuffer <> '' then
begin
if fTrim then vBuffer:=Trim(vBuffer);
if fTrim then vBuffer := Trim(vBuffer);
Result.Add(vBuffer);
end;
end;

View File

@ -1,6 +1,6 @@
{
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
Apophysis "7X" Copyright (C) 2009-2013 Georg Kiehne
Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
}
unit Translation;
@ -13,9 +13,9 @@ procedure ListLanguages;
procedure LanguageInfo(path: string; var name, localName: string);
function LanguageAuthor(path: string): string;
procedure Add(key, value: string);
procedure LoadLanguage(path:string);
procedure LoadLanguage(path: string);
procedure LoadEnglish();
function TextByKey(key:string):string;
function TextByKey(key: string):string;
type
TParser = class
@ -121,6 +121,7 @@ begin
Add('common-keepaspect', 'Maintain aspect ratio');
Add('common-destination', 'Destination');
Add('common-filename', 'File name');
Add('common-comment', 'Comment');
Add('common-browse', 'Browse...');
Add('common-quality', 'Quality');
Add('common-filterradius', 'Filter Radius');
@ -155,7 +156,7 @@ begin
Add('common-invalidformat', 'Invalid format.');
Add('common-confirmexit', 'Do you really want to exit? All unsaved data will be lost!');
Add('common-confirmdelete', 'Are you sure you want to permanently delete "%s"? ');
Add('common-confirmrename', 'After renaming "%s", all changes made to this flame can be lost. Do you want to continue?');
Add('common-confirmselect', 'After new selection, all changes made to the current flame will be lost. Do you want to save its editing history?');
Add('common-deletecurrent', 'All changes made to the current flame will be lost!');
Add('common-dragpanelhint', 'Click and drag to change value');
Add('common-trace-title', 'Trace log');
@ -198,12 +199,13 @@ begin
Add('common-filter-templatefiles', 'Apophysis Template Library (*.template;*.flame)');
Add('common-filter-undofiles', 'Apophysis Undo Parameters (*.undo;*.apo)');
Add('common-filter-scriptfiles', 'Apophysis Script (*.aposcript;*.asc)');
Add('common-filter-allimages', 'All images (*.bmp;*.dib;*.jpg;*.jpeg)');
Add('common-filter-allimages', 'All images (*.bmp;*.dib;*.jpg;*.jpeg;*.png)');
Add('common-filter-bitmap', 'Windows Bitmap (*.bmp;*.dib)');
Add('common-filter-jpeg', 'JPEG (*.jpg;*.jpeg)');
Add('common-filter-png', 'Portable Network Graphics (*.png)');
Add('common-filter-allfiles', 'All files (*.*)');
Add('common-open-apoimage', 'Import Apophysis parameters from the image...');
Add('common-selectimage', 'Select an image file...');
Add('common-favscriptadded', 'The script "%s" was added to your favourites list.');
Add('common-favscriptexists', 'The script "%s" already exists in your favourites list.');
Add('common-screenshot-saved', 'The screenshot "%s" was successfully saved in "%s" directory.');
@ -246,6 +248,7 @@ begin
Add('adjustment-tab-camera-ypos', 'Y-Position');
Add('adjustment-tab-camera-rotation', 'Rotation');
Add('adjustment-tab-camera-resetzoom', 'Reset zoom'); // AV
Add('adjustment-tab-camera-draw3daxes', 'Display coordinate axes in 3D-space'); // AV
Add('adjustment-tab-rendering-title', 'Rendering');
Add('adjustment-tab-rendering-istransparent', 'Transparent');
Add('adjustment-tab-gradient-title', 'Gradient');
@ -309,8 +312,9 @@ begin
Add('adjustment-popup-gradient-smooth', 'Smooth Palette...');
Add('adjustment-popup-gradient-browser', 'Gradient Browser...');
Add('adjustment-popup-gradient-saveasugr', 'Save Gradient...');
Add('adjustment-popup-gradient-saveasmap', 'Save as Map File...');
Add('adjustment-popup-gradient-saveasmap', 'Save as Map file...');
Add('adjustment-popup-gradient-saveasdefault', 'Save as default');
Add('adjustment-popup-gradient-saveasscript', 'Save as script file...');
Add('adjustment-popup-gradient-adjustfragment', 'Adjust color fragment...');
Add('editor-title', 'Transform Editor');
Add('editor-common-transform', 'Transform:');
@ -319,15 +323,19 @@ begin
Add('editor-common-finalxformlistitem', 'Final');
Add('editor-common-fromprefix', 'from %d');
Add('editor-common-toprefix', 'to %d');
Add('editor-common-editcomment', 'Edit flame comment...');
Add('editor-tab-variations-title', 'Variations');
Add('editor-tab-variations-name', 'Name');
Add('editor-tab-variations-value', 'Value');
Add('editor-tab-variations-search', 'Search:'); // AV
Add('editor-tab-variations-searchhint', 'Type a variation name...'); // AV
Add('editor-tab-variations-order', 'Edit the Order...'); // AV
Add('editor-tab-variations-orderhint', 'Adjust the order of variations for the chosen transform'); // AV
Add('editor-tab-variations-togglehideunused', ' Hide unused variations');
Add('editor-tab-variations-toggleshowall', ' Show all variations'); // AV
Add('editor-tab-variations-togglefavourites', ' Favourite variations'); // AV
Add('editor-tab-variations-toggle3d', ' 3D-aware variations'); // AV
Add('editor-tab-variations-toggledc', ' Direct coloring variations'); // AV
Add('editor-tab-variables-title', 'Variables');
Add('editor-tab-variables-name', 'Name');
Add('editor-tab-variables-value', 'Value');
@ -369,10 +377,13 @@ begin
Add('editor-tab-triangle-transformshint', ' Hotkey A - apply to all vectors, hotkey X - apply to OX-vector only, hotkey Y - apply to OY-vector only, hotkey O - apply to O-vector only');
Add('editor-tab-triangle-coordinates', 'Coordinates');
Add('editor-tab-triangle-menuhint', 'Adjust the transformation tools...');
Add('editor-tab-triangle-syncall', 'Apply operations to all triangles');
Add('editor-tab-triangle-pivot1x', 'Pivot point abscissa in the chosen coordinate system');
Add('editor-tab-triangle-pivot1y', 'Pivot point ordinate in the chosen coordinate system');
Add('editor-tab-triangle-pivot2x', 'Second point abscissa in the chosen coordinate system');
Add('editor-tab-triangle-pivot2y', 'Second point ordinate in the chosen coordinate system');
Add('editor-tab-triangle-enablesync', 'Synchronize operations for selected triangles');
Add('editor-tab-triangle-disablesync', 'Synchronization for triangles disabled');
Add('editor-tab-transform-title', 'Transform');
Add('editor-tab-transform-reset', 'Reset transform');
Add('editor-tab-transform-resethint', 'Reset all vectors to default position');
@ -445,7 +456,9 @@ begin
Add('editor-toolbar-calcsin', 'Calculate sine of the value');
Add('editor-toolbar-calctan', 'Calculate tangent of the value');
Add('editor-toolbar-usedegrees', 'Use degrees');
Add('editor-toolbar-calcexpression', 'Calculate math expression...');
Add('editor-toolbar-showchaos', 'Show chaotic transitions structure...');
Add('editor-toolbar-savestate', 'Save current flame into the opened file');
Add('editor-popup-panel-autozoom', 'Zoom automatically');
Add('editor-popup-panel-toggleextendededit', 'Toggle extended edit mode');
Add('editor-popup-panel-locktransformaxes', 'Lock transform axes');
@ -459,8 +472,10 @@ begin
Add('editor-popup-transform-resetflip', 'Reset reflection');
Add('editor-popup-transform-copycoords', 'Copy triangle coordinates');
Add('editor-popup-transform-pastecoords', 'Paste triangle coordinates');
Add('editor-popup-transform-copywhole', 'Copy whole transform');
Add('editor-popup-transform-copywhole', 'Copy selected transform(s)');
Add('editor-popup-transform-pastewhole', 'Paste transform(s)');
Add('editor-popup-transform-copyvars', 'Copy variations with parameters');
Add('editor-popup-transform-pastevars', 'Paste variations and parameters');
Add('editor-popup-transform-resetentiretriangle', 'Reset triangle');
Add('editor-popup-chaos-rebuildlinks', 'Rebuild chaos links');
Add('editor-popup-chaos-clearall', 'Clear all current modifiers (reset to zero)');
@ -475,6 +490,8 @@ begin
Add('editor-popup-chaos-container', 'Add container transform');
Add('editor-popup-chaos-keepweight', 'Inherit original weights');
Add('editor-popup-chaos-invert', 'Invert current settings');
Add('editor-popup-chaos-copy', 'Copy current weight modifiers');
Add('editor-popup-chaos-paste', 'Apply saved modifiers to transform(s)');
Add('editor-popup-triangle-rotateall', 'Rotate all vectors');
Add('editor-popup-triangle-rotatex', 'Rotate only X-axis');
Add('editor-popup-triangle-rotatey', 'Rotate only Y-axis');
@ -488,7 +505,6 @@ begin
Add('editor-popup-triangle-invertstep', 'Invert current Move step');
Add('editor-popup-triangle-arcsin', 'Calculate arcsin of the scale factor');
Add('editor-popup-triangle-display', 'Display internally modified values');
// Add('editor-status-zoomformat', 'Zoom: %f');
Add('editor-status-xformat', 'X: %f');
Add('editor-status-yformat', 'Y: %f');
Add('editor-status-rotateformat', 'Rotate: %3.2f° Inner angle: %3.2f°');
@ -506,6 +522,7 @@ begin
Add('editor-status-warnscale', 'Current scale factor is out of range! The value inserted into the "Scale" field must be less than 100 percents.');
Add('editor-status-warninvert', 'The affine determinant is too small for this operation.');
Add('editor-status-nonumfield', 'No active numeric field found. Please select a numeric field before opening the menu.');
Add('editor-status-formula', 'Type the math formula: ');
Add('export-title', 'Export to flam3');
Add('export-paramoptions-title', 'Parameter options');
Add('export-paramoptions-bufferdepth', 'Buffer depth');
@ -531,7 +548,7 @@ begin
Add('postprocess-title', 'Post-process render');
Add('postprocess-save', 'Save');
Add('postprocess-fittowindow', 'Fit to window');
Add('render-title', 'Render flame');
Add('render-title', 'Render flame to disk');
Add('render-common-gotofolder', 'Open target folder...');
Add('render-tab-settings-title', 'Settings');
Add('render-tab-output-title', 'Output');
@ -587,8 +604,10 @@ begin
Add('render-status-log-largepng-message2', 'PNG format with extreme high-resolution images is not recommended!');
Add('render-status-log-largepng-message3', 'To avoid slowdown (and possible memory problems) use BMP file format instead.');
Add('render-status-confirmstop', 'Do you want to stop the current render?');
Add('render-status-stop', 'Cancel current rendering');
Add('render-status-dosnapshot', 'Do snapshot');
Add('render-status-dosnapshothint', 'Save current state as a picture');
Add('render-status-showimage', 'Show the image state...');
Add('messages-title', 'Messages');
Add('messages-openautomatically', 'Automatically open this window');
Add('mutation-title', 'Mutation');
@ -609,12 +628,15 @@ begin
Add('options-tab-general-bufferdepth', 'Buffer depth ');
Add('options-tab-general-jpegquality', 'JPEG quality ');
Add('options-tab-general-pngtransparency', 'PNG transparency ');
Add('options-tab-general-notifications', 'Notifications');
Add('options-tab-general-defaults', 'Defaults');
Add('options-tab-general-showextendedstatistics', 'Show extended render statistics ');
Add('options-tab-general-showrenderimage', 'Show the rendered image ');
Add('options-tab-general-confirmdelete', 'Confirm deleting flames ');
Add('options-tab-general-confirmexit', 'Confirm exit ');
Add('options-tab-general-confirmrenderstop', 'Confirm stop rendering ');
Add('options-tab-general-confirmclearscript', 'Confirm clear script ');
Add('options-tab-general-confirmresetundo', 'Confirm reset editing history ');
Add('options-tab-general-oldgradientformat', 'Use old gradient format ');
Add('options-tab-general-templaterandcolor', 'Randomize gradient for templates ');
Add('options-tab-general-alwaysblankflame', 'Disable templates ');
@ -641,6 +663,7 @@ begin
Add('options-tab-general-playsound', 'Play sound ');
Add('options-tab-general-soundfile', 'Sound file: ');
Add('options-tab-general-playhint', 'Play');
Add('options-tab-general-createanimdir', 'Create a new folder for frames');
Add('options-tab-general-autoflatten', 'Apply flattening to old flames');
Add('options-tab-general-pluginpath', 'Plugin folder ');
Add('options-tab-editor-title', 'Editor ');
@ -660,6 +683,7 @@ begin
Add('options-tab-editor-previewtransparency', 'Transparency');
Add('options-tab-editor-resetcoefs', 'Reset affine values by double-click');
Add('options-tab-editor-resetlinear', 'Reset linear when other variation is set');
Add('options-tab-editor-synctriangles', 'Allow synchronize triangles');
Add('options-tab-display-title', 'Display ');
Add('options-tab-display-rendering', 'Rendering ');
Add('options-tab-display-previewdensity', 'Preview density ');
@ -852,6 +876,7 @@ begin
Add('main-menu-view-imagesize', 'Image size');
Add('main-menu-view-messages', 'Messages');
Add('main-menu-view-curves', 'Curves');
Add('main-menu-view-animator', 'Animator');
Add('main-menu-flame-title', 'Flame');
Add('main-menu-flame-reset', 'Reset location');
Add('main-menu-flame-randomize', 'Randomize all parameters');
@ -972,6 +997,7 @@ begin
Add('main-toolbar-mutation', 'Mutation | Show randomly generated modifications of the current flame');
Add('main-toolbar-quality', 'Rendering quality | Set flame quality (density) for the main preview window');
Add('main-toolbar-imagesize', 'Image size | Change the image size');
Add('main-toolbar-animator', 'Animator | Show animation editor');
Add('main-toolbar-messages', 'Messages | Show error messages');
Add('main-toolbar-options', 'Settings | Change Apophysis default settings');
Add('main-toolbar-editscript', 'Edit script | Edit the script code');
@ -1006,6 +1032,49 @@ begin
Add('varorder-byindex', 'Default order');
Add('varorder-byindexhint', 'Restore the default variation order in Transform Editor');
Add('varorder-noselected', 'Active variation not found. Please, select the variation to move.');
Add('formula-wrongargscount', 'Invalid number of arguments to %s: expected %d, received %d.');
Add('formula-wrongdatatype', 'The parameter must be a number.');
Add('formula-outofrange', 'The value must be in range [-1, 1].');
Add('formula-unsigned', 'The value must be positive.');
Add('formula-cannotevaluate', 'Cannot evaluate the mathematical expression.');
Add('animate-title', 'Animate flame');
Add('animate-general', 'General');
Add('animate-animation', 'Animation');
Add('animate-output', 'Output settings');
Add('animate-duration', 'Duration');
Add('animate-fps', 'Frames per second');
Add('animate-parameters', 'Animation parameters');
Add('animate-outflame', 'Output flame file');
Add('animate-prefix', 'Name prefix');
Add('animate-frame', 'Frame');
Add('animate-preview', 'Animation preview');
Add('animate-save', 'Save');
Add('animate-stop', 'Stop');
Add('animate-playhint', 'Play animation');
Add('animate-stophint', 'Stop current animation');
Add('animate-type', 'Animation type');
Add('animate-showframes', 'Show generated frames');
Add('animate-currentflame', ' (Current flame)');
Add('animate-status-generating', 'Generating frame %d of %d...');
Add('animate-status-finished', 'Frame generation finished.');
Add('animate-status-changeflame', 'Initial and final frames must be different.');
Add('animate-status-stopped', 'Frame generation is interrupted.');
Add('animate-kind-rotateflame', 'Rotate flame');
Add('animate-kind-rotatereference', 'Rotate reference triangle');
Add('animate-kind-rotatehue', 'Change gradient hue');
Add('animate-kind-rotatepalette', 'Rotate color gradient');
Add('animate-kind-rotatecamera', 'Rotate 3D camera');
Add('animate-kind-morph1', 'Morphing (interpolation: cosine, RGB)');
Add('animate-kind-morph2', 'Morphing (interpolation: cosine, HSV)');
Add('animate-kind-morph3', 'Morphing (interpolation: linear, RGB)');
Add('animate-kind-morph4', 'Morphing (interpolation: linear, HSV)');
Add('animate-render', 'Render all frames after generation');
Add('animate-resetlocation', 'Calculate flame location for each frame');
Add('animate-graphicext', 'Graphic extension');
Add('animate-initflame', 'Initial flame');
Add('animate-finalflame', 'Initial flame');
Add('animate-savehint', 'Save all animated frames to hard disk');
Add('animate-invertbg', 'Invert background color');
end;
procedure Add(key, value: string);
@ -1087,6 +1156,7 @@ begin
self.parentTagnames.Add(self.currentTagname);
self.currentTagname := TagName;
end;
procedure TParser.ListXmlScannerEndTag(Sender: TObject; TagName: string);
var lastIndex : integer;
begin
@ -1116,7 +1186,7 @@ procedure TParser.ListXmlScannerContent(Sender: TObject; Content: string);
const root: string = 'stringtable';
var key, tn: string; i: integer;
begin
for i:=0 to self.parentTagnames.Count - 1 do begin
for i := 0 to self.parentTagnames.Count - 1 do begin
tn := self.parentTagnames.Strings[i];
if not (tn = '') and not (tn = root) then key := key + tn + '-';
end;

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
@ -27,19 +27,13 @@ unit XFormMan;
interface
uses
BaseVariation, SysUtils, Forms, Windows;
BaseVariation, SysUtils, System.Generics.Collections;
const
NRLOCVAR = 36;
var
NumBuiltinVars: integer;
type
TFNToVN = record
FileName: string;
VarName: string;
end;
function NrVar: integer;
function Varnames(const index: integer): String;
procedure RegisterVariation(Variation: TVariationLoader; supports3D, supportsDC : boolean);
@ -49,11 +43,9 @@ function GetNrVariableNames: integer;
function GetVariableNameAt(const Index: integer): string;
function GetVariationIndex(const str: string): integer;
function GetVariationIndexFromVariableNameIndex(const Index: integer): integer;
procedure VarSupports(index : integer; var supports3D : boolean; var supportsDC : boolean);
procedure InitializeXFormMan;
procedure DestroyXFormMan;
procedure RegisterVariationFile(filename, name: string);
function GetFileNameOfVariation(name: string): string;
function VarSupports3D(index: smallint): boolean; // AV
function VarSupportsDC(index: smallint): boolean; // AV
procedure FillVarNamesList; // AV
implementation
@ -61,23 +53,22 @@ uses
Classes;
var
VariationList: TList;
VariableNames: TStringlist;
loaderNum : integer;
VariationList: TList<TVariationLoader>; // AV: changed to generic type
VariationNames: TStringList; // AV
VariableNames: TStringList;
Variable2VariationIndex : array of integer;
FNToVNList : array of TFNToVN;
FNToVNCount: integer;
Vars3D: array of boolean;
VarsDC: array of boolean;
procedure InitializeXFormMan;
begin
VariationList := TList.Create;
VariableNames := TStringlist.create;
VariationList := TList<TVariationLoader>.Create; // AV: changed to generic type
VariationNames := TStringList.Create; // AV
VariableNames := TStringList.create;
SetLength(Variable2VariationIndex,0);
SetLength(FNToVNList, 0);
FNToVNCount := 0;
end;
procedure VarSupports(index : integer; var supports3D : boolean; var supportsDC : boolean);
procedure FillVarsSupport; // AV
const
supports3D_arr: array[0..NRLOCVAR-1] of boolean = (
true, //'linear',
@ -162,38 +153,50 @@ const
false, //'pyramid'
false // polar2
);
var
varl : TVariationLoader;
var i: word;
begin
if (index >= NRLOCVAR) then begin
supports3D := TVariationLoader(VariationList.Items[index - NRLOCVAR]).supports3D;
supportsDC := TVariationLoader(VariationList.Items[index - NRLOCVAR]).supportsDC;
end else begin
supports3D := supports3D_arr[index];
supportsDC := supportsDC_arr[index];
SetLength(Vars3D, VariationNames.Count);
SetLength(VarsDC, VariationNames.Count);
for i := 0 to NRLOCVAR-1 do
begin
Vars3D[i] := supports3D_arr[i];
VarsDC[i] := supportsDC_arr[i];
end;
for i := 0 to VariationList.Count - 1 do
begin
Vars3D[i + NRLOCVAR] := VariationList[i].Supports3D;
VarsDC[i + NRLOCVAR] := VariationList[i].SupportsDC;
end;
end;
function VarSupports3D(index: smallint): boolean;
begin
Result := Vars3D[index]; // AV: added precalc
end;
function VarSupportsDC(index: smallint): boolean;
begin
Result := VarsDC[index]; // AV: added precalc
end;
{ ///////////////////////////////////////////////////////////////////////// }
procedure DestroyXFormMan;
var i: integer;
begin
VariationNames.Free; // AV
VariableNames.Free;
// The registered variation loaders are owned here, so we must free them.
for i := 0 to VariationList.Count-1 do
TVariationLoader(VariationList[i]).Free;
VariationList[i].Free;
VariationList.Free;
Finalize(Variable2VariationIndex);
Finalize(FNToVNList);
end;
///////////////////////////////////////////////////////////////////////////////
function NrVar: integer;
function NrVar: integer; // AV: reduce Nr of calc since we use it thousand times
begin
Result := NRLOCVAR + VariationList.Count;
Result := VariationNames.Count; // NRLOCVAR + VariationList.Count;
end;
///////////////////////////////////////////////////////////////////////////////
@ -206,7 +209,9 @@ begin
Result := Variable2VariationIndex[Index];
end;
function Varnames(const index: integer): String;
{ ////////////////////////////////////////////////////////////////////////// }
procedure FillVarNamesList; // AV: this method used once at startup
const
cvarnames: array[0..NRLOCVAR-1] of string = (
'linear',
@ -216,23 +221,10 @@ const
'swirl',
'horseshoe',
'polar',
// 'handkerchief',
// 'heart',
'disc',
'spiral',
'hyperbolic',
'diamond',
// 'ex',
// 'julia',
// 'bent',
// 'waves',
// 'fisheye',
// 'popcorn',
// 'exponential',
// 'power',
// 'cosine',
// 'rings',
// 'fan',
'eyefish',
'bubble',
'cylinder',
@ -241,48 +233,51 @@ const
'gaussian_blur',
'zblur',
'blur3D',
'pre_blur',
'pre_zscale',
'pre_ztranslate',
'pre_rotate_x',
'pre_rotate_y',
'zscale',
'ztranslate',
'zcone',
'post_rotate_x',
'post_rotate_y',
'post_mirror_x',
'post_mirror_y',
'post_mirror_z',
'hemisphere',
'cross',
'pyramid',
'polar2'
);
var i: integer;
begin
if Index < NRLOCVAR then
Result := cvarnames[Index]
for i := 0 to High(cvarnames) do
VariationNames.Add(cvarnames[i]);
for i := 0 to VariationList.Count - 1 do
VariationNames.Add(VariationList[i].GetName);
VariationList.TrimExcess;
FillVarsSupport; // 3D and DC
end;
function Varnames(const index: integer): string; // AV: totally rewritten
begin
if (index >= 0) and (index < VariationNames.Count) then
Result := VariationNames[index]
else
Result := TVariationLoader(VariationList[Index - NRLOCVAR]).GetName;
Result := '';
end;
///////////////////////////////////////////////////////////////////////////////
function GetVariationIndex(const str: string): integer;
var
i: integer;
function GetVariationIndex(const str: string): integer; // AV: totally rewritten
begin
i := NRVAR-1;
while (i >= 0) and (Varnames(i) <> str) do Dec(i);
Result := i;
Result := VariationNames.IndexOf(str);
end;
///////////////////////////////////////////////////////////////////////////////
(*
procedure RegisterVariationFile(filename, name: string);
begin
FNToVNCount := FNToVNCount + 1;
@ -302,13 +297,14 @@ begin
end;
Result := '';
end;
*)
procedure RegisterVariation(Variation: TVariationLoader; supports3D, supportsDC : boolean);
var
i: integer;
prevNumVariables:integer;
begin
OutputDebugString(PChar(Variation.GetName));
// OutputDebugString(PChar(Variation.GetName));
VariationList.Add(Variation);
Variation.Supports3D := supports3D;
@ -318,7 +314,7 @@ begin
setLength(Variable2VariationIndex, prevNumVariables + Variation.GetNrVariables);
for i := 0 to Variation.GetNrVariables - 1 do begin
VariableNames.Add(Variation.GetVariableNameAt(i));
Variable2VariationIndex[prevNumVariables + i] := NrVar-1;
Variable2VariationIndex[prevNumVariables + i] := NRLOCVAR + VariationList.Count - 1; //NrVar-1;
end;
end;
@ -331,7 +327,8 @@ end;
///////////////////////////////////////////////////////////////////////////////
function GetRegisteredVariation(const Index: integer): TVariationLoader;
begin
Result := TVariationLoader(VariationList[Index]);
// AV: no more unsafe type casting here since we use generics!
Result := VariationList[Index];
end;
///////////////////////////////////////////////////////////////////////////////