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

@ -2,7 +2,8 @@
Apophysis Copyright (C) 2001-2004 Mark Townsend
Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
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
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
@ -29,14 +30,12 @@ uses
Vcl.Themes,
Vcl.Styles,
Binary in 'IO\Binary.pas',
Base64 in 'IO\Base64.pas',
sdStringTable in 'System\sdStringTable.pas',
CustomDrawControl in 'System\CustomDrawControl.pas',
LibXmlComps in 'System\LibXmlComps.pas',
LibXmlParser in 'System\LibXmlParser.pas',
LibXmlComps in 'System\LibXmlComps.pas',
CustomDrawControl in 'System\CustomDrawControl.pas',
RegexHelper in 'System\RegexHelper.pas',
CurvesControl in 'System\CurvesControl.pas',
{$ifndef Apo7X64}
{$ifndef CPUX64}
AsmRandom in 'System\AsmRandom.pas',
{$endif }
Global in 'Core\Global.pas',
@ -60,6 +59,7 @@ uses
BucketFillerThread in 'Rendering\BucketFillerThread.pas',
RenderThread in 'Rendering\RenderThread.pas',
ImageMaker in 'Rendering\ImageMaker.pas',
MathExpressions in 'System\MathExpressions.pas',
varSinusoidal in 'Variations\varSinusoidal.pas',
varLog in 'Variations\varLog.pas',
varModulus in 'Variations\varModulus.pas',
@ -131,6 +131,7 @@ uses
varPreCircleCrop in 'Variations\varPreCircleCrop.pas',
varPreCrop in 'Variations\varPreCrop.pas',
varPreFalloff2 in 'Variations\varPreFalloff2.pas',
varPreMobius in 'Variations\varPreMobius.pas',
varPostBoarders2 in 'Variations\varPostBoarders2.pas',
varPostBwraps in 'Variations\varPostBwraps.pas',
varPostCurl in 'Variations\varPostCurl.pas',
@ -138,6 +139,7 @@ uses
varPostCircleCrop in 'Variations\varPostCircleCrop.pas',
varPostCrop in 'Variations\varPostCrop.pas',
varPostFalloff2 in 'Variations\varPostFalloff2.pas',
varPostMobius in 'Variations\varPostMobius.pas',
varPostSpherical in 'Variations\varPostSpherical.pas',
varPostSinusoidal in 'Variations\varPostSinusoidal.pas',
varProjective in 'Variations\varProjective.pas',
@ -178,30 +180,29 @@ uses
SavePreset in 'Forms\SavePreset.pas' {SavePresetForm},
SplashForm in 'Forms\SplashForm.pas' {SplashWindow},
Template in 'Forms\Template.pas' {TemplateForm},
Curves in 'Forms\Curves.pas' {CurvesForm},
Preview in 'Forms\Preview.pas' {PreviewForm},
FormFavorites in 'Forms\FormFavorites.pas' {FavoritesForm},
ScriptForm in 'Forms\ScriptForm.pas' {ScriptEditor},
ScriptRender in 'Forms\ScriptRender.pas' {ScriptRenderForm},
ColorRangeForm in 'Forms\ColorRangeForm.pas' {ColorSelection},
Chaos in 'Forms\Chaos.pas' {ChaosForm},
VarOrderForm in 'Forms\VarOrderForm.pas' {VarOrder};
VarOrderForm in 'Forms\VarOrderForm.pas' {VarOrder},
Animate in 'Forms\Animate.pas' {AnimateForm},
FlameComment in 'Forms\FlameComment.pas' {CommentForm};
{$R *.res}
{$R Apophysis.res}
{$R Apophysis.res}
begin
ReportMemoryLeaksOnShutdown := true;
InitializePlugins;
SplashWindow := TSplashWindow.Create(Application);
SplashWindow.Show;
Application.Initialize;
SplashWindow.Update;
{$ifdef Apo7X64}
{$ifdef CPUX64}
Application.Title := 'Apophysis AV (64 bit)';
{$else}
Application.Title := 'Apophysis AV (32 bit)';
@ -222,7 +223,6 @@ begin
Application.CreateForm(TSaveForm, SaveForm);
Application.CreateForm(TSavePresetForm, SavePresetForm);
Application.CreateForm(TTemplateForm, TemplateForm);
Application.CreateForm(TCurvesForm, CurvesForm);
Application.CreateForm(TPreviewForm, PreviewForm);
Application.CreateForm(TFavoritesForm, FavoritesForm);
Application.CreateForm(TScriptEditor, ScriptEditor);
@ -230,6 +230,8 @@ begin
Application.CreateForm(TColorSelection, ColorSelection);
Application.CreateForm(TChaosForm, ChaosForm);
Application.CreateForm(TVarOrder, VarOrder);
Application.CreateForm(TAnimateForm, AnimateForm);
Application.CreateForm(TCommentForm, CommentForm);
Application.UpdateFormatSettings := False;
FormatSettings.DecimalSeparator := '.';
Application.Run;

View File

@ -8,7 +8,7 @@
<AppType>Application</AppType>
<FrameworkType>VCL</FrameworkType>
<ProjectVersion>18.8</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<Platform Condition="'$(Platform)'==''">Win64</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
@ -58,7 +58,7 @@
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=IFS Fractal Generator;FileVersion=1.0.1.0;InternalName=Apophysis;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis Phoenix Edition;ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.1.0</VerInfo_Keys>
<VerInfo_Keys>CompanyName=;FileDescription=IFS Fractal Generator;FileVersion=1.0.2.0;InternalName=Apophysis;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis Phoenix Edition;ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.2.0</VerInfo_Keys>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<Icon_MainIcon>ApophysisAV_Icon2.ico</Icon_MainIcon>
<DCC_IOChecking>false</DCC_IOChecking>
@ -86,7 +86,7 @@
<SanitizedProjectName>ApophysisAV</SanitizedProjectName>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<Custom_Styles>&quot;Cyan Night|VCLSTYLE|$(BDSCOMMONDIR)\Styles\CyanNight.vsf&quot;;&quot;Ruby Graphite|VCLSTYLE|$(BDSCOMMONDIR)\Styles\RubyGraphite.vsf&quot;</Custom_Styles>
<VerInfo_Release>1</VerInfo_Release>
<VerInfo_Release>2</VerInfo_Release>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_ExeOutput>..\..\Out\x86\</DCC_ExeOutput>
@ -95,7 +95,7 @@
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
<VerInfo_Keys>CompanyName=;FileDescription=IFS Fractal Editor;FileVersion=1.0.1.0;InternalName=Apophysis;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis AV &quot;Phoenix Edition&quot;;ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.1.0</VerInfo_Keys>
<VerInfo_Keys>CompanyName=;FileDescription=IFS Fractal Editor;FileVersion=1.0.2.0;InternalName=Apophysis;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis AV &quot;Phoenix Edition&quot;;ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.2.0</VerInfo_Keys>
<Icon_MainIcon>ApophysisAV_Icon.ico</Icon_MainIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
@ -105,7 +105,7 @@
<DCC_Namespace>Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
<VerInfo_Keys>CompanyName=;FileDescription=IFS Fractal Editor;FileVersion=1.0.1.0;InternalName=Apophysis;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis AV &quot;Phoenix Edition&quot;;ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.1.0</VerInfo_Keys>
<VerInfo_Keys>CompanyName=;FileDescription=IFS Fractal Editor;FileVersion=1.0.2.0;InternalName=Apophysis;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis AV &quot;Phoenix Edition&quot;;ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.2.0</VerInfo_Keys>
<Icon_MainIcon>ApophysisAV_Icon.ico</Icon_MainIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
@ -115,14 +115,14 @@
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<VerInfo_Keys>CompanyName=Alice V., Apophysis Developers;FileDescription=RIFS Fractal Editor;FileVersion=1.0.1.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV.exe;ProductName=Apophysis AV &quot;Phoenix Edition&quot;;ProductVersion=1.0.1.0</VerInfo_Keys>
<VerInfo_Keys>CompanyName=Alice V., Apophysis Developers;FileDescription=RIFS Fractal Editor;FileVersion=1.0.2.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV.exe;ProductName=Apophysis AV &quot;Phoenix Edition&quot;;ProductVersion=1.0.2.0</VerInfo_Keys>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<BT_BuildType>Debug</BT_BuildType>
<Icon_MainIcon>ApophysisAV_Icon.ico</Icon_MainIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<VerInfo_Keys>CompanyName=Alice V., Apophysis Developers;FileDescription=RIFS Fractal Editor;FileVersion=1.0.1.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV_64.exe;ProductName=Apophysis AV &quot;Phoenix Edition&quot;;ProductVersion=1.0.1.0</VerInfo_Keys>
<VerInfo_Keys>CompanyName=Alice V., Apophysis Developers;FileDescription=RIFS Fractal Editor;FileVersion=1.0.2.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV_64.exe;ProductName=Apophysis AV &quot;Phoenix Edition&quot;;ProductVersion=1.0.2.0</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<Icon_MainIcon>ApophysisAV_Icon.ico</Icon_MainIcon>
</PropertyGroup>
@ -130,13 +130,13 @@
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<VerInfo_Keys>CompanyName=;FileDescription=IFS Fractal Editor;FileVersion=1.0.1.0;InternalName=ApophysisAV;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis AV &quot;Phoenix Edition&quot;;ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.1.0</VerInfo_Keys>
<VerInfo_Keys>CompanyName=;FileDescription=IFS Fractal Editor;FileVersion=1.0.2.0;InternalName=ApophysisAV;LegalCopyright=Alice Koryagina;LegalTrademarks=;OriginalFilename=Apophysis AV &quot;Phoenix Edition&quot;;ProductName=Apophysis Phoenix Edition;ProductVersion=1.0.2.0</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=Apophysis Developers Team;FileDescription=RIFS Fractal Editor;FileVersion=1.0.1.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV.exe;ProductName=Apophysis AV &quot;Phoenix Edition&quot;;ProductVersion=1.0.1.0</VerInfo_Keys>
<VerInfo_Keys>CompanyName=Apophysis Developers Team;FileDescription=RIFS Fractal Editor;FileVersion=1.0.2.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV.exe;ProductName=Apophysis AV &quot;Phoenix Edition&quot;;ProductVersion=1.0.2.0</VerInfo_Keys>
<Icon_MainIcon>ApophysisAV_Icon1.ico</Icon_MainIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win64)'!=''">
@ -145,7 +145,7 @@
<DCC_RemoteDebug>true</DCC_RemoteDebug>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_Keys>CompanyName=Apophysis Developers Team;FileDescription=RIFS Fractal Editor;FileVersion=1.0.1.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV64.exe;ProductName=Apophysis AV &quot;Phoenix Edition&quot;;ProductVersion=1.0.1.0</VerInfo_Keys>
<VerInfo_Keys>CompanyName=Apophysis Developers Team;FileDescription=RIFS Fractal Editor;FileVersion=1.0.2.0;InternalName=Apophysis;LegalCopyright=© 2021 Alice V. Koryagina;LegalTrademarks=;OriginalFilename=ApophysisAV64.exe;ProductName=Apophysis AV &quot;Phoenix Edition&quot;;ProductVersion=1.0.2.0</VerInfo_Keys>
<Icon_MainIcon>ApophysisAV_Icon.ico</Icon_MainIcon>
</PropertyGroup>
<ItemGroup>
@ -153,11 +153,9 @@
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="IO\Binary.pas"/>
<DCCReference Include="IO\Base64.pas"/>
<DCCReference Include="System\sdStringTable.pas"/>
<DCCReference Include="System\CustomDrawControl.pas"/>
<DCCReference Include="System\LibXmlComps.pas"/>
<DCCReference Include="System\LibXmlParser.pas"/>
<DCCReference Include="System\LibXmlComps.pas"/>
<DCCReference Include="System\CustomDrawControl.pas"/>
<DCCReference Include="System\RegexHelper.pas"/>
<DCCReference Include="System\CurvesControl.pas"/>
<DCCReference Include="System\AsmRandom.pas"/>
@ -182,6 +180,7 @@
<DCCReference Include="Rendering\BucketFillerThread.pas"/>
<DCCReference Include="Rendering\RenderThread.pas"/>
<DCCReference Include="Rendering\ImageMaker.pas"/>
<DCCReference Include="System\MathExpressions.pas"/>
<DCCReference Include="Variations\varSinusoidal.pas"/>
<DCCReference Include="Variations\varLog.pas"/>
<DCCReference Include="Variations\varModulus.pas"/>
@ -253,6 +252,7 @@
<DCCReference Include="Variations\varPreCircleCrop.pas"/>
<DCCReference Include="Variations\varPreCrop.pas"/>
<DCCReference Include="Variations\varPreFalloff2.pas"/>
<DCCReference Include="Variations\varPreMobius.pas"/>
<DCCReference Include="Variations\varPostBoarders2.pas"/>
<DCCReference Include="Variations\varPostBwraps.pas"/>
<DCCReference Include="Variations\varPostCurl.pas"/>
@ -260,6 +260,7 @@
<DCCReference Include="Variations\varPostCircleCrop.pas"/>
<DCCReference Include="Variations\varPostCrop.pas"/>
<DCCReference Include="Variations\varPostFalloff2.pas"/>
<DCCReference Include="Variations\varPostMobius.pas"/>
<DCCReference Include="Variations\varPostSpherical.pas"/>
<DCCReference Include="Variations\varPostSinusoidal.pas"/>
<DCCReference Include="Variations\varProjective.pas"/>
@ -334,9 +335,6 @@
<DCCReference Include="Forms\Template.pas">
<Form>TemplateForm</Form>
</DCCReference>
<DCCReference Include="Forms\Curves.pas">
<Form>CurvesForm</Form>
</DCCReference>
<DCCReference Include="Forms\Preview.pas">
<Form>PreviewForm</Form>
</DCCReference>
@ -358,6 +356,14 @@
<DCCReference Include="Forms\VarOrderForm.pas">
<Form>VarOrder</Form>
</DCCReference>
<DCCReference Include="Forms\Animate.pas">
<Form>AnimateForm</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="Forms\FlameComment.pas">
<Form>CommentForm</Form>
<FormType>dfm</FormType>
</DCCReference>
<None Include="ApophysisAV.todo"/>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>

Binary file not shown.

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,12 @@ unit GradientHlpr;
interface
uses
windows, Graphics, Cmap;
const
PixelCountMax = 32768;
type
pRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple;
Graphics, Cmap;
type
TGradientHelper = class
private
procedure RGBBlend(a, b: integer; var Palette: TColorMap);
//procedure RGBBlend(a, b: integer; var Palette: TColorMap);
public
function GetGradientBitmap(Index: integer; const hue_rotation: double): TBitmap;
function RandomGradient: TColorMap;
@ -81,7 +74,7 @@ begin
Result := BitMap;
end;
///////////////////////////////////////////////////////////////////////////////
{//////////////////////////////////////////////////////////////////////////////}
function TGradientHelper.RandomGradient: TColorMap;
var
a, b, i, n, nodes: integer;
@ -143,7 +136,8 @@ begin
Result := Pal;
end;
///////////////////////////////////////////////////////////////////////////////
{//////////////////////////////////////////////////////////////////////////////}
(* // AV: how many duplicated code has this app...
procedure TGradientHelper.RGBBlend(a, b: integer; var Palette: TColorMap);
{ Linear blend between to indices of a palette }
var
@ -181,8 +175,8 @@ begin
Palette[i mod 256][2] := Round(c);
end;
end;
///////////////////////////////////////////////////////////////////////////////
*)
{//////////////////////////////////////////////////////////////////////////////}
initialization
GradientHelper := TGradientHelper.create;
finalization

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
@ -25,23 +25,32 @@ unit Cmap;
interface
uses sysutils, classes;
uses cmapdata, SysUtils, Classes, Windows;
// AV: moved following from Main unit and deleted all duplicates
const
PixelCountMax = 32768;
type
pRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple;
TColorMap = array[0..255, 0..3] of integer;
type
EFormatInvalid = class(Exception);
EPaletteInvalid = class(Exception); // AV: renamed due to name-space conflicts
const
RANDOMCMAP = -1;
NRCMAPS = 704;
NRCMAPS = NMAPS + 1; //704;
procedure GetCmap(var Index: integer; const hue_rotation: double; out cmap: TColorMap);
procedure GetCmapName(var Index: integer; out Name: string);
procedure rgb2hsv(const rgb: array of double; out hsv: array of double);
procedure hsv2rgb(const hsv: array of double; out rgb: array of double);
function GetGradient(FileName, Entry: string): string;
function GetVal(token: string): string; // AV: make public
function ReplaceTabs(str: string): string; // AV: make public
function CreatePalette(strng: string): TColorMap; // AV: moved from RndFlame
function GetPalette(strng: string; var Palette: TColorMap): boolean;
procedure GetTokens(s: string; var mlist: TStringList);
procedure HSVBlend(a, b: integer; var Palette: TColorMap); // AV
@ -51,7 +60,7 @@ procedure Brighten(const n: byte; var r, g, b: byte); // AV
implementation
uses
cmapdata, Math;
Math;
procedure rgb2hsv(const rgb: array of double; out hsv: array of double);
var
@ -91,10 +100,6 @@ var
f, p, q, t, v: double;
begin
try
// rgb[0] := 0;
// rgb[1] := 0;
// rgb[2] := 0;
j := floor(hsv[0]);
f := hsv[0] - j;
@ -111,6 +116,11 @@ begin
5: begin rgb[0] := v; rgb[1] := p; rgb[2] := q; end;
end;
except on EMathError do
begin
rgb[0] := 0;
rgb[1] := 0;
rgb[2] := 0;
end;
end;
end;
@ -152,7 +162,6 @@ begin
Name := CMapNames[Index];
end;
procedure RGBBlend(a, b: integer; var Palette: TColorMap);
{ Linear blend between to indices of a palette }
var
@ -286,6 +295,83 @@ begin
end;
end;
function CreatePalette(strng: string): TColorMap; // AV: moved from RndFlame
{ 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 EPaletteInvalid.Create('No closing brace');
if Pos('{', Strings[0]) = 0 then raise EPaletteInvalid.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 EPaletteInvalid.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);
a := StrToInt(Colors[i]); // AV: added precalc
Result[index][0] := a mod 256;
Result[index][1] := trunc(a / 256) mod 256;
Result[index][2] := trunc(a / 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 EPaletteInvalid do
begin
//
end;
end;
finally
Tokens.Free;
Strings.Free;
Indices.Free;
Colors.Free;
end;
end;
function GetPalette(strng: string; var Palette: TColorMap): boolean;
{ Loads a palette from a gradient string }
@ -304,8 +390,10 @@ begin
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.');
if Pos('}', Strings.Text) = 0 then
raise EPaletteInvalid.Create('No closing brace');
if Pos('{', Strings[0]) = 0 then
raise EPaletteInvalid.Create('No opening brace.');
GetTokens(ReplaceTabs(Strings.Text), Tokens);
i := 0;
while (Pos('}', Tokens[i]) = 0) and (Pos('opacity:', Lowercase(Tokens[i])) = 0) do
@ -322,7 +410,8 @@ begin
Palette[i][1] := 0;
Palette[i][2] := 0;
end;
if Indices.Count = 0 then raise EFormatInvalid.Create('No color info');
if Indices.Count = 0 then
raise EPaletteInvalid.Create('No color info');
for i := 0 to Indices.Count - 1 do
begin
try
@ -330,8 +419,8 @@ begin
while index < 0 do inc(index, 400);
index := Round(Index * (255 / 399));
indices[i] := IntToStr(index);
assert(index>=0);
assert(index<256);
assert(index >= 0);
assert(index < 256);
Palette[index][0] := StrToInt(Colors[i]) mod 256;
Palette[index][1] := trunc(StrToInt(Colors[i]) / 256) mod 256;
Palette[index][2] := trunc(StrToInt(Colors[i]) / 65536);
@ -351,7 +440,7 @@ begin
b := StrToInt(Indices[0]) + 256;
RGBBlend(a, b, Palette);
end;
except on EFormatInvalid do
except on EPaletteInvalid do
begin
Result := False;
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
@ -31,7 +31,7 @@ interface
Const
NMAPS = 703;
cmaps : array[0..NMAPS,0..255,0..2] of byte =
cmaps : array[0..NMAPS, 0..255, 0..2] of byte =
(
// 0 south-sea-bather
((185, 234, 235), (193, 238, 235), (197, 242, 235), (201, 242, 235),

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
@ -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;
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;
///////////////////////////////////////////////////////////////////////////////

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];
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;
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
{ // 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,23 +59,29 @@ 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!
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
@ -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,21 +356,23 @@ 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(ifs[i]);
v := GetVariationIndex(vn);
if (vars[v] <> 0.0) then
begin
vn := ifs[i];
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
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
else if (vn = 'affine3D') or (vn = 'trianglecrop') or (vn = 'projective')
or (vn = 'spherecrop') then
begin
GetVariable(vn + '_mode', mode);
if (mode = 0) then
@ -386,52 +397,46 @@ 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
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
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
GetVariable(vn + '_mode', mode);
if (mode <> 1) then continue;
end;
v := GetVariationIndex(vn);
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
Inc(FNrFunctions);
end;
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
begin
vn := ifs[i];
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
else if (vn = 'affine3D') or (vn = 'trianglecrop') or (vn = 'projective')
or (vn = 'spherecrop') then
begin
GetVariable(ifs[i] + '_mode', mode);
GetVariable(vn + '_mode', mode);
if (mode = 2) then
begin
v := GetVariationIndex(vn);
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
Inc(FNrFunctions);
end;
end;
end;
end;
UsedVars.Free;
polar_vpi := vars[6]/pi;
disc_vpi := vars[7]/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]);

View File

@ -5216,11 +5216,11 @@ object AboutForm: TAboutForm
StyleElements = [seClient, seBorder]
end
object Label24: TLabel
Left = 24
Left = 16
Top = 55
Width = 100
Width = 136
Height = 13
Caption = 'Copyright '#169' 2021'
Caption = 'Copyright '#169' 2021- 2022'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
@ -5236,12 +5236,12 @@ object AboutForm: TAboutForm
Shape = bsBottomLine
end
object lblAuthor: TLabel
Left = 145
Left = 165
Top = 54
Width = 86
Height = 13
Cursor = crHandPoint
Hint = 'https://www.donationalerts.com/r/fract_alice'
Hint = 'https://www.youtube.com/channel/UCX-fyv7NmSg2OaprPvxLTlQ/featured'
Caption = 'Alice V. Koryagina'
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
@ -5341,7 +5341,7 @@ object AboutForm: TAboutForm
Top = 50
Width = 57
Height = 16
Caption = 'v 1.0.1.0'
Caption = 'v 1.0.2.0'
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -15

View File

@ -170,7 +170,7 @@ object AdjustForm: TAdjustForm
Top = 181
Width = 451
Height = 155
ActivePage = TabGradient
ActivePage = TabCamera
Anchors = [akLeft, akRight, akBottom]
Images = MainForm.Buttons
TabOrder = 1
@ -365,10 +365,23 @@ object AdjustForm: TAdjustForm
TabOrder = 12
OnClick = btResetZoomClick
end
object chkDisplay3DAxes: TCheckBox
Left = 128
Top = 105
Width = 310
Height = 17
Caption = 'Display 3D axes'
TabOrder = 13
OnClick = chkDisplay3DAxesClick
end
end
object TabRendering: TTabSheet
Caption = 'Rendering'
ImageIndex = 35
ExplicitLeft = 0
ExplicitTop = 0
ExplicitWidth = 0
ExplicitHeight = 0
DesignSize = (
443
126)
@ -406,7 +419,7 @@ object AdjustForm: TAdjustForm
Height = 15
Anchors = [akLeft, akTop, akRight]
LargeChange = 10
Max = 500
Max = 1000
Min = 100
PageSize = 0
Position = 500
@ -630,6 +643,10 @@ object AdjustForm: TAdjustForm
object TabGradient: TTabSheet
Caption = 'Gradient'
ImageIndex = 11
ExplicitLeft = 0
ExplicitTop = 0
ExplicitWidth = 0
ExplicitHeight = 0
DesignSize = (
443
126)
@ -948,7 +965,7 @@ object AdjustForm: TAdjustForm
Left = 115
Top = 83
Width = 210
Height = 21
Height = 20
BevelInner = bvLowered
BevelOuter = bvRaised
Style = csOwnerDrawFixed
@ -1128,10 +1145,14 @@ object AdjustForm: TAdjustForm
object TabSize: TTabSheet
Caption = 'Image Size'
ImageIndex = 14
ExplicitLeft = 0
ExplicitTop = 0
ExplicitWidth = 0
ExplicitHeight = 0
object gbSize: TGroupBox
Left = 1
Top = 5
Width = 188
Width = 189
Height = 105
Caption = 'Size in pixels'
Font.Charset = DEFAULT_CHARSET
@ -1142,21 +1163,8 @@ object AdjustForm: TAdjustForm
ParentFont = False
TabOrder = 0
DesignSize = (
188
189
105)
object lblRatio: TLabel
Left = 5
Top = 78
Width = 56
Height = 13
Caption = 'Aspect ratio'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object pnlWidth: TPanel
Left = 4
Top = 19
@ -1204,7 +1212,7 @@ object AdjustForm: TAdjustForm
object txtHeight: TComboBox
Left = 91
Top = 45
Width = 78
Width = 79
Height = 21
Anchors = [akLeft, akTop, akRight]
Font.Charset = DEFAULT_CHARSET
@ -1230,7 +1238,7 @@ object AdjustForm: TAdjustForm
object txtWidth: TComboBox
Left = 91
Top = 19
Width = 78
Width = 79
Height = 21
Anchors = [akLeft, akTop, akRight]
Font.Charset = DEFAULT_CHARSET
@ -1251,8 +1259,8 @@ object AdjustForm: TAdjustForm
'1280')
end
object cbAspectRatio: TComboBox
Left = 70
Top = 75
Left = 74
Top = 71
Width = 113
Height = 21
Style = csDropDownList
@ -1276,6 +1284,28 @@ object AdjustForm: TAdjustForm
'16 : 10'
'21 : 9 ')
end
object lblRatio: TPanel
Left = 4
Top = 71
Width = 70
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'Aspect ratio'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 5
OnDblClick = DragPanelDblClick
OnMouseDown = DragPanelMouseDown
OnMouseMove = DragPanelMouseMove
OnMouseUp = DragPanelMouseUp
end
end
object gbPresets: TGroupBox
Left = 194
@ -1507,6 +1537,10 @@ object AdjustForm: TAdjustForm
object TabCurves: TTabSheet
Caption = 'Curves'
ImageIndex = 69
ExplicitLeft = 0
ExplicitTop = 0
ExplicitWidth = 0
ExplicitHeight = 0
object CurvesPanel: TPanel
Left = 3
Top = 1
@ -1938,6 +1972,10 @@ object AdjustForm: TAdjustForm
Caption = 'Save as Map file...'
OnClick = SaveasMapfile1Click
end
object SaveAsScript: TMenuItem
Caption = 'Save as Script file...'
OnClick = SaveAsScriptClick
end
object N6: TMenuItem
Caption = '-'
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,12 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, ComCtrls, Buttons, Menus, AppEvnts, CurvesControl,
StdCtrls, ExtCtrls, ComCtrls, Buttons, Menus, CurvesControl,
ControlPoint, Cmap, RenderingInterface, Translation;
const
WM_UPDATE_PARAMS = WM_APP + 5439;
const
PixelCountMax = 32768;
type
pRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple;
type
TAdjustForm = class(TForm)
QualityPopup: TPopupMenu;
@ -190,7 +183,6 @@ type
N13: TMenuItem;
mnuLuminance: TMenuItem;
cbAspectRatio: TComboBox;
lblRatio: TLabel;
AdjustColorFragment: TMenuItem;
N14: TMenuItem;
mnuSepia: TMenuItem;
@ -207,12 +199,13 @@ type
SmoothizeSelected: TMenuItem;
btResetZoom: TButton;
btnMenu: TButton; // AV: changed from TSpeedButton for auto-drawing the arrow
SaveAsScript: TMenuItem;
lblRatio: TPanel;
chkDisplay3DAxes: TCheckBox; // AV
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormDestroy(Sender: TObject);
procedure DrawPreview;
// procedure btnOKClick(Sender: TObject);
// procedure btnCancelClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure mnuLowQualityClick(Sender: TObject);
procedure mnuMediumQualityClick(Sender: TObject);
@ -231,20 +224,6 @@ type
procedure txtVibrancyExit(Sender: TObject);
procedure scrollCameraScroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
(*
procedure scrollCenterXScroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
procedure scrollCenterYScroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
procedure scrollGammaScroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
procedure scrollBrightnessScroll(Sender: TObject;
ScrollCode: TScrollCode; var ScrollPos: Integer);
procedure scrollVibrancyScroll(Sender: TObject;
ScrollCode: TScrollCode; var ScrollPos: Integer);
procedure scrollAngleScroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
*)
procedure scrollVibrancyScroll(Sender: TObject);
procedure scrollGammaChange(Sender: TObject);
procedure scrollBrightnessChange(Sender: TObject);
@ -398,6 +377,8 @@ type
procedure txtContrastKeyPress(Sender: TObject; var Key: Char);
procedure SmoothizeSelectedClick(Sender: TObject);
procedure btResetZoomClick(Sender: TObject);
procedure SaveAsScriptClick(Sender: TObject);
procedure chkDisplay3DAxesClick(Sender: TObject);
private
CurvesControl: TCurvesControl;
Resetting: boolean;
@ -472,8 +453,8 @@ procedure HSVToRGB(H, S, V: real; var Rb, Gb, Bb: integer);
implementation
uses
RndFlame, Main, cmapdata, Math, Browser, Editor, Global,
Save, Mutate, ClipBrd, GradientHlpr, Registry, Curves, ColorRangeForm;
RndFlame, Main, cmapdata, Math, Browser, Editor, Global, // Curves,
Save, Mutate, ClipBrd, GradientHlpr, Registry, ColorRangeForm;
{$R *.DFM}
@ -494,8 +475,8 @@ begin
tbWeightLeft.Position := Round(CurvesControl.WeightLeft * 10);
tbWeightRight.Position := Round(CurvesControl.WeightRight * 10);
pw := PrevPnl.Width -2;
ph := PrevPnl.Height -2;
pw := PrevPnl.Width - 2;
ph := PrevPnl.Height - 2;
if (cp.width / cp.height) > (PrevPnl.Width / PrevPnl.Height) then
begin
PreviewImage.Width := pw;
@ -572,7 +553,6 @@ begin
if EditForm.Visible then EditForm.UpdateDisplay;
if MutateForm.Visible then MutateForm.UpdateDisplay;
if CurvesForm.Visible then CurvesForm.SetCp(cp);
if bBgOnly then
MainForm.tbShowAlphaClick(Self)
@ -585,17 +565,97 @@ var
i: integer;
Row: pRGBTripleArray;
BitMap: TBitMap;
procedure Draw3DAxes; // AV
const
w = 60; // default axis length
var
Origin, EndPoint, Rot: TPoint;
sinPitch, cosPitch, sinRoll, cosRoll, sinYaw, cosYaw: double;
sinA, cosA: double;
DoRotate: boolean;
begin
SinCos(cp.cameraPitch, sinPitch, cosPitch);
SinCos(cp.cameraRoll, sinRoll, cosRoll);
SinCos(-cp.cameraYaw, sinYaw, cosYaw);
if cp.FAngle <> 0 then
begin
SinCos(cp.FAngle, sinA, cosA);
DoRotate := True;
end
else
DoRotate := False;
Origin.X := BM.Width shr 1;
Origin.Y := BM.Height shr 1;
with BM.Canvas do
begin
Pen.Width := 2;
Font.Color := clBlack; // clWhite;
// X - axis
Pen.Color := clRed;
Brush.Color := clRed;
EndPoint.X := Round(cosRoll * cosYaw * w);
EndPoint.Y := Round((sinPitch * sinRoll * cosYaw + cosPitch * sinYaw) * w);
if DoRotate then
begin
Rot.X := Round(EndPoint.X * cosA + EndPoint.Y * sinA);
Rot.Y := Round(-EndPoint.X * sinA + EndPoint.Y * cosA);
EndPoint := Rot;
end;
MoveTo(Origin.X, Origin.Y);
LineTo(Origin.X + EndPoint.X, Origin.Y + EndPoint.Y);
TextOut(PenPos.X - 2, PenPos.Y - 2, 'X');
// Y - axis
Pen.Color := clBlue;
Brush.Color := clBlue;
EndPoint.X := Round(-cosRoll * sinYaw * w);
EndPoint.Y := Round((-sinPitch * sinRoll * sinYaw + cosPitch * cosYaw) * w);
if DoRotate then
begin
Rot.X := Round(EndPoint.X * cosA + EndPoint.Y * sinA);
Rot.Y := Round(-EndPoint.X * sinA + EndPoint.Y * cosA);
EndPoint := Rot;
end;
MoveTo(Origin.X, Origin.Y);
LineTo(Origin.X + EndPoint.X, Origin.Y + EndPoint.Y);
TextOut(PenPos.X - 2, PenPos.Y - 2, 'Y');
// Z - axis
Pen.Color := clGreen;
Brush.Color := clGreen;
EndPoint.X := Round(sinRoll * w);
EndPoint.Y := Round(-sinPitch * cosRoll * w);
if DoRotate then
begin
Rot.X := Round(EndPoint.X * cosA + EndPoint.Y * sinA);
Rot.Y := Round(-EndPoint.X * sinA + EndPoint.Y * cosA);
EndPoint := Rot;
end;
MoveTo(Origin.X, Origin.Y);
LineTo(Origin.X + EndPoint.X, Origin.Y + EndPoint.Y);
TextOut(PenPos.X - 2, PenPos.Y - 2, 'Z');
end;
end;
begin
if Resetting then exit;
Render.Stop;
// AdjustScale(cp, PreviewImage.Width, PreviewImage.Height);
cp.sample_density := PreviewDensity;
cp.spatial_oversample := defOversample;
cp.spatial_filter_radius := defFilterRadius;
Render.SetCP(cp);
Render.Render;
BM.Assign(Render.GetImage);
if chkDisplay3DAxes.Checked then Draw3DAxes; // AV
PreviewImage.Picture.Graphic := bm;
if mnuInstantPreview.Checked then PreviewImage.Refresh;
@ -678,9 +738,9 @@ begin
pnlYPos.Caption := TextByKey('adjustment-tab-camera-ypos');
pnlAngle.Caption := TextByKey('adjustment-tab-camera-rotation');
btResetZoom.Caption := TextByKey('adjustment-tab-camera-resetzoom');
chkDisplay3DAxes.Caption := TextByKey('adjustment-tab-camera-draw3daxes');
btResetZoom.Hint := TextByKey('adjustment-hint-resetzoom');
TabRendering.Caption := TextByKey('adjustment-tab-rendering-title');
//chkTransparent.Caption := TextByKey('adjustment-tab-rendering-istransparent');
TabGradient.Caption := TextByKey('adjustment-tab-gradient-title');
mnuRotate.Caption := TextByKey('adjustment-tab-gradient-moderotate');
mnuHue.Caption := TextByKey('adjustment-tab-gradient-modehue');
@ -723,6 +783,7 @@ begin
SaveGradient1.Caption := TextByKey('adjustment-popup-gradient-saveasugr');
SaveasMapfile1.Caption := TextByKey('adjustment-popup-gradient-saveasmap');
mnuSaveAsDefault.Caption := TextByKey('adjustment-popup-gradient-saveasdefault');
SaveAsScript.Caption := TextByKey('adjustment-popup-gradient-saveasscript');
btnMenu.Caption := TextByKey('adjustment-tab-gradient-moderotate');
Red1.Caption := TextByKey('adjustment-tab-curves-red');
Green1.Caption := TextByKey('adjustment-tab-curves-green');
@ -806,6 +867,7 @@ begin
Registry.WriteInteger('Left', AdjustForm.Left);
Registry.WriteBool('InstantPreview', mnuInstantPreview.Checked);
Registry.WriteBool('ResizeMain', chkResizeMain.Checked);
Registry.WriteBool('Display3DAxes', chkDisplay3DAxes.Checked); // AV
end;
finally
Registry.Free;
@ -841,12 +903,14 @@ begin
mnuInstantPreview.Checked := Registry.ReadBool('InstantPreview');
if Registry.ValueExists('ResizeMain') then
chkResizeMain.Checked := Registry.ReadBool('ResizeMain');
if Registry.ValueExists('Display3DAxes') then // AV
chkDisplay3DAxes.Checked := Registry.ReadBool('Display3DAxes');
Registry.CloseKey;
end;
if Registry.OpenKey('Software\' + APP_NAME + '\ImageSizePresets', False) then
begin
for i:=1 to 3 do begin
for i := 1 to 3 do begin
strx:='Preset' + IntToStr(i) + 'Left';
stry:='Preset' + IntToStr(i) + 'Top';
strw:='Preset' + IntToStr(i) + 'Width';
@ -861,9 +925,7 @@ begin
end;
Preset[i].Left := MainForm.Left;
Preset[i].Top := MainForm.Top;
// Preset[i].Width := 512;
// Preset[i].Height := 384;
// AV: them different by default
// AV: make them different by default
case i of
1: begin
Preset[1].Width := 512;
@ -881,7 +943,7 @@ begin
end;
end
else begin
for i:=1 to 3 do begin
for i := 1 to 3 do begin
Preset[i].Left := MainForm.Left;
Preset[i].Top := MainForm.Top;
end;
@ -943,6 +1005,11 @@ begin
DrawPreview;
end;
procedure TAdjustForm.chkDisplay3DAxesClick(Sender: TObject); // AV
begin
DrawPreview; // show or hide coordinate axes
end;
procedure TAdjustForm.txtZoomEnter(Sender: TObject);
begin
EditBoxValue := txtZoom.Text;
@ -1183,38 +1250,6 @@ begin
if ScrollCode = scEndScroll then UpdateFlame;
end;
(*
procedure TAdjustForm.scrollCenterXScroll(Sender: TObject;
ScrollCode: TScrollCode; var ScrollPos: Integer);
begin
if ScrollCode = scEndScroll then UpdateFlame;
end;
procedure TAdjustForm.scrollCenterYScroll(Sender: TObject;
ScrollCode: TScrollCode; var ScrollPos: Integer);
begin
if ScrollCode = scEndScroll then UpdateFlame;
end;
procedure TAdjustForm.scrollGammaScroll(Sender: TObject;
ScrollCode: TScrollCode; var ScrollPos: Integer);
begin
if ScrollCode = scEndScroll then UpdateFlame;
end;
procedure TAdjustForm.scrollBrightnessScroll(Sender: TObject;
ScrollCode: TScrollCode; var ScrollPos: Integer);
begin
if ScrollCode = scEndScroll then UpdateFlame;
end;
procedure TAdjustForm.scrollVibrancyScroll(Sender: TObject;
ScrollCode: TScrollCode; var ScrollPos: Integer);
begin
if ScrollCode = scEndScroll then UpdateFlame;
end;
*)
procedure TAdjustForm.scrollVibrancyScroll(Sender: TObject);
begin
cp.Vibrancy := ScrollVibrancy.Position / 100;
@ -1381,7 +1416,6 @@ begin
if EditForm.visible then EditForm.UpdateDisplay;
if MutateForm.Visible then MutateForm.UpdateDisplay;
if CurvesForm.Visible then CurvesForm.SetCp(MainCp);
if mnuInstantPreview.Checked then DrawPreview;
@ -1413,7 +1447,8 @@ begin
end;
CloseFile(MapFile);
except
on EInOutError do Application.MessageBox(PChar(Format(TextByKey('common-genericopenerror'), [FileName])), 'Apophysis', 16);
on EInOutError do
raise Exception.CreateFmt(TextByKey('common-genericopenerror'), [FileName]); // AV
end;
end;
@ -2048,6 +2083,42 @@ begin
SaveMap(SaveDialog.Filename);
end;
procedure TAdjustForm.SaveAsScriptClick(Sender: TObject);
var
gradstr: TStringList;
fn, s: string;
i: word;
begin
SaveDialog.InitialDir := AppPath + 'Scripts';
SaveDialog.FileName := 'Palette_' + IntToStr(cmbPalette.ItemIndex) + '.asc';
SaveDialog.DefaultExt := 'asc';
SaveDialog.Filter := Format('%s|*.aposcript;*.asc|%s|*.*',
[TextByKey('common-filter-scriptfiles'),
TextByKey('common-filter-allfiles')]);
if SaveDialog.Execute then
begin
fn := SaveDialog.FileName;
gradstr := TStringList.Create;
try
gradstr.Add('procedure SetCustomPalette;');
gradstr.Add('begin');
gradstr.Add(' with Flame do begin');
for i := 0 to 255 do
gradstr.Add(Format(' Gradient[%d,0] := %d; Gradient[%0:d,1] := %2:d; Gradient[%0:d,2] := %3:d;',
[i, Palette[i][0], palette[i][1], palette[i][2]]));
gradstr.Add(' end;');
gradstr.Add('end;');
s := ExtractFileName(fn);
for i := 1 to Length(s) do
if CharInSet(s[i], [#32, '-', '(', ')']) then s[i] := '_';
gradstr.SaveToFile(ExtractFilePath(fn) + s);
MainForm.GetScripts;
finally
gradstr.Free;
end;
end;
end;
procedure TAdjustForm.cmbPaletteDrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
@ -2190,7 +2261,7 @@ begin
end;
procedure TAdjustForm.mnuSepiaClick(Sender: TObject);
var i, sep: integer;
var i, sep: smallint;
begin
for i := 0 to 255 do
begin
@ -2205,7 +2276,7 @@ end;
procedure TAdjustForm.mnuSetColorClick(Sender: TObject);
var
i: integer;
i: smallint;
col: Longint;
begin
ColorDialog.Color := RGB(Palette[selA,0], Palette[selA,1], Palette[selA,2]);
@ -2278,8 +2349,8 @@ procedure TAdjustForm.GradImageMouseMove(Sender: TObject;
begin
j := j0 + round((i - i0) * k);
assert(j >= 0);
assert(j < 256);
assert(j >= 0);
assert(j < 256);
cp.cmap[i] := Palette[j];
BackupPal[i] := tmpBackupPal[j]; //?
@ -2292,8 +2363,8 @@ assert(j < 256);
j := j0 + trunc(f);
f := frac(f);
assert(j >= 0);
assert(j < 256);
assert(j >= 0);
assert(j < 256);
if j < 255 then jj := j + 1
else jj := 0;
@ -2417,7 +2488,7 @@ begin
end;
end;
// AV: operations with selected color fragments
//*************** AV: operations with selected color fragments **********//
procedure TAdjustForm.InvertColorsClick(Sender: TObject);
var
@ -2460,19 +2531,20 @@ begin
end;
procedure TAdjustForm.Pastefragment1Click(Sender: TObject);
var i, j, l: integer;
var i, j, l: smallint;
begin
l := High(tmpColors);
l := Min(selA + l, selB);
for i := selA to l do
for j := 0 to 2 do Palette[i][j] := tmpColors[i - selA][j];
for j := 0 to 2 do
Palette[i][j] := tmpColors[i - selA][j];
UpdateGradient(palette);
Apply;
end;
procedure TAdjustForm.ReverseFragmentClick(Sender: TObject);
var
i, j: integer;
i, j: byte;
pal: array of array of byte;
begin
SetLength(pal, selB - selA + 1, 3);
@ -2490,11 +2562,11 @@ end;
function TAdjustForm.PresetToStr(n: integer): string;
begin
Result:=IntToStr(Preset[n].Width) + ' x ' + IntToStr(Preset[n].Height)
Result := IntToStr(Preset[n].Width) + ' x ' + IntToStr(Preset[n].Height)
end;
procedure TAdjustForm.RandomizeSelectedClick(Sender: TObject);
var i, j: integer;
var i, j: byte;
tempPal: TColorMap;
begin
tempPal := GradientHelper.RandomGradient;
@ -2513,8 +2585,8 @@ begin
txtHeight.Text := IntToStr(ImageHeight);
if chkResizeMain.Checked then begin
MainForm.Left:=Preset[n].Left;
MainForm.Top:=Preset[n].Top;
MainForm.Left := Preset[n].Left;
MainForm.Top := Preset[n].Top;
end;
SetMainWindowSize;
@ -2542,7 +2614,6 @@ begin
if EditForm.Visible then EditForm.UpdateDisplay;
if MutateForm.Visible then MutateForm.UpdateDisplay;
if CurvesForm.Visible then CurvesForm.SetCp(cp);
MainForm.RedrawTimer.enabled := true;
{ if ScrollCode = scEndScroll then
@ -2595,7 +2666,7 @@ begin
if (s[1] = '-') then
start := 2;
for i:=start to length(s) do
for i := start to length(s) do
if not (CharInSet(s[i],['0'..'9'])) then
begin
Result := False;
@ -2639,10 +2710,12 @@ begin
end;
end;
//procedure TAdjustForm.chkMaintainClick(Sender: TObject);
//begin
// Ratio := ImageWidth / ImageHeight;
//end;
{
procedure TAdjustForm.chkMaintainClick(Sender: TObject);
begin
Ratio := ImageWidth / ImageHeight;
end;
}
procedure TAdjustForm.SetMainWindowSize;
var

981
Forms/Animate.dfm Normal file
View File

@ -0,0 +1,981 @@
object AnimateForm: TAnimateForm
Left = 0
Top = 0
BorderStyle = bsSingle
Caption = 'Animate Flame'
ClientHeight = 476
ClientWidth = 496
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
Icon.Data = {
0000010001001010000000000000680400001600000028000000100000002000
000001002000000000000004000000000000000000000000000000000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00113D55F7285F87FB4988BDFB428DBCC12D77
B322FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF002E2E
2ED8292929FA242424CCFFFFFF002B6583FB94C7F9FF91C9F9FF4185C9FF1C64
AAF310202DE0050505FF020202DCFFFFFF00FFFFFF00FFFFFF00FFFFFF003434
34FA2F2F2F61353535FF575757FF4389AAFFE0F2FFFF549AD8FF1A7ABEFF4998
C5FF3177B0FF1B3C5A6D050505EFFFFFFF00FFFFFF00FFFFFF00FFFFFF003A3A
3AFF353535C6303030F56EDF9DFE54B2A0FE7AB6D5FF90B7D1FF55C9E4FF5BDF
F5FF78D0EDFF3E8DCFF70F1B25FFFFFFFF00FFFFFF00FFFFFF00FFFFFF004040
40D03B3B3B6C363636D54FCB5CFF57D77AFF35B883FF73B8D3FFC2F6FDFF63DF
F7FF5DE2F8FF79D3F0FF4291D5FD388CD820FFFFFF00FFFFFF00FFFFFF004545
45DF404040C33B3B3BD04FC445FF4BBA2CFFD8BD60FFB1A87FFF77CBE7FFC7F7
FDFF5EDCF5FF5AE1F7FF7BD4F1FF4295DCF2368CD934FFFFFF00FFFFFF004B4B
4BDA464646A2414141CF7FBF36FFDDC569FFFFC270FFFFBF67FF86C3BAFF79D3
EEFFC7F7FDFF5FDCF5FF5BE2F7FF7AD6F2FF4099DFE8448DCD30FFFFFF005151
51D44C4C4C81474747CCF8C66EFFFFC877FFFFC572FFFFC46CFF98D8CFFF78D7
E9FF7BD3ECFFC4F6FDFF6CDDF6FF6DCAEDFF63A3D7FF5D9BD2EC5192CA265656
56E2515151D0686868FF575757FF575757FF575757FF575757FF575757FF5757
57FF275969F97CD2EAFEB2E3F9FF8BC0E7FFAED3F6FFC4E0FCFF669FD3F75B5B
5BD457575781525252CD72E29EFF7CE3A4FF78E3A0FF63E095FF5AE195FF55E2
93FF303030D026748BAD77BEE7FFB4D2F0FFE5F3FFFFACD2EFFF488CC7E86060
60DA5C5C5CA2575757CF4FCB5CFF57D77AFF42D16AFF70C75EFFB6B850FFCBAE
3FFF363636D0313131A22E5C6CE658A5D8FF85B1DBFF469DD0FF2B95D15E6464
64DF606060C35C5C5CD04FC445FF4BBA2CFFD8BD60FFFFBA62FFFFB965FFDBBB
7DFF3B3B3BD2363636C3313131DFFFFFFF00FFFFFF00FFFFFF00FFFFFF006868
68D165656584616161D47FBF36FFDDC569FFFFC270FFFFBF67FFAECBACFF68E0
F9FF414141D63C3C3C6C373737D0FFFFFF00FFFFFF00FFFFFF00FFFFFF006C6C
6CFF696969ED656565FAE5BA6CF6ECBC74F6EBB86EF6EBB668F680CBCDF680D7
EAF6474747FA424242CC3D3D3DFFFFFFFF00FFFFFF00FFFFFF00FFFFFF006F6F
6FF86C6C6C9B696969FF575757FF575757FF575757FF575757FF575757FF5757
57FF4D4D4DFF4848488D434343D5FFFFFF00FFFFFF00FFFFFF00FFFFFF007171
71D46F6F6FF36D6D6DDDFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00525252D64D4D4DF9494949D7FFFFFF00FFFFFF00FFFFFF00FFFFFF00F0FF
0000100F0000402F0000000F0000400F00000007000000030000000100000000
00000000000000010000000F0000002F0000000F0000000F00001F8F0000}
OldCreateOrder = False
OnClose = FormClose
OnCreate = FormCreate
OnDestroy = FormDestroy
OnShow = FormShow
DesignSize = (
496
476)
PixelsPerInch = 96
TextHeight = 13
object btSaveAnimation: TButton
Left = 304
Top = 427
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Caption = 'Save'
ParentShowHint = False
ShowHint = True
TabOrder = 0
OnClick = btSaveAnimationClick
end
object AnimPages: TPageControl
Left = 8
Top = 8
Width = 480
Height = 412
ActivePage = tsSettings
Anchors = [akLeft, akTop, akRight, akBottom]
TabOrder = 1
object tsSettings: TTabSheet
Caption = 'General'
object gbOutput: TGroupBox
Left = 5
Top = 5
Width = 450
Height = 125
Caption = ' Output settings '
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = [fsBold]
ParentFont = False
TabOrder = 0
object btSetFlame: TSpeedButton
Left = 420
Top = 24
Width = 24
Height = 24
Hint = 'Browse...'
Flat = True
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Arial'
Font.Style = [fsBold]
Glyph.Data = {
36030000424D3603000000000000360000002800000010000000100000000100
18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF
FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F
607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13
18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708
88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3
8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367
805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51
C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF
7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC
EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67
D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2
98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8
FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788
A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6
A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788
93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89
9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA
ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF}
ParentFont = False
ParentShowHint = False
ShowHint = True
OnClick = btSetFlameClick
end
object lbSeconds: TLabel
Left = 390
Top = 56
Width = 39
Height = 13
Caption = 'seconds'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
end
object pnlFPS: TPanel
Left = 8
Top = 52
Width = 121
Height = 21
BevelOuter = bvLowered
Caption = 'Frames per second'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 0
end
object pnlDuration: TPanel
Left = 200
Top = 52
Width = 121
Height = 21
BevelOuter = bvLowered
Caption = 'Duration'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 1
end
object seDuration: TSpinEdit
Left = 321
Top = 52
Width = 65
Height = 22
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
MaxValue = 100
MinValue = 1
ParentFont = False
TabOrder = 2
Value = 1
end
object seFPS: TSpinEdit
Left = 129
Top = 52
Width = 65
Height = 22
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
MaxValue = 200
MinValue = 2
ParentFont = False
TabOrder = 3
Value = 25
end
object pnlOutFlame: TPanel
Left = 8
Top = 24
Width = 121
Height = 21
BevelOuter = bvLowered
Caption = 'Output flame file'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 4
end
object edOutFlame: TEdit
Left = 127
Top = 24
Width = 290
Height = 21
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 5
end
object chkListFlames: TCheckBox
Left = 8
Top = 80
Width = 378
Height = 17
Caption = 'Show generated flames'
Checked = True
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
State = cbChecked
TabOrder = 6
end
object chkRender: TCheckBox
Left = 8
Top = 100
Width = 378
Height = 17
Caption = 'Render all frames'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 7
OnClick = chkRenderClick
end
end
object gbFrame: TGroupBox
Left = 5
Top = 142
Width = 450
Height = 221
Caption = 'Frame'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = [fsBold]
ParentFont = False
TabOrder = 1
object pnlFrameWidth: TPanel
Left = 8
Top = 24
Width = 121
Height = 21
BevelOuter = bvLowered
Caption = 'Width'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 0
end
object pnlFrameHeight: TPanel
Left = 200
Top = 24
Width = 121
Height = 21
BevelOuter = bvLowered
Caption = 'Height'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 1
end
object seFrameHeight: TSpinEdit
Left = 321
Top = 24
Width = 65
Height = 22
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
MaxValue = 10000
MinValue = 1
ParentFont = False
TabOrder = 2
Value = 600
OnChange = seFrameHeightChange
end
object seFrameWidth: TSpinEdit
Left = 129
Top = 24
Width = 65
Height = 22
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
MaxValue = 10000
MinValue = 1
ParentFont = False
TabOrder = 3
Value = 800
OnChange = seFrameWidthChange
end
object cbAspectRatio: TComboBox
Left = 129
Top = 52
Width = 160
Height = 21
Style = csDropDownList
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ItemIndex = 1
ParentFont = False
TabOrder = 4
Text = 'Maintain aspect ratio'
OnChange = cbAspectRatioChange
Items.Strings = (
'Custom'
'Maintain aspect ratio'
'3 : 2 (Classic Film)'
'4 : 3 (Standart Monitor)'
'5 : 4 '
'16 : 9 (HD Video)'
'16 : 10'
'21 : 9 (CinemaScope)')
end
object pnlRatio: TPanel
Left = 8
Top = 52
Width = 121
Height = 21
BevelOuter = bvLowered
Caption = 'Aspect ratio'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 5
end
object pnlPrefix: TPanel
Left = 8
Top = 80
Width = 121
Height = 21
BevelOuter = bvLowered
Caption = 'Frame prefix'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 6
end
object edPrefix: TEdit
Left = 129
Top = 80
Width = 65
Height = 21
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 7
Text = 'anim-'
end
object pnlFrameExt: TPanel
Left = 200
Top = 80
Width = 121
Height = 21
BevelOuter = bvLowered
Caption = 'Graphic extension'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 8
end
object cbFrameExt: TComboBox
Left = 321
Top = 80
Width = 65
Height = 21
Style = csDropDownList
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ItemIndex = 1
ParentFont = False
TabOrder = 9
Text = '.png'
OnChange = cbAspectRatioChange
Items.Strings = (
'.bmp'
'.png'
'.jpg')
end
object gbFrameQuality: TGroupBox
Left = 8
Top = 112
Width = 200
Height = 97
Caption = 'Quality settings'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = [fsBold]
ParentFont = False
TabOrder = 10
object pnlDensity: TPanel
Left = 8
Top = 20
Width = 121
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'Density'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
TabOrder = 2
end
object pnlFilter: TPanel
Left = 8
Top = 44
Width = 121
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'Filter radius'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
TabOrder = 3
end
object pnlOversample: TPanel
Left = 8
Top = 68
Width = 121
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'Oversample'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
TabOrder = 4
end
object txtDensity: TComboBox
Left = 128
Top = 20
Width = 65
Height = 21
AutoComplete = False
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
TabOrder = 0
Text = '200'
Items.Strings = (
'200'
'500'
'1000'
'2000'
'4000')
end
object txtFilterRadius: TEdit
Left = 128
Top = 44
Width = 65
Height = 21
BiDiMode = bdLeftToRight
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentBiDiMode = False
ParentFont = False
TabOrder = 1
Text = '0.1'
end
object sbFilterRadius: TSpinButton
Left = 175
Top = 45
Width = 15
Height = 17
DownGlyph.Data = {
0E010000424D0E01000000000000360000002800000009000000060000000100
200000000000D800000000000000000000000000000000000000008080000080
8000008080000080800000808000008080000080800000808000008080000080
8000008080000080800000808000000000000080800000808000008080000080
8000008080000080800000808000000000000000000000000000008080000080
8000008080000080800000808000000000000000000000000000000000000000
0000008080000080800000808000000000000000000000000000000000000000
0000000000000000000000808000008080000080800000808000008080000080
800000808000008080000080800000808000}
FocusControl = txtFilterRadius
TabOrder = 5
UpGlyph.Data = {
0E010000424D0E01000000000000360000002800000009000000060000000100
200000000000D800000000000000000000000000000000000000008080000080
8000008080000080800000808000008080000080800000808000008080000080
8000000000000000000000000000000000000000000000000000000000000080
8000008080000080800000000000000000000000000000000000000000000080
8000008080000080800000808000008080000000000000000000000000000080
8000008080000080800000808000008080000080800000808000000000000080
8000008080000080800000808000008080000080800000808000008080000080
800000808000008080000080800000808000}
OnDownClick = sbFilterRadiusDownClick
OnUpClick = sbFilterRadiusUpClick
end
object seOversample: TSpinEdit
Left = 128
Top = 68
Width = 65
Height = 22
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
MaxValue = 4
MinValue = 1
ParentFont = False
ReadOnly = True
TabOrder = 6
Value = 2
end
end
end
end
object tsAnimation: TTabSheet
Caption = 'Animation'
ImageIndex = 1
ExplicitLeft = 0
ExplicitTop = 0
ExplicitWidth = 0
ExplicitHeight = 380
object gbAnimType: TGroupBox
Left = 3
Top = 4
Width = 450
Height = 155
Caption = ' Animation parameters'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = [fsBold]
ParentFont = False
TabOrder = 0
object cbAnimType: TComboBox
Left = 129
Top = 24
Width = 310
Height = 21
Style = csDropDownList
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ItemIndex = 0
ParentFont = False
TabOrder = 0
Text = 'Rotate flame'
OnChange = cbAnimTypeChange
Items.Strings = (
'Rotate flame'
'Rotate reference triangle'
'Rotate 3D camera'
'Rotate color gradient'
'Change gradient hue'
'Morphing (cosine, RGB)'
'Morphing (cosine, HSV)'
'Morphing (linear, RGB)'
'Morphing (linear, HSV)')
end
object pnlAnimType: TPanel
Left = 8
Top = 24
Width = 121
Height = 21
BevelOuter = bvLowered
Caption = 'Animation type'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 1
end
object pnlStartFlame: TPanel
Left = 8
Top = 52
Width = 121
Height = 21
BevelOuter = bvLowered
Caption = 'Initial flame'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 2
end
object cbFlames: TComboBox
Left = 129
Top = 52
Width = 310
Height = 21
Style = csDropDownList
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ItemIndex = 0
ParentFont = False
TabOrder = 3
Text = 'Current'
OnChange = cbFlamesChange
Items.Strings = (
'Current')
end
object pnlEndFlame: TPanel
Left = 8
Top = 80
Width = 121
Height = 21
BevelOuter = bvLowered
Caption = 'Final flame'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 4
end
object cbFlamesTo: TComboBox
Left = 129
Top = 80
Width = 310
Height = 21
Style = csDropDownList
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ItemIndex = 0
ParentFont = False
TabOrder = 5
Text = 'Current'
OnChange = cbFlamesChange
Items.Strings = (
'Current')
end
object chkResetLocation: TCheckBox
Left = 8
Top = 110
Width = 378
Height = 17
Caption = 'Reset location for each frame'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 6
end
object chkInvertBG: TCheckBox
Left = 8
Top = 130
Width = 378
Height = 17
Caption = 'Invert background color'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 7
end
end
object gbPreview: TGroupBox
Left = 5
Top = 160
Width = 450
Height = 220
Caption = 'Preview'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = [fsBold]
ParentFont = False
TabOrder = 1
object tbPlay: TSpeedButton
Left = 50
Top = 189
Width = 75
Height = 22
Hint = 'Play'
Caption = 'Play'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
Glyph.Data = {
36060000424D3606000000000000360000002800000020000000100000000100
18000000000000060000120B0000120B00000000000000000000FF00FFFF00FF
FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FFDEEAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFDEEAE0FF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FF096314DEEAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9FF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FF11681B04600FDEEAE0FF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9DE
EAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FF1A6F2420732C04600FDEEAE0FF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
EDD9DEEAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FF23752E2F833D20732C04600FDEEAE0FF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
EDD9D6EDD9D6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FF2E7C3750A25A2F833D20732C04600FDEEAE0FF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
EDD9D6EDD9D6EDD9DEEAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FF3883415DB06850A25A2F833D20732C0B6618DEEAE0FF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
EDD9D6EDD9D6EDD9D6EDD9DEEAE0FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FF438A4C6BBF766BBF7650A25A2F7639D6EDD9FF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
EDD9D6EDD9D6EDD9D6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FF4B90536BBF76A3DAB02F7639D6EDD9FF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
EDD9D6EDD9D6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FF52945AA3DAB02F7639D6EDD9FF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
EDD9D6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FF5898602F7639D6EDD9FF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9D6
EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FF589860D6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9D6EDD9FF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FFD6EDD9FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFD6EDD9FF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF}
NumGlyphs = 2
ParentFont = False
ParentShowHint = False
ShowHint = True
OnClick = tbPlayClick
end
object tbStop: TSpeedButton
Left = 140
Top = 189
Width = 75
Height = 22
Hint = 'Stop'
Caption = 'Stop'
Enabled = False
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
Glyph.Data = {
36060000424D3606000000000000360000002800000020000000100000000100
18000000000000060000120B0000120B00000000000000000000FF00FFFF00FF
FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFE39A75B66239B05C33A7532A9D4820923E1689340D822D06812C05FF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFE39770F3BCA0D7A183CE8D6DC17C59AF6B48A762409B5837812C05FF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFE79B74F9C9AFF5B594EDA37EE6956CDA8559CE794EAC6543853009FF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFEA9E78F9D0BBF8BDA1F4B090EF9F79E69268DC8459B46B488B360FFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFEFA37DFBD7C8F8C7ADF7B798F2AB88ED9F7AE6946DBE7755923E16FF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFF3A881FBE1D3F9CEBAF8BFA5F3B394F2A885EB9F7AD08D6C9A461EFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFF6AD86FBE5DAFBDACAF9CAB3F8C2A8F6B698F3B391DCA387A24E25FF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFAB08AFCE1D5FBE2D4FAD8C6F9CDB9F9CAB3F9C6ACF5BB9DAA552DFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFDB38DFAB08AF6AD86F3A881EFA37DEA9E78E79B74E39770E39A75FF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFF9C6ACF9C6ACF9C6ACF9C6ACF9
C6ACF9C6ACF9C6ACF9C6ACF9C6ACFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF}
NumGlyphs = 2
ParentFont = False
ParentShowHint = False
ShowHint = True
OnClick = tbStopClick
end
object pnlPreview: TPanel
Left = 16
Top = 24
Width = 240
Height = 160
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 0
object AnimPreview: TImage
Left = 0
Top = 0
Width = 240
Height = 160
PopupMenu = QualityPopup
end
end
end
end
end
object AnimStatus: TStatusBar
Left = 0
Top = 457
Width = 496
Height = 19
Panels = <>
SimplePanel = True
end
object btClose: TButton
Left = 399
Top = 427
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Caption = 'Close'
TabOrder = 3
OnClick = btCloseClick
end
object QualityPopup: TPopupMenu
Images = MainForm.Buttons
Left = 24
Top = 416
object mnuLowQuality: TMenuItem
Caption = 'Low Quality'
RadioItem = True
OnClick = mnuPreviewQualityClick
end
object mnuMediumQuality: TMenuItem
Tag = 1
Caption = 'Medium Quality'
Checked = True
RadioItem = True
OnClick = mnuPreviewQualityClick
end
object mnuHighQuality: TMenuItem
Tag = 2
Caption = 'High Quality'
RadioItem = True
OnClick = mnuPreviewQualityClick
end
end
end

831
Forms/Animate.pas Normal file
View File

@ -0,0 +1,831 @@
{ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina }
unit Animate;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, StdCtrls, ComCtrls, ExtCtrls,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Samples.Spin, Vcl.Buttons,
Menus, ControlPoint, RenderingInterface, Translation;
type
TAnimateForm = class(TForm)
seFPS: TSpinEdit;
seDuration: TSpinEdit;
edOutFlame: TEdit;
btSetFlame: TSpeedButton;
gbOutput: TGroupBox;
pnlFPS: TPanel;
pnlDuration: TPanel;
pnlOutFlame: TPanel;
btSaveAnimation: TButton;
pnlFrameWidth: TPanel;
pnlFrameHeight: TPanel;
seFrameWidth: TSpinEdit;
seFrameHeight: TSpinEdit;
pnlPrefix: TPanel;
edPrefix: TEdit;
cbAspectRatio: TComboBox;
pnlRatio: TPanel;
AnimPages: TPageControl;
tsSettings: TTabSheet;
chkListFlames: TCheckBox;
AnimStatus: TStatusBar;
gbFrame: TGroupBox;
tsAnimation: TTabSheet;
gbAnimType: TGroupBox;
cbAnimType: TComboBox;
pnlAnimType: TPanel;
pnlStartFlame: TPanel;
cbFlames: TComboBox;
pnlEndFlame: TPanel;
cbFlamesTo: TComboBox;
gbPreview: TGroupBox;
AnimPreview: TImage;
btClose: TButton;
chkResetLocation: TCheckBox;
chkRender: TCheckBox;
QualityPopup: TPopupMenu;
mnuLowQuality: TMenuItem;
mnuMediumQuality: TMenuItem;
mnuHighQuality: TMenuItem;
pnlFrameExt: TPanel;
cbFrameExt: TComboBox;
gbFrameQuality: TGroupBox;
pnlDensity: TPanel;
pnlFilter: TPanel;
pnlOversample: TPanel;
txtDensity: TComboBox;
txtFilterRadius: TEdit;
sbFilterRadius: TSpinButton;
seOversample: TSpinEdit;
lbSeconds: TLabel;
pnlPreview: TPanel;
tbPlay: TSpeedButton;
tbStop: TSpeedButton;
chkInvertBG: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btSaveAnimationClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure btSetFlameClick(Sender: TObject);
procedure cbAspectRatioChange(Sender: TObject);
procedure seFrameWidthChange(Sender: TObject);
procedure seFrameHeightChange(Sender: TObject);
procedure cbFlamesChange(Sender: TObject);
procedure cbAnimTypeChange(Sender: TObject);
procedure tbPlayClick(Sender: TObject);
procedure btCloseClick(Sender: TObject);
procedure mnuPreviewQualityClick(Sender: TObject);
procedure chkRenderClick(Sender: TObject);
procedure sbFilterRadiusDownClick(Sender: TObject);
procedure sbFilterRadiusUpClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure tbStopClick(Sender: TObject);
private
{ Private declarations }
totFrames: integer;
FrameWidth, FrameHeight: integer;
FrameRatio: double;
AnimPrefix, SaveAnimPath: string;
AnimType: shortint;
AnimCp, PreviewCp: TControlPoint;
PreviewDensity: double;
AnimRender: TRenderer;
AnimProc, DrawPreviewProc: TProc;
StatusGenerating, StatusFinished: string;
CurrentFlame: string;
StopAnimate: boolean;
StartBG: array [0..2] of byte;
procedure ARotateFlame;
procedure ARotateReference;
procedure ARotate3DCamera;
procedure ARotateGradient;
procedure ARotateHue;
procedure AMorphing;
procedure LerpBG(const i: integer);
procedure DoAnimate;
procedure FillFlameList;
procedure ChangeControlState(const activate: boolean);
public
{ Public declarations }
procedure UpdateControls;
end;
var
AnimateForm: TAnimateForm;
implementation
{$R *.dfm}
uses
Main, Editor, Global, XForm, XFormMan, CMap, FormRender, Registry;
procedure TAnimateForm.btCloseClick(Sender: TObject);
begin
AnimRender.Stop;
tbStopClick(Sender);
Close;
end;
procedure TAnimateForm.btSaveAnimationClick(Sender: TObject);
var
i: word;
FrameFolder: string;
begin
// AV: first we must check the output directory
SaveAnimPath := edOutFlame.Text;
if SaveAnimPath = '' then begin
Application.MessageBox(PChar(TextByKey('render-status-nofilename')),
ApophysisSVN, 48);
exit;
end;
if not DirectoryExists(ExtractFilePath(SaveAnimPath)) then
raise Exception.Create(TextByKey('render-status-pathdoesnotexist')); // AV
if FileExists(SaveAnimPath) then begin
if Application.MessageBox(PChar(
Format(TextByKey('render-status-fileexists-message1'),[SaveAnimPath]) +
#13#10 + TextByKey('render-status-fileexists-message2')),
ApophysisSVN, 52) = ID_NO then exit;
DeleteFile(SaveAnimPath);
end;
AnimPrefix := edPrefix.Text;
cbFlamesChange(Sender);
AnimCp.AdjustScale(FrameWidth, FrameHeight);
StopAnimate := False;
ChangeControlState(false);
if chkInvertBG.Checked then
for i := 0 to 2 do
StartBG[i] := AnimCp.background[i];
AnimProc := procedure
begin
MainForm.SaveXMLFlame(AnimCp, AnimCp.name, SaveAnimPath);
end;
DoAnimate;
if StopAnimate then begin
AnimStatus.SimpleText := TextByKey('animate-status-stopped');
exit;
end
else
AnimStatus.SimpleText := StatusFinished;
ChangeControlState(true);
if FileExists(SaveAnimPath) then
begin
if chkListFlames.Checked then
begin
OpenFile := SaveAnimPath;
OpenFileType := ftXML;
ListXML(SaveAnimPath, 1);
end;
if chkRender.Checked then
begin
if Assigned(RenderForm.Renderer) then
if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')),
ApophysisSVN, 36) = ID_NO then exit;
if Assigned(RenderForm.Renderer) then RenderForm.Renderer.Terminate;
if Assigned(RenderForm.Renderer) then RenderForm.Renderer.WaitFor; // hmm #1
RenderForm.ResetControls;
RenderForm.bRenderAll := true;
if Assigned(RenderForm.Renderer) then RenderForm.Renderer.WaitFor; // hmm #2
RenderForm.RenderFlameFile := SaveAnimPath;
SetLength(RenderForm.FlameNames, totFrames);
for i := 0 to totFrames - 1 do
RenderForm.FlameNames[i] := AnimPrefix + Format('%.3d', [i]);
if CreateAnimFolder then begin
FrameFolder := RemoveExt(SaveAnimPath) + '\';
CreateDir(FrameFolder); // create a separate folder for flames
end else
FrameFolder := ExtractFilePath(SaveAnimPath);
RenderForm.Filename := FrameFolder + AnimCp.name +
cbFrameExt.Items[cbFrameExt.ItemIndex];
renderFileFormat := cbFrameExt.ItemIndex + 1;
renderOversample := seOversample.Value;
renderFilterRadius := StrToFloat(txtFilterRadius.Text);
renderDensity := StrToFloat(txtDensity.Text);
renderWidth := seFrameWidth.Value;
renderHeight := seFrameHeight.Value;
SaveInFlame := False; // all flames are already saved
RenderForm.Show;
self.Close;
RenderForm.btnRenderClick(Sender);
end;
end;
end;
procedure TAnimateForm.btSetFlameClick(Sender: TObject);
begin
with MainForm.SaveDialog do begin
Filter := TextByKey('common-filter-flamefiles') + '|*.flame;*.xml|'
+ TextByKey('common-filter-allfiles') + '|*.*';
InitialDir := ParamFolder;
FileName := ExtractFileName(edOutFlame.Text);
if Execute then
begin
if ExtractFileExt(FileName) = '' then
FileName := FileName + '.flame';
edOutFlame.Text := FileName;
end;
end;
end;
procedure TAnimateForm.cbAnimTypeChange(Sender: TObject);
begin
AnimType := cbAnimType.ItemIndex;
if AnimType < 5 then
begin
cbFlamesTo.ItemIndex := cbFlames.ItemIndex;
cbFlamesTo.Enabled := False;
end
else begin
cbFlamesTo.Enabled := True;
end;
end;
procedure TAnimateForm.cbAspectRatioChange(Sender: TObject);
var
r: double;
begin
case cbAspectRatio.ItemIndex of
0, 1: FrameRatio := FrameWidth / FrameHeight;
2: FrameRatio := 1.5;
3: FrameRatio := 4 / 3;
4: FrameRatio := 1.25;
5: FrameRatio := 16 / 9;
6: FrameRatio := 1.6;
7: FrameRatio := 21 / 9;
end;
if FrameRatio > (pnlPreview.Width / pnlPreview.Height) then
begin
AnimPreview.Width := pnlPreview.Width;
r := FrameWidth / AnimPreview.Width;
AnimPreview.Height := round(FrameHeight / r);
AnimPreview.Left := 0;
AnimPreview.Top := (pnlPreview.Height - AnimPreview.Height) shr 1;
end
else begin
AnimPreview.Height := pnlPreview.Height;
r := FrameHeight / AnimPreview.height;
AnimPreview.Width := round(FrameWidth / r);
AnimPreview.Top := 0;
AnimPreview.Left := (pnlPreview.Width - AnimPreview.Width) shr 1;
end;
end;
procedure TAnimateForm.cbFlamesChange(Sender: TObject);
var
flameXML: string;
i: integer;
begin
i := cbFlames.ItemIndex;
if i < 0 then exit;
if i < (cbFlames.Items.Count - 1) then
begin
flameXML := LoadXMLFlameText(Openfile, cbFlames.Items[i]);
MainForm.ParseXML(AnimCp, flameXML, true);
end
else
AnimCp.Copy(MainCp);
seFrameWidth.Value := AnimCp.Width;
seFrameHeight.Value := AnimCp.Height;
cbAspectRatioChange(Sender);
DrawPreviewProc;
end;
procedure TAnimateForm.chkRenderClick(Sender: TObject);
begin
gbFrameQuality.Enabled := chkRender.Checked;
cbFrameExt.Enabled := chkRender.Checked;
end;
procedure TAnimateForm.FillFlameList;
var FItem: TListItem;
begin
cbFlames.Clear;
for FItem in MainForm.ListView1.Items do
cbFlames.AddItem(FItem.Caption, nil);
cbFlames.AddItem(MainCp.name + CurrentFlame, nil);
cbFlames.ItemIndex := cbFlames.Items.Count - 1;
cbFlamesTo.Items.Assign(cbFlames.Items);
cbFlamesTo.ItemIndex := cbFlames.ItemIndex;
end;
procedure TAnimateForm.LerpBG(const i: integer);
var
k, k1: double;
c: byte;
begin
//if (totFrames <= 1) then exit;
k := i / (totFrames - 1);
k1 := (1 - k);
for c := 0 to 2 do
AnimCp.background[c] := Round(k1 * StartBG[c] + k * (255 - StartBG[c]));
end;
procedure TAnimateForm.ARotateFlame;
var
j: integer;
i, nx: smallint;
rstep: double;
Triangles: TTriangles;
fx: TXForm;
begin
rstep := 2 * pi / totFrames;
nx := AnimCp.NumXForms;
fx := TXForm.Create;
fx.Assign(AnimCp.xform[nx]);
AnimCp.TrianglesFromCp(Triangles);
for j := 0 to totFrames - 1 do
begin
AnimStatus.SimpleText := Format(StatusGenerating, [j+1, totFrames]);
for i := -1 to nx - 1 do
Triangles[i] := RotateTriangle(Triangles[i], rstep * j);
AnimCp.GetFromTriangles(Triangles, nx);
AnimCp.xform[nx].Assign(fx);
if chkResetLocation.Checked then AnimCp.CalcBoundbox;
if chkInvertBG.Checked then LerpBG(j);
AnimCp.name := AnimPrefix + Format('%.3d', [j]);
AnimProc;
if StopAnimate then break;
end;
fx.Free;
end;
procedure TAnimateForm.ARotateReference;
var
j, nx: integer;
rstep: double;
Triangles: TTriangles;
fx: TXForm;
begin
rstep := 2 * pi / totFrames;
nx := AnimCp.NumXForms;
fx := TXForm.Create;
fx.Assign(AnimCp.xform[nx]);
AnimCp.TrianglesFromCp(Triangles);
for j := 0 to totFrames - 1 do
begin
AnimStatus.SimpleText := Format(StatusGenerating, [j+1, totFrames]);
Triangles[-1] := RotateTriangle(Triangles[-1], rstep * j);
AnimCp.GetFromTriangles(Triangles, nx);
AnimCp.xform[nx].Assign(fx);
if chkResetLocation.Checked then AnimCp.CalcBoundbox;
if chkInvertBG.Checked then LerpBG(j);
AnimCp.name := AnimPrefix + Format('%.3d', [j]);
AnimProc;
if StopAnimate then break;
end;
fx.Free;
end;
procedure TAnimateForm.ARotate3DCamera;
var
j: integer;
rstep: double;
begin
rstep := 2 * pi / totFrames;
for j := 0 to totFrames - 1 do
begin
AnimStatus.SimpleText := Format(StatusGenerating, [j+1, totFrames]);
AnimCp.cameraPitch := AnimCp.cameraPitch + rstep;
AnimCp.cameraYaw := AnimCp.cameraYaw + rstep;
AnimCp.cameraRoll := AnimCp.cameraRoll + rstep;
if chkResetLocation.Checked then AnimCp.CalcBoundbox;
if chkInvertBG.Checked then LerpBG(j);
AnimCp.name := AnimPrefix + Format('%.3d', [j]);
AnimProc;
if StopAnimate then break;
end;
end;
procedure TAnimateForm.ARotateGradient;
var
i, j, n: integer;
rstep: double;
SourceMap: TColorMap;
begin
SourceMap := AnimCp.cmap;
rstep := 256 / totFrames;
for j := 0 to totFrames - 1 do
begin
AnimStatus.SimpleText := Format(StatusGenerating, [j+1, totFrames]);
for i := 0 to 255 do
begin
n := (256 + i - Round(rstep * j)) mod 256;
AnimCp.cmap[i,0] := SourceMap[n,0];
AnimCp.cmap[i,1] := SourceMap[n,1];
AnimCp.cmap[i,2] := SourceMap[n,2];
end;
if chkInvertBG.Checked then LerpBG(j);
AnimCp.name := AnimPrefix + Format('%.3d', [j]);
AnimProc;
if StopAnimate then break;
end;
end;
procedure TAnimateForm.ARotateHue;
var
j: integer;
h: double;
begin
h := 1 / totFrames;
for j := 0 to totFrames - 1 do
begin
AnimStatus.SimpleText := Format(StatusGenerating, [j+1, totFrames]);
AnimCp.hue_rotation := h;
RotateCMapHue(AnimCp);
AnimCp.hue_rotation := 1;
if chkInvertBG.Checked then LerpBG(j);
AnimCp.name := AnimPrefix + Format('%.3d', [j]);
AnimProc;
if StopAnimate then break;
end;
end;
procedure TAnimateForm.AMorphing;
var
j: integer;
t: smallint;
SourceCp, TargetCp: TControlPoint;
flameXML: string;
begin
j := cbFlamesTo.ItemIndex;
if j = cbFlames.ItemIndex then begin
Application.MessageBox(PChar(TextByKey('animate-status-changeflame')),
ApophysisSVN, 48);
exit;
end;
SourceCp := AnimCp.Clone;
SourceCp.time := 0;
if j < (cbFlamesTo.Items.Count - 1) then
begin
TargetCp := TControlPoint.Create;
flameXML := LoadXMLFlameText(Openfile, cbFlamesTo.Items[j]);
MainForm.ParseXML(TargetCp, flameXML, true);
end
else
TargetCp := MainCp.Clone;
TargetCp.time := totFrames - 1;
PrepareToInterpolation(SourceCp, TargetCp); // adjust non-common parameters
if chkInvertBG.Checked then
for j := 0 to 2 do // invert target background
TargetCp.background[j] := 255 - SourceCp.background[j];
t := AnimType - 5; // interpolation type
try
for j := 0 to totFrames - 1 do
begin
AnimStatus.SimpleText := Format(StatusGenerating, [j+1, totFrames]);
AnimCp.InterpolateAll(SourceCp, TargetCp, j, t);
if chkResetLocation.Checked then AnimCp.CalcBoundbox;
AnimCp.name := AnimPrefix + Format('%.3d', [j]);
AnimProc;
if StopAnimate then break;
end;
finally
SourceCp.Free;
TargetCp.Free;
end;
end;
procedure TAnimateForm.DoAnimate;
begin
totFrames := seFPS.Value * seDuration.Value;
try
case AnimType of
0: ARotateFlame;
1: ARotateReference;
2: ARotate3DCamera;
3: ARotateGradient;
4: ARotateHue;
5..8: AMorphing;
end;
except
// TODO
end;
end;
procedure TAnimateForm.FormClose(Sender: TObject; var Action: TCloseAction);
var
Registry: TRegistry;
begin
{ Write position to registry }
Registry := TRegistry.Create;
try
Registry.RootKey := HKEY_CURRENT_USER;
if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Animate', True) then
begin
Registry.WriteInteger('Top', self.Top);
Registry.WriteInteger('Left', self.Left);
Registry.WriteBool('ResetLocation', chkResetLocation.Checked);
Registry.WriteBool('ListFlames', chkListFlames.Checked);
Registry.WriteBool('RenderFrames', chkRender.Checked);
Registry.WriteInteger('AnimationType', cbAnimType.ItemIndex);
end;
finally
Registry.Free;
end;
end;
procedure TAnimateForm.FormCreate(Sender: TObject);
begin
self.Caption := TextByKey('animate-title');
tsSettings.Caption := TextByKey('animate-general');
tsAnimation.Caption := TextByKey('animate-animation');
gbOutput.Caption := TextByKey('animate-output');
pnlOutFlame.Caption := TextByKey('animate-outflame');
pnlPrefix.Caption := TextByKey('animate-prefix');
gbPreview.Caption := TextByKey('animate-preview');
pnlFrameExt.Caption := TextByKey('animate-graphicext');
pnlDuration.Caption := TextByKey('animate-duration');
lbSeconds.Caption := TextByKey('common-seconds');
pnlFPS.Caption := TextByKey('animate-fps');
gbFrame.Caption := TextByKey('animate-frame');
pnlFrameWidth.Caption := TextByKey('common-width');
pnlFrameHeight.Caption := TextByKey('common-height');
pnlRatio.Caption := TextByKey('adjustment-tab-size-ratio');
cbAspectRatio.Items[0] := TextByKey('adjustment-tab-size-custom');
cbAspectRatio.Items[1] := TextByKey('common-keepaspect');
cbAspectRatio.ItemIndex := 1; // keep current aspect ratio
gbFrameQuality.Caption := TextByKey('common-quality');
pnlFilter.Caption := TextByKey('common-filterradius');
pnlDensity.Caption := TextByKey('common-density');
pnlOversample.Caption := TextByKey('common-oversample');
gbAnimType.Caption := TextByKey('animate-parameters');
pnlAnimType.Caption := TextByKey('animate-type');
chkListFlames.Caption := TextByKey('animate-showframes');
chkRender.Caption := TextByKey('animate-render');
chkResetLocation.Caption := TextByKey('animate-resetlocation');
chkInvertBG.Caption := TextByKey('animate-invertbg');
tbPlay.Caption := TextByKey('common-start');
btSaveAnimation.Caption := TextByKey('animate-save');
btClose.Caption := TextByKey('common-close');
btSetFlame.Hint := TextByKey('common-browse');
StatusGenerating := TextByKey('animate-status-generating');
StatusFinished := TextByKey('animate-status-finished');
CurrentFlame := #32 + TextByKey('animate-currentflame');
pnlStartFlame.Caption := TextByKey('animate-initflame');
pnlEndFlame.Caption := TextByKey('animate-finalflame');
tbPlay.Hint := TextByKey('animate-playhint');
tbStop.Hint := TextByKey('animate-stophint');
tbStop.Caption := TextByKey('animate-stop');
btSaveAnimation.Hint := TextByKey('animate-savehint');
cbAnimType.Items[0] := TextByKey('animate-kind-rotateflame');
cbAnimType.Items[1] := TextByKey('animate-kind-rotatereference');
cbAnimType.Items[2] := TextByKey('animate-kind-rotatecamera');
cbAnimType.Items[3] := TextByKey('animate-kind-rotatepalette');
cbAnimType.Items[4] := TextByKey('animate-kind-rotatehue');
cbAnimType.Items[5] := TextByKey('animate-kind-morph1');
cbAnimType.Items[6] := TextByKey('animate-kind-morph2');
cbAnimType.Items[7] := TextByKey('animate-kind-morph3');
cbAnimType.Items[8] := TextByKey('animate-kind-morph4');
cbAnimType.ItemIndex := 0;
mnuLowQuality.Caption := TextByKey('common-lowquality');
mnuMediumQuality.Caption := TextByKey('common-mediumquality');
mnuHighQuality.Caption := TextByKey('common-highquality');
case AnimPrevQual of
0: begin
PreviewDensity := prevLowQuality;
mnuLowQuality.Checked := True;
end;
1: begin
PreviewDensity := prevMediumQuality;
mnuMediumQuality.Checked := True;
end;
2: begin
PreviewDensity := prevHighQuality;
mnuHighQuality.Checked := True;
end;
end;
AnimCp := TControlPoint.Create;
PreviewCp := TControlPoint.Create;
AnimRender := TRenderer.Create;
DrawPreviewProc := procedure
begin
PreviewCp.Copy(AnimCp);
PreviewCp.sample_density := PreviewDensity;
PreviewCp.AdjustScale(AnimPreview.Width, AnimPreview.Height);
AnimRender.Stop;
AnimRender.SetCP(PreviewCp);
AnimRender.Render;
AnimPreview.Picture.Graphic := AnimRender.GetImage;
Application.ProcessMessages;
end;
end;
procedure TAnimateForm.FormDestroy(Sender: TObject);
begin
AnimCp.Free;
PreviewCp.Free;
AnimRender.Free;
end;
procedure TAnimateForm.FormShow(Sender: TObject);
var
Registry: TRegistry;
begin
{ Read position from registry }
Registry := TRegistry.Create;
try
Registry.RootKey := HKEY_CURRENT_USER;
if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Animate', False) then
begin
if Registry.ValueExists('Left') then
self.Left := Registry.ReadInteger('Left');
if Registry.ValueExists('Top') then
self.Top := Registry.ReadInteger('Top');
if Registry.ValueExists('ResetLocation') then
chkResetLocation.Checked := Registry.ReadBool('ResetLocation');
if Registry.ValueExists('ListFlames') then
chkListFlames.Checked := Registry.ReadBool('ListFlames');
if Registry.ValueExists('RenderFrames') then
chkRender.Checked := Registry.ReadBool('RenderFrames');
if Registry.ValueExists('AnimationType') then
cbAnimType.ItemIndex := Registry.ReadInteger('AnimationType');
Registry.CloseKey;
end;
finally
Registry.Free;
end;
cbFrameExt.ItemIndex := defFrameExt;
txtDensity.Text := FloatToStr(renderDensity);
txtFilterRadius.Text := FloatToStr(Round6(renderFilterRadius));
seOversample.Value := renderOversample;
edPrefix.Text := defAnimPrefix;
seFPS.Value := AnimFPS;
edOutFlame.Text := ParamFolder + MainCp.name + ' (animated).flame';
chkRenderClick(Sender);
cbAnimTypeChange(Sender);
UpdateControls;
end;
procedure TAnimateForm.mnuPreviewQualityClick(Sender: TObject);
begin
if TMenuItem(Sender).Checked then exit; // prevent unneseccary updating
TMenuItem(Sender).Checked := True;
case TMenuItem(Sender).Tag of
0: PreviewDensity := prevMediumQuality;
1: PreviewDensity := prevMediumQuality;
2: PreviewDensity := prevHighQuality;
end;
AnimPrevQual := TMenuItem(Sender).Tag;
DrawPreviewProc;
end;
procedure TAnimateForm.sbFilterRadiusDownClick(Sender: TObject);
var n: double;
begin
try
n := StrToFloat(txtFilterRadius.Text);
n := Round6(n - 0.05);
if (n > 0) then
txtFilterRadius.Text := FloatToStr(n);
except
raise Exception.Create(TextByKey('render-status-invalidfilterradius'));
end;
end;
procedure TAnimateForm.sbFilterRadiusUpClick(Sender: TObject);
var n: double;
begin
try
n := StrToFloat(txtFilterRadius.Text);
txtFilterRadius.Text := Format('%.3g', [n + 0.05]);
except
raise Exception.Create(TextByKey('render-status-invalidfilterradius'));
end;
end;
procedure TAnimateForm.seFrameHeightChange(Sender: TObject);
begin
try
FrameHeight := seFrameHeight.Value;
if (cbAspectRatio.ItemIndex > 0) and seFrameHeight.Focused then
begin
FrameWidth := Round(FrameHeight * FrameRatio);
seFrameWidth.Value := FrameWidth;
end;
except
end;
end;
procedure TAnimateForm.seFrameWidthChange(Sender: TObject);
begin
try
FrameWidth := seFrameWidth.Value;
if (cbAspectRatio.ItemIndex > 0) and seFrameWidth.Focused then
begin
FrameHeight := Round(FrameWidth / FrameRatio);
seFrameHeight.Value := FrameHeight;
end;
except
end;
end;
procedure TAnimateForm.tbPlayClick(Sender: TObject);
var i: byte;
begin
StopAnimate := False;
cbFlamesChange(Sender);
ChangeControlState(false);
if chkInvertBG.Checked then
for i := 0 to 2 do
StartBG[i] := AnimCp.background[i];
AnimProc := DrawPreviewProc;
DoAnimate;
AnimStatus.SimpleText := '';
ChangeControlState(true);
end;
procedure TAnimateForm.tbStopClick(Sender: TObject);
begin
StopAnimate := True;
ChangeControlState(true);
end;
procedure TAnimateForm.ChangeControlState(const activate: boolean);
begin
gbFrame.Enabled := activate;
gbAnimType.Enabled := activate;
btSaveAnimation.Enabled := activate;
tbPlay.Enabled := activate;
tbStop.Enabled := not activate;
end;
procedure TAnimateForm.UpdateControls;
begin
FillFlameList;
cbFlamesChange(self);
end;
end.

View File

@ -204,7 +204,7 @@ object GradientBrowser: TGradientBrowser
end
end
object SmallImages: TImageList
Left = 192
Left = 224
Top = 24
Bitmap = {
494C010101000400040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
@ -363,12 +363,12 @@ object GradientBrowser: TGradientBrowser
object OpenDialog: TOpenDialog
DefaultExt = 'ugr'
Filter = 'Gradient files (*.ugr)|*.ugr|Fractint map files (*.map)|*.map'
Left = 136
Left = 160
Top = 24
end
object TooltipTimer: TTimer
OnTimer = TooltipTimerTimer
Left = 88
Left = 96
Top = 20
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,11 +28,7 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, ComCtrls, ToolWin, ImgList, StdCtrls, System.ImageList,
Cmap, Menus, Global, Buttons, Translation;
const
PixelCountMax = 32768;
PaletteTooltipTimeout = 1500;
Cmap, Menus, Global, Buttons;
type
TGradientBrowser = class(TForm)
@ -64,10 +60,10 @@ type
procedure ListViewInfoTip(Sender: TObject; Item: TListItem;
var InfoTip: String);
procedure TooltipTimerTimer(Sender: TObject);
// AV: now you really can rename it :-)
function RenameGradient(OldIdent: string; var NewIdent: string): boolean;
procedure btnRandomClick(Sender: TObject); // AV
private
// AV: now you really can rename it :-)
function RenameGradient(OldIdent: string; var NewIdent: string): boolean;
procedure DrawPalette;
procedure Apply;
public
@ -78,22 +74,24 @@ type
function LoadFractintMap(filen: string): TColorMap;
end;
{ // AV: we already have this declarations in other units (Cmap and Global)!
type
EFormatInvalid = class(Exception);
pRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = array[0..PixelCountMax - 1] of TRGBTriple;
}
var
GradientBrowser: TGradientBrowser;
function CreatePalette(strng: string): TColorMap;
implementation
uses Main, Options, Editor, Registry, Adjust, Mutate;
uses
Main, Options, Editor, Registry, Adjust, Mutate, Translation;
{$R *.DFM}
(* // AV: exactly the same functions we have in Cmap unit
function GetVal(token: string): string;
var
p: integer;
@ -118,6 +116,7 @@ begin
end;
Result := str;
end;
*)
function TGradientBrowser.LoadFractintMap(filen: string): TColorMap;
var
@ -140,10 +139,12 @@ begin
CloseFile(MapFile);
Result := Pal;
except
on EInOutError do Application.MessageBox(PChar(Format(TextByKey('common-genericopenfailure'), [FileName])), PCHAR('Apophysis'), 16);
on EInOutError do
raise Exception.CreateFmt(TextByKey('common-genericopenfailure'), [FileName]);
end;
end;
(* // AV: moved into Cmap unit
function CreatePalette(strng: string): TColorMap;
{ Loads a palette from a gradient string }
var
@ -209,7 +210,7 @@ begin
RGBBlend(a, b, Result);
end;
except on EFormatInvalid do
// Result := False;
//
end;
finally
Tokens.Free;
@ -218,6 +219,7 @@ begin
Colors.Free;
end;
end;
*)
procedure TGradientBrowser.DrawPalette;
var
@ -338,6 +340,11 @@ begin
DeleteItem.Caption := TextByKey('common-delete');
RenameItem.Caption := TextByKey('common-rename');
btnRandom.Hint := TextByKey('adjustment-tab-gradient-presethint');
// AV: moved this here since it never changes
OpenDialog.Filter := Format('%s|*.gradient;*.ugr|%s|*.map|%s|*.*',
[TextByKey('common-filter-gradientfiles'),
TextByKey('common-filter-fractintfiles'),
TextByKey('common-filter-allfiles')]);
end;
procedure TGradientBrowser.FormShow(Sender: TObject);
@ -373,8 +380,8 @@ begin
if ListView.SelCount <> 0 then
begin
if ConfirmDelete then
c := Application.MessageBox(
PChar(Format(TextByKey('common-confirmdelete'), [ListView.Selected.Caption])), 'Apophysis', 36) = IDYES
c := Application.MessageBox(PChar(Format(TextByKey('common-confirmdelete'),
[ListView.Selected.Caption])), 'Apophysis', 36) = IDYES
else
c := True;
if c then
@ -415,7 +422,8 @@ begin
end
else
Result := False;
except on Exception do Result := False;
except on Exception do
Result := False;
end;
finally
Strings.Free;
@ -424,7 +432,7 @@ end;
procedure TGradientBrowser.RenameItemClick(Sender: TObject);
begin
if ListView.SelCount <> 0 then
if ListView.Selected <> nil then
ListView.Items[ListView.Selected.Index].EditCaption;
end;
@ -437,21 +445,15 @@ begin
end;
procedure TGradientBrowser.btnDefGradientClick(Sender: TObject);
var
fn:string;
begin
OpenDialog.InitialDir := BrowserPath;
OpenDialog.Filter := Format('%s|*.gradient;*.ugr|%s|*.map|%s|*.*',
[TextByKey('common-filter-gradientfiles'),
TextByKey('common-filter-fractintfiles'),
TextByKey('common-filter-allfiles')]);
OpenDialog.FileName := '';
if OpenSaveFileDialog(GradientBrowser, OpenDialog.DefaultExt, OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
//if OpenDialog.Execute then
//if OpenSaveFileDialog(GradientBrowser, OpenDialog.DefaultExt, OpenDialog.Filter, OpenDialog.InitialDir, TextByKey('common-browse'), fn, true, false, false, true) then
if OpenDialog.Execute then
begin
Filename := fn; //OpenDialog.FileName;
Filename := OpenDialog.FileName;
GradientFile := Filename;
BrowserPath := ExtractFilePath(fn); //ExtractFilePath(OpenDialog.FileName);
BrowserPath := ExtractFilePath(Filename);
ListFileContents;
end;
end;
@ -512,6 +514,8 @@ end;
procedure TGradientBrowser.ListViewInfoTip(Sender: TObject;
Item: TListItem; var InfoTip: String);
const
PaletteTooltipTimeout = 1500;
var
i, j: integer;
Row: pRGBTripleArray;

View File

@ -61,29 +61,15 @@ object ColorSelection: TColorSelection
object StartColor: TShape
Left = 10
Top = 40
Width = 30
Width = 40
Height = 22
end
object LastColor: TShape
Left = 140
Left = 150
Top = 40
Width = 30
Width = 40
Height = 22
end
object lbStart: TLabel
Left = 8
Top = 16
Width = 94
Height = 13
Caption = 'Start palette index:'
end
object lbLast: TLabel
Left = 140
Top = 16
Width = 90
Height = 13
Caption = 'Last palette index:'
end
object btOK: TButton
Left = 101
Top = 82
@ -107,9 +93,9 @@ object ColorSelection: TColorSelection
TabOrder = 1
end
object SpinStart: TSpinEdit
Left = 40
Left = 50
Top = 40
Width = 70
Width = 80
Height = 22
MaxValue = 253
MinValue = 0
@ -119,9 +105,9 @@ object ColorSelection: TColorSelection
OnKeyPress = SpinValueKeyPress
end
object SpinLast: TSpinEdit
Left = 170
Left = 190
Top = 40
Width = 70
Width = 80
Height = 22
MaxValue = 255
MinValue = 2
@ -130,4 +116,22 @@ object ColorSelection: TColorSelection
OnChange = SpinLastChange
OnKeyPress = SpinValueKeyPress
end
object lbStart: TPanel
Left = 10
Top = 19
Width = 120
Height = 21
BevelOuter = bvLowered
Caption = 'Start palette index:'
TabOrder = 4
end
object lbLast: TPanel
Left = 150
Top = 19
Width = 120
Height = 21
BevelOuter = bvLowered
Caption = 'Last palette index:'
TabOrder = 5
end
end

View File

@ -5,9 +5,10 @@ unit ColorRangeForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, ComCtrls, StdCtrls, ExtCtrls, Vcl.Forms, Vcl.Dialogs, Adjust, Translation,
Vcl.Samples.Spin;
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Controls, ComCtrls, StdCtrls, ExtCtrls, Vcl.Dialogs,
Vcl.Forms, Vcl.Graphics,Vcl.Samples.Spin, Adjust, Translation;
type
TColorSelection = class(TForm)
btOK: TButton;
@ -16,8 +17,8 @@ type
SpinLast: TSpinEdit;
StartColor: TShape;
LastColor: TShape;
lbStart: TLabel;
lbLast: TLabel;
lbStart: TPanel;
lbLast: TPanel;
procedure FormCreate(Sender: TObject);
procedure btOKClick(Sender: TObject);
procedure FormShow(Sender: TObject);

View File

@ -1,125 +0,0 @@
object CurvesForm: TCurvesForm
Left = 197
Top = 111
BorderStyle = bsDialog
Caption = 'Curves'
ClientHeight = 492
ClientWidth = 489
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'System'
Font.Style = []
OldCreateOrder = False
OnClose = FormClose
OnCreate = FormCreate
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 16
object Label1: TLabel
Left = 8
Top = 16
Width = 75
Height = 13
Caption = 'Selected curve:'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
end
object CurvesPanel: TPanel
Left = 8
Top = 68
Width = 473
Height = 414
BevelOuter = bvNone
Color = clBlack
ParentBackground = False
TabOrder = 0
end
object cbChannel: TComboBox
Left = 8
Top = 35
Width = 185
Height = 21
Style = csDropDownList
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ItemIndex = 0
ParentFont = False
TabOrder = 1
Text = 'Overall'
OnChange = cbChannelChange
Items.Strings = (
'Overall'
'Red'
'Green'
'Blue')
end
object tbWeightLeft: TScrollBar
Left = 326
Top = 8
Width = 155
Height = 21
Max = 160
PageSize = 0
Position = 80
TabOrder = 2
OnChange = tbWeightChange
OnScroll = tbWeightScroll
end
object tbWeightRight: TScrollBar
Left = 326
Top = 35
Width = 155
Height = 21
Max = 160
PageSize = 0
Position = 80
TabOrder = 3
OnChange = tbWeightChange
OnScroll = tbWeightScroll
end
object Panel2: TPanel
Left = 199
Top = 8
Width = 121
Height = 21
Cursor = crHandPoint
BevelOuter = bvLowered
Caption = ' First CP weight:'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 4
end
object Panel1: TPanel
Left = 199
Top = 35
Width = 121
Height = 21
Cursor = crHandPoint
BevelOuter = bvLowered
Caption = ' Second CP weight:'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 5
end
end

View File

@ -1,123 +0,0 @@
unit Curves;
interface
uses Windows, Classes, Graphics, Forms, Controls, CurvesControl, Vcl.ExtCtrls,
Vcl.StdCtrls, Vcl.ComCtrls, ControlPoint, Registry, Global;
type
TCurvesForm = class(TForm)
CurvesPanel: TPanel;
cbChannel: TComboBox;
tbWeightLeft: TScrollBar;
tbWeightRight: TScrollBar;
Panel2: TPanel;
Panel1: TPanel;
Label1: TLabel;
procedure FormShow(Sender: TObject);
procedure cbChannelChange(Sender: TObject);
procedure tbWeightChange(Sender: TObject);
procedure tbWeightScroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
published
CurvesControl: TCurvesControl;
public
procedure SetCp(cp: TControlPoint);
end;
var
CurvesForm: TCurvesForm;
implementation
uses Main;
{$R *.DFM}
procedure TCurvesForm.tbWeightScroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
begin
if ScrollCode = scEndScroll then
CurvesControl.UpdateFlame;
end;
procedure TCurvesForm.SetCp(cp: TControlPoint);
begin
if CurvesControl = nil then Exit;
CurvesControl.SetCp(cp);
end;
procedure TCurvesForm.cbChannelChange(Sender: TObject);
begin
if CurvesControl = nil then Exit;
CurvesControl.ActiveChannel := TCurvesChannel(cbChannel.ItemIndex);
tbWeightLeft.Position := Round(CurvesControl.WeightLeft * 10);
tbWeightRight.Position := Round(CurvesControl.WeightRight * 10);
end;
procedure TCurvesForm.FormClose(Sender: TObject; var Action: TCloseAction);
var
Registry: TRegistry;
begin
{ Write position to registry }
Registry := TRegistry.Create;
try
Registry.RootKey := HKEY_CURRENT_USER;
if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Curves', True) then
begin
Registry.WriteInteger('Top', self.Top);
Registry.WriteInteger('Left', self.Left);
end;
finally
Registry.Free;
end;
// bStop := True;
end;
procedure TCurvesForm.FormCreate(Sender: TObject);
begin
//
end;
procedure TCurvesForm.FormShow(Sender: TObject);
var Registry: TRegistry;
begin
if not (assigned(curvesControl)) then
begin
CurvesControl := TCurvesControl.Create(self);
CurvesControl.Align := alClient;
CurvesControl.Parent := CurvesPanel;
end;
Registry := TRegistry.Create;
try
Registry.RootKey := HKEY_CURRENT_USER;
if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Curves', False) then
begin
if Registry.ValueExists('Left') then
self.Left := Registry.ReadInteger('Left');
if Registry.ValueExists('Top') then
self.Top := Registry.ReadInteger('Top');
Registry.CloseKey;
end;
finally
Registry.Free;
end;
tbWeightLeft.Position := Round(CurvesControl.WeightLeft * 10);
tbWeightRight.Position := Round(CurvesControl.WeightRight * 10);
SetCp(MainCp);
end;
procedure TCurvesForm.tbWeightChange(Sender: TObject);
begin
CurvesControl.WeightLeft := tbWeightLeft.Position / 10.0;
CurvesControl.WeightRight := tbWeightRight.Position / 10.0;
end;
end.

View File

@ -419,6 +419,31 @@ object EditForm: TEditForm
Style = tbsDropDown
OnClick = InsertPi1Click
end
object ToolButton7: TToolButton
Left = 655
Top = 0
Width = 8
Caption = 'ToolButton7'
ImageIndex = 33
Style = tbsSeparator
end
object tbComment: TToolButton
Left = 663
Top = 0
Caption = 'tbComment'
ImageIndex = 45
ParentShowHint = False
ShowHint = True
OnClick = tbCommentClick
end
object SaveFlameState: TToolButton
Left = 687
Top = 0
ImageIndex = 46
ParentShowHint = False
ShowHint = True
OnClick = SaveFlameStateClick
end
end
end
object EditPnl: TPanel
@ -497,7 +522,7 @@ object EditForm: TEditForm
Top = 79
Width = 298
Height = 413
ActivePage = TabVariables
ActivePage = tabVariations
Anchors = [akLeft, akTop, akRight, akBottom]
MultiLine = True
ParentShowHint = False
@ -541,9 +566,9 @@ object EditForm: TEditForm
TabOrder = 0
OnResize = TrianglePanelResize
object TriangleToolBar: TToolBar
Left = 28
Left = 15
Top = 218
Width = 163
Width = 200
Height = 28
ParentCustomHint = False
Align = alNone
@ -622,8 +647,19 @@ object EditForm: TEditForm
ParentShowHint = False
ShowHint = True
end
object tbSyncTriangles: TToolButton
Left = 161
Top = 0
Caption = 'tbSyncTriangles'
DropdownMenu = mnuSyncTriangles
ImageIndex = 44
ParentShowHint = False
ShowHint = True
Style = tbsDropDown
OnClick = tbSyncTrianglesClick
end
object GroupBox5: TGroupBox
end
object gbTrgOperations: TGroupBox
Left = 20
Top = 112
Width = 177
@ -1078,7 +1114,7 @@ object EditForm: TEditForm
'0.01')
end
end
object GroupBox6: TGroupBox
object gbCoordinates: TGroupBox
Left = 6
Top = 0
Width = 209
@ -1438,7 +1474,7 @@ object EditForm: TEditForm
OnUpClick = SpinButtonUpClick
end
end
object GroupBox3: TGroupBox
object gbPivot: TGroupBox
Left = 6
Top = 248
Width = 209
@ -1623,7 +1659,7 @@ object EditForm: TEditForm
OnUpClick = SpinButtonUpClick
end
end
object GroupBox10: TGroupBox
object gbFlip: TGroupBox
Left = 6
Top = 319
Width = 209
@ -3068,7 +3104,7 @@ object EditForm: TEditForm
DesignSize = (
290
367)
object Label4: TLabel
object lblSearch: TLabel
Left = 2
Top = 8
Width = 37
@ -3137,6 +3173,7 @@ object EditForm: TEditForm
Height = 21
Anchors = [akLeft, akTop, akRight]
TabOrder = 0
TextHint = 'type a name...'
OnChange = chkCollapseVariationsClick
end
object btnVarOrder: TBitBtn
@ -3215,7 +3252,9 @@ object EditForm: TEditForm
Items.Strings = (
'Show all variations'
'Hide unused variations'
'Favourite variations')
'Favourite variations'
'3D-aware variations'
'Direct coloring variations')
end
end
object TabVariables: TTabSheet
@ -3627,136 +3666,264 @@ object EditForm: TEditForm
Left = 313
Top = 40
Bitmap = {
494C01012B003000040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
000000000000360000002800000040000000B0000000010020000000000000B0
494C01012F004000040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
000000000000360000002800000040000000C0000000010020000000000000C0
000000000000000000000000000000000000A449A300A449A300A449A300A449
A300A449A300A449A30000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000DEE0DF009EA2
A0008B908E008B908E008B908E008A8F8D008A8F8D00898F8D00898E8C00898E
8C00888E8C009A9E9C00DDDEDD0000000000F8F8F807C6C6C639C5C5C53AC5C5
C53AC5C5C53AC5C5C53AC5C5C53AC5C5C53ACACACA35FAFAFA05FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000A449A300BD6ABD00BD6ABD00BD6A
BD00A449A300000000000000000000000000000000006E9B7000FCFDFD000000
00000000000000000000000000000000000000000000000000009EA3A100EBED
EC00FEFFFE00FEFFFF00FEFFFF00000000000000000000000000000000000000
000000000000EEEFEF00999E9C0000000000C6C6C639F7F7F6FEF9F9F9FFFBFB
FBFFFBFBFBFFFCFCFCFFFDFDFDFFFFFFFFFFEAE9E9FE9C9C9AC7F5F5F50AFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000A449A300BD6ABD00BD6ABD00A449
A30000000000000000000000000000000000000000004F885300619765000000
00000000000000000000000000000000000000000000000000008F959200FEFE
FE00EAEDEC00EAEDEC00EBEEED00ECEFEE00EDEFEE00EDF0EF00EEF0EF00EEF0
EF00EEF0EF00FEFFFF008D929000FBFCFB00C5C5C53AF7F7F6FFF8F8F8FFFAFA
FAFFFBFBFBFFFCFCFCFFFDFDFDFFFEFEFEFFF4F4F4FFCCCCCCFF979793D5EDED
ED12FFFFFF00FFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000A449A300BD6ABD00A449A3000000
0000C6D7C7005789590023662700266B2B002A712F0053995A00569D5E006FA5
730000000000000000000000000000000000000000000000000091969400FDFE
FE00E7EAE900858A8800858A8800858A880000000000005CCE00BACFE500E9EC
EB00EAEDEC00FEFEFE008E939100FBFCFC00C5C5C53AF6F6F6FFF7F7F7FF9191
BFFFECECF1FF9595C4FFFCFCFCFFFEFEFEFFFBFBFBFFC4C4C4FFFDFDFDFF9999
94D5F5F5F50AFFFFFF00FFFFFF00FFFFFF000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000A449A300A449A30000000000C6D7
C7004D82500060A7680081C88C0084C98E0087CA91008ACB94008DCD970060A7
6800529B5A00000000000000000000000000000000000000000092989600FDFE
FD00E4E8E700E3E7E500E3E8E600E4E8E600005CCE000000000036576B00005C
CE00B8CDE200FEFEFE0090969400FAFBFB00C5C5C53AF6F6F5FFF6F6F6FF3236
C2FF2A2EB8FF3339C3FFFCFCFCFFFEFEFEFFFEFEFEFFE0E0E0FFC6C6C6FFCFCF
CEFFA2A09FC7FAFAFA05FFFFFF00FFFFFF000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000A449A30000000000000000007AA2
7C005BA1630082C88D0051975800317A360035803B005DA4650062A96A0075B1
7B00000000000000000000000000000000000000000000000000949A9700FDFD
FD00E1E6E300858A8800858A8800858A8800858A8800005CCE003EAFFC000079
F500005CCE00A2C3EC0092979500FBFBFB00C5C5C53AF5F5F4FFF5F5F5FF3337
C4FF0108DAFF373AC3FFFBFBFBFFFDFDFDFFFEFEFEFFFEFEFEFFFCFCFCFFFAFA
FAFFF0EFEFFECACACA35FFFFFF00FFFFFF000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000407C
4400296F2E002D753300639B6800000000000000000062A3670071AE7700FEFE
FE00F9FCF9000000000000000000000000000000000000000000969B9900FDFD
FD00DDE3E000DCE1DF00DCE2DF00DDE2E000DDE2E000005CCE0000D4F5003EAF
FC000079F500005CCE004B7BB200FCFCFC00C5C5C53AF4F4F4FFF4F4F4FF3B3E
C2FF0409CFFF3E41C2FFFAFAFAFFFCFCFCFFFDFDFDFFFDFDFDFFFEFEFEFFFEFE
FEFFFEFEFEFFC5C5C53AFFFFFF00FFFFFF000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000CC483F00CC483F00CC483F00CC48
3F00CC483F00CC483F00CC483F00CC483F000000000082B98800000000000000
0000000000000000000000000000000000000000000000000000979D9B00FDFD
FD00DAE0DD00858A8800858A8800858A8800858A8800858A8800005CCE0000D4
F5003EAFFC000079F500005CCE0080ADE500C5C5C53AF4F4F3FFF3F3F2FF3A3E
BCFF060BC3FF3D40BCFFFAFAFAFFFBFBFBFFFCFCFCFFFCFCFCFFFDFDFDFFFDFD
FDFFFDFDFDFFC5C5C53AFFFFFF00FFFFFF000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000CC483F00E8A20000E8A20000E8A2
0000E8A20000E8A20000CC483F0080B585000000000000000000241CED00241C
ED00241CED00241CED00241CED00241CED000000000000000000999F9D00FDFD
FD00D9DFDC00D6DCDA00D6DDD900D5DCD900D5DCD900D5DCD900D6DCD900005C
CE0000D4F5003EAFFC000079F500005CCE00C5C5C53AF2F2F2FFF1F1F1FF3336
B3FF080CB8FF3738B4FFF9F9F9FFFAFAFAFFFBFBFBFFFBFBFBFFFCFCFCFFFCFC
FCFFFCFCFCFFC5C5C53AFFFFFF00FFFFFF000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000CC483F00E8A20000E8A20000E8A2
0000E8A20000CC483F0070AE760068AC6F000000000000000000241CED00285E
FD00285EFD00285EFD00241CED000000000000000000000000009BA19E00FDFD
FD00DAE0DC00858A8800858A8800858A8800858A8800858A8800858A8800858A
8800005CCE0000D4F5003EAFFC00005CCE00C5C5C53AF1F1F0FFF0F0EFFF2C2E
AAFF0B0DADFF3031ABFFF7F7F7FFF9F9F9FFFAFAFAFFFAFAFAFF9CDE9CFF26C0
26FF0AB10AFF1DB81DE2A1E1A15EFFFFFF000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000CC483F00E8A20000E8A20000E8A2
0000CC483F0077B17C006BB374006FB7780052A95C0057AF6100241CED00285E
FD00285EFD00241CED00000000000000000000000000000000009CA2A000FDFD
FD00DCE3E000DAE0DD00D8DFDC00D7DEDB00D6DCD900D4DBD800D1D9D500CBD2
CE00C6CDC900005CCE00005CCE00A1C3EC00C5C5C53AEFEFEEFFEEEEEDFF2525
A1FF0D0EA2FF292AA2FFF5F5F5FFF7F7F7FFF8F8F8FF9BDE9BFF01B401FF00A9
17FFFFFFFFFF00B234FF02B504FD9BE09B640000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000CC483F00E8A20000E8A20000CC48
3F005FA566006CB474009FD5A700A2D6AA00A5D8AD00A8D9AF00241CED00285E
FD00241CED00D9F1DC00000000000000000000000000000000009EA4A200FDFD
FD00E1E6E400858A8800858A8800858A8800858A8800D7DEDB00BBC1BF00AAB0
AC00B1B3B200D8DBD900BABFBD0000000000C5C5C53AEEEEEDFFECECECFF1D1E
9DFF0D0EA1FF21219FFFF3F3F2FFF5F5F5FFF6F6F6FF22B522FF009F03FF00A0
34FFFFFFFFFF00B064FF00B033FF22B522DD0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000CC483F00E8A20000CC483F000000
00000000000080BE870075BE7E0079C282005DB7670060BC6B00241CED00241C
ED00D9F1DC000000000000000000000000000000000000000000A0A6A300FDFE
FD00E5E9E700E2E7E400E0E5E300DEE4E100DCE2DF00DAE0DD00C1C6C4000000
0000FCFDFC00ABAFAD00E7E8E70000000000C5C5C53AECECEBFFEBEBEAFF1C1D
A5FF0B0DACFF1F21A7FFF0F0F0FFF2F2F2FFF3F3F3FF099509FFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFF099709F60000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000CC483F00CC483F00000000000000
0000000000000000000083C68A007AC583000000000000000000241CED000000
0000000000000000000000000000000000000000000000000000A1A7A500FEFE
FE00E9ECEB00E5E9E700E3E8E500E1E6E300DEE4E100DFE5E200D8DAD900FDFD
FD00BCC0BF00D2D5D4000000000000000000C5C5C53AEAE9E8FFE8E8E7FF2223
B1FF090CB7FF2427B1FFEEEEEDFFF0F0EFFFF1F1F0FF25AC25FF1DAF1DFF29B4
3FFFFFFFFFFF29BC5AFF1DB531FF26AE26D90000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000CC483F0000000000000000000000
00000000000000000000FDFEFD0096D49E000000000000000000000000000000
0000000000000000000000000000000000000000000000000000AEB3B100EDEF
EE000000000000000000000000000000000000000000F9FAF900E8E9E900AFB5
B200D3D5D400000000000000000000000000C5C5C53AEAEAEAFFE8E8E7FF282A
BCFF060BC3FF2A2CBCFFEEEEEDFFF0F0EFFFF1F1F0FF96D496FF36B736FF78D1
78FFFFFFFFFF78D67AFF36BB36FD9FDC9F600000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000E4E6E500AFB5
B300A6ACAA00A6ACA900A5ABA900A5ABA800A5ABA800A6ACAA00BFC3C100E6E8
E70000000000000000000000000000000000EFEFEF10C5C5C53AC5C5C53A6A6D
DFF08183E5F9686ADEEEC5C5C53AC5C5C53AC5C5C53AC5C5C53A79B779863EB2
3EE55EC45EF942B342E29BD99B64FFFFFF000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000050101002A0E0D00250D0B00250D
0B00260D0B0026090700000000007B7B7B00E6E6E60000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000A449A300A449A300A449A300A449
A300A449A3000000800000008000000080000000800000008000000080000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000002A0F0C00F1554A00DE4E4400DF4E
4400F653480057181400D7DEDF001A1A1A0000000000D8D8D800000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000A449A300BD6ABD00BD6ABD000000
8000000080000000800000008000000080000000800000008000000080000000
8000000080000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000250D0B00DE4E4400CD483F00D948
3E003A020000D6E1E20000000000000000000000000000000000E6E6E6000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000A449A300BD6ABD00000080000000
8000000080000000800000008000000080000000800000008000000080000000
8000000080000000800000008000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000250D0B00DF4E4500D8483E004C1C
1800CAD8D900000000000000000000000000F4F4F40010101000000000000000
000000000000000000000000000000000000000000000000000000000000FFFF
FF00FFFFFF00D7D7D7000000000000000000D7D7D700FFFFFF00FFFFFF00FFFF
FF00000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FF0000000000000000000000000000000000A449A30000008000000080000000
8000000080000000800023662700266B2B002A712F0053995A00569D5E000000
8000000080000000800000008000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000260D0B00F65348003A020000CAD8
D900000000000000000000000000000000000000000084848400000000000000
000000000000000000000000000000000000000000000000000000000000FFFF
FF00FFFFFF00FFFFFF000000000000000000FFFFFF00FFFFFF00FFFFFF009191
9100C3C3C3000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9100C3C3C3000000000000000000000000000000800000008000000080000000
800000008000000080000000800084C98E0087CA91008ACB94008DCD970060A7
6800000080000000800000008000000080000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000002609060056171300D6E1E2000000
0000000000000000000000000000000000000000000000000000000000006D6D
6D00000000000000000000000000000000000000000000000000000000009191
9100FFFFFF00FFFFFF000000000000000000FFFFFF00FFFFFF00FFFFFF000000
0000FFFFFF000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FFFFFF000000000000000000000000000000800000008000000080000000
80000000800000008000000080000000800035803B005DA4650062A96A0075B1
7B00000000000000800000008000000080000000000000000000000000000000
0000000000000000000000000000000000000000000052525200000000000000
00000000000000000000000000000000000000000000DAE1E100000000000000
000000000000000000000000000000000000F7F7F7000A0A0A005B5B5B000000
0000000000000000000000000000000000000000000000000000000000000000
0000FFFFFF00FFFFFF009191910000000000C3C3C300FFFFFF00FFFFFF000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000080000000800000000000407C
4400000080000000800000008000000080000000800062A3670071AE7700FEFE
FE00F9FCF9000000000000008000000080000000000000000000000000000000
0000000000000000000000000000000000005252520000000000000000000000
000000000000000000000000000000000000F1F1F10099999900F7F7F7000000
00000000000000000000000000000000000000000000E9E9E900000000000000
0000000000000000000000000000000000000000000000000000000000000000
000091919100FFFFFF009191910000000000C3C3C300FFFFFF00FFFFFF000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000800000008000CC483F00CC48
3F00CC483F000000800000008000000080000000800000008000000000000000
0000000000000000000000008000000080000000000000000000000000000000
0000000000000000000000000000525252000000000000000000000000000000
000000000000000000000000000000000000929292000000000000000000E9E9
E900DFDFDF00C2C3B600C5C6B700C5C6B700C5C6B700CACABC00C4C4C100CECE
CE00000000000000000000000000000000000000000000000000000000000000
000000000000C3C3C300C3C3C3000000000091919100FFFFFF00FFFFFF000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000800000008000E8A20000E8A2
0000E8A20000E8A200000000800000008000000080000000800000008000241C
ED00241CED00241CED0000008000000080000000000000000000000000000000
0000000000000000000052525200000000000000000000000000000000000000
000000000000000000000000000000000000626262000000000078787800BBBB
BB004C4D40000000620000006E0000006C0000006D000000850000000000B3B4
B100000000000000000000000000000000000000000000000000D7D7D7000000
00000000000091919100C3C3C3000000000091919100FFFFFF00FFFFFF000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000800000008000E8A20000E8A2
0000E8A20000CC483F0070AE7600000080000000800000008000000080000000
8000285EFD00285EFD0000008000000080000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000DADADA0000000000F1F1F1000000
0000505139001B11EF00261DFD00261DFB00251CFF0000006F00C9C9C3000000
000000000000000000000000000000000000000000000000000091919100FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FF00FFFFFF00000000000000000000000000000080000000800000008000E8A2
0000CC483F0077B17C006BB374006FB778000000800000008000000080000000
8000000080000000800000008000000080000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000D0D0D00000000000F5F5F5000000
0000505139001910E300241CEF00261DFF0009066400CDCEB800000000000000
000000000000000000000000000000000000000000000000000000000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FF00FFFFFF000000000000000000000000000000800000008000000080000000
80005FA566006CB474009FD5A700A2D6AA00A5D8AD0000008000000080000000
8000000080000000800000008000000080000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000C8C8C800000000003F3F3F009F9F
9F005D5E46001910E400261DFF0000005E007A7A6A00393A3C00000000000000
000000000000E8E8E8009C9C9C00000000000000000000000000000000009191
9100D7D7D700FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FF00FFFFFF00000000000000000000000000CC483F0000008000000080000000
8000000080000000800075BE7E0079C282005DB7670060BC6B00000080000000
8000000080000000800000008000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000007F7F7F00000000007373
730060614B00160DF00004006700D1D2BF00DBDBDB0000000000000000004B4B
4B00F8F8F800C8C8C80000000000ADADAD000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000CC483F00CC483F00000080000000
8000000080000000800000008000000080000000800000008000000080000000
8000000080000000800000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F50460000005900C3C4AD000000000000000000BDBDBD00666666000000
0000000000000000000000000000424242000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000CC483F0000000000000000000000
8000000080000000800000008000000080000000800000008000000080000000
8000000080000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00003D3D3D00C9C9BF000000000000000000000000000000000000000000C8C8
C800D4D4D400AFAFAF0043434300000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000800000008000000080000000800000008000000080000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -5038,12 +5205,16 @@ object EditForm: TEditForm
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000424D3E000000000000003E000000
2800000040000000B00000000100010000000000800500000000000000000000
000000000000000000000000FFFFFF007FFF007FFFFF0000BBFF003FFFFF0000
DFFF031FFFFF0000EBFF071FE30F0000F7FF0F9FE3070000A80A1F0FE3170000
F99F3F1FF11F0000FA3F1FBFF11F0000FA71000FF91F0000F8B9000FD91F0000
F9D5101FC0070000FBEF103FE0070000FFD70039E0070000FABB8000FFFF0000
FE7DF180FFFF0000FA3EF3E1FFFF0000FFFFFFFF0001FFFFFFE7000100010000
2800000040000000C00000000100010000000000000600000000000000000000
000000000000000000000000FFFFFF0003FFC00100000000079FC1F900000000
0F9FC00000000000100FC000000000002007C00000000000600FC00000000000
E187C0000000000000BFC0000000000000C0C0000000000000C1C00000000000
0003C000000000000003C001000000001807C011000000003CDFC00300000000
7CFFCF8700000000FFFFC00F000000007FFF007FFFFF001FBBFF003FFFFF0007
DFFF031FFFFF0001EBFF071FE30F0001F7FF0F9FE3070000A80A1F0FE3170008
F99F3F1FF11F2004FA3F1FBFF11F003CFA71000FF91F0000F8B9000FD91F0000
F9D5101FC0070000FBEF103FE0070000FFD70039E0070001FABB8000FFFF0003
FE7DF180FFFF6007FA3EF3E1FFFFF81FFFFFFFFF0001FFFFFFE7000100010000
FFC7000100010001000300010001000200010007000700070001000D000D000E
0003001F001F001FE027003D003D003EE02700570057002B0003003D00FD007E
0001031F03FF00FF0001068D06FD017E00030FC70FFF03FFFFC71EE11EFD077E
@ -5265,6 +5436,18 @@ object EditForm: TEditForm
object N19: TMenuItem
Caption = '-'
end
object mnuCopyChaos: TMenuItem
Caption = 'Copy settings'
OnClick = mnuCopyChaosClick
end
object mnuPasteChaos: TMenuItem
Caption = 'Paste settings'
Enabled = False
OnClick = mnuPasteChaosClick
end
object N23: TMenuItem
Caption = '-'
end
object ShowChaosMatrix: TMenuItem
Caption = 'Show chaos matrix...'
OnClick = btnFullChaosClick
@ -5389,31 +5572,56 @@ object EditForm: TEditForm
Caption = 'Use degrees'
Checked = True
end
object N22: TMenuItem
Caption = '-'
end
object mnuCalcExpression: TMenuItem
Caption = 'Calculate expression...'
OnClick = mnuCalcExpressionClick
end
end
object CopyMenu: TPopupMenu
Left = 305
Top = 241
object Copytrianglecoordinates1: TMenuItem
object CopyTriangleCoordinates: TMenuItem
Caption = 'Copy Triangle Coordinates'
OnClick = btnCopyTriangleClick
end
object Copytransform1: TMenuItem
object CopyTransform: TMenuItem
Caption = 'Copy Whole Transform'
OnClick = Copytransform1Click
OnClick = CopyTransformClick
end
object CopyVariations: TMenuItem
Caption = 'Copy variations '
OnClick = CopyVariationsClick
end
object CopyChaos: TMenuItem
Caption = 'Copy chaos'
OnClick = mnuCopyChaosClick
end
end
object PasteMenu: TPopupMenu
Left = 385
Top = 233
object Pastetrianglecoordinates1: TMenuItem
object PasteTriangleCoordinates: TMenuItem
Caption = 'Paste Triangle Coordinates'
Enabled = False
OnClick = btnPasteTriangleClick
end
object Pastetransform1: TMenuItem
object PasteTransform: TMenuItem
Caption = 'Paste Transform(s)'
Enabled = False
OnClick = Pastetransform1Click
OnClick = PasteTransformClick
end
object PasteVariations: TMenuItem
Caption = 'Paste variations'
Enabled = False
OnClick = PasteVariationsClick
end
object PasteChaos: TMenuItem
Caption = 'Paste chaos'
Enabled = False
OnClick = mnuPasteChaosClick
end
end
object TriangleOperations: TPopupMenu
@ -5506,6 +5714,15 @@ object EditForm: TEditForm
Caption = '-'
GroupIndex = 5
end
object SynchronizeAll: TMenuItem
Caption = 'Apply operations to all triangles'
GroupIndex = 5
OnClick = SynchronizeAllClick
end
object N20: TMenuItem
Caption = '-'
GroupIndex = 5
end
object InvertMovevalue1: TMenuItem
Caption = 'Invert current Move step'
GroupIndex = 5
@ -5934,4 +6151,10 @@ object EditForm: TEditForm
FE7FFC7FFFF7FFCFFF7FFC7FFFFFFFFF00000000000000000000000000000000
000000000000}
end
object mnuSyncTriangles: TPopupMenu
AutoHotkeys = maManual
OwnerDraw = True
Left = 377
Top = 369
end
end

File diff suppressed because it is too large Load Diff

303
Forms/FlameComment.dfm Normal file
View File

@ -0,0 +1,303 @@
object CommentForm: TCommentForm
Left = 0
Top = 0
BorderStyle = bsSingle
Caption = 'Edit Flame Comment'
ClientHeight = 172
ClientWidth = 459
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
Icon.Data = {
0000010001001616000000000000100800001600000028000000160000002C00
000001002000000000009007000000000000000000000000000000000000FFFF
FF00000000070000002100000026000000260000002600000026000000260000
0026000000260000002600000026000000260000002600000026000000260000
002600000026000000260000002100000007FFFFFF00000000020000001C3133
325E818583C58B918FFD8B908EFF8B908EFF8B908EFF8A908DFF8A8F8DFF8A8F
8DFF8A8F8DFF898E8CFF898E8CFF898E8CFF888E8CFF888D8BFF898E8CFD7E82
80C52F32305E0000001C00000002FFFFFF00000000078A908DB9D9DBDAFFFEFE
FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFD9DBDAFF878C8AB90000
0007FFFFFF00FFFFFF00FFFFFF008F9593FCFEFEFEFFEBEEEDFFEAEDECFFEBEE
ECFFECEEEDFFECEFEEFFEDF0EFFFEEF0F0FFEFF1F0FFEFF1F0FFEFF1F1FFEFF1
F1FFEFF1F1FFEFF1F0FFF0F1F1FFFEFEFEFF8B908EFCFFFFFF00FFFFFF00FFFF
FF00FFFFFF00909593FFFFFFFFFFEAEDECFFEBEEEDFF9AAAB4FF22313CFF6E8B
9FFFB9C9D2FFD8DADAFFE4E6E5FFF1F2F2FFF2F4F3FFF2F4F3FFF2F3F3FFF1F3
F2FFF0F2F2FFFFFFFFFF8B908EFFFFFFFF00FFFFFF00FFFFFF00FFFFFF009196
94FFFFFFFFFFEAEDECFFD0D3D2FFC7C9CAFF223542FF6A9FC4FF6DB5E8FF67B3
E6FF668EB8FFA7A8A8FFC0C1C1FFE7E8E8FFF0F1F1FFF2F3F3FFF1F3F2FFFFFF
FFFF8C9290FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00929895FFFFFFFFFFE9EC
EBFFEAEDECFFEBEEEDFF97C6E9FF8BC4ECFFFFFFFFFF8CBFEEFF1569D0FF7D9E
C5FFCBCCCCFFD5D7D6FFDFE0E0FFEAECECFFEFF1F1FFFFFFFFFF8E9391FFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00939997FFFFFFFFFFE8EBEAFFCFD1D0FFC7CA
C9FFBAC6CDFF6BB5E8FFA2D7FCFF4EAAF3FF549DE7FF1669D0FF7A9AC0FFB7B8
B8FFBCBDBCFFCDCFCEFFEDF0EFFFFFFFFFFF8F9492FFFFFFFF00FFFFFF00FFFF
FF00FFFFFF00959A98FFFFFFFFFFE6EAE9FFE7EBE9FFE8EBEAFFE9ECEBFF72A9
E0FF2B7DDAFF6BBFFBFF4CAAF3FF549DE7FF176AD1FF9DBDE2FFE8EBEAFFE8EB
EAFFEBEDECFFFFFFFFFF909693FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00969B
99FFFFFFFFFFE4E8E7FFCBCFCDFFC4C6C5FFC4C7C5FFC5C7C6FF5C90CBFF2A7C
D9FF6CBFFBFF4DAAF3FF539DE7FF1669D0FF85A5C8FFCED0CFFFE8EBEAFFFFFF
FFFF919795FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00979D9AFFFFFFFFFFE2E7
E5FFE3E7E5FFE3E7E6FFE4E8E6FFE4E8E7FFE5E9E7FF689EDAFF2B7DDAFF6CBF
FBFF4DAAF3FF539CE7FF146AD1FF9EBDDFFFE5E9E7FFFFFFFFFF939896FFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00989E9CFFFFFFFFFFE0E5E2FFC7CBC9FFBFC3
C1FFBFC4C2FFC0C4C2FFC0C4C2FFC0C5C3FF558CC9FF2A7CD9FF6CC0FBFF4DAA
F3FF529CE7FF1368D0FF9DBDDDFFFFFFFFFF949997FFFFFFFF00FFFFFF00FFFF
FF00FFFFFF009A9F9DFFFFFFFFFFDFE4E2FFE0E5E2FFE0E4E2FFDFE5E2FFE0E5
E2FFDFE4E2FFDFE4E2FFDFE4E2FF6198D7FF2B7FDBFF6CC0FBFF4DAAF3FF529C
E6FF1469D1FFA5BAD1FF959B98FFFFFFFF00FFFFFF00FFFFFF00FFFFFF009BA1
9EFFFFFFFFFFE0E4E3FFC7CBC8FFBEC3C0FFBFC2C0FFBEC3C0FFBDC2BFFFBDC1
BFFFBDC1BFFFBCC0BFFF4F87C8FF2A7CD9FF6DC0FBFF4DAAF3FF5998D9FF858A
88FF77899BFDFFFFFF00FFFFFF00FFFFFF00FFFFFF009CA29FFFFFFFFFFFE0E5
E3FFE0E5E2FFE0E5E2FFDFE4E2FFDFE4E1FFDEE3E1FFDEE3E1FFDDE2E0FFDCE2
DFFFDBE1DEFF5791D2FF2B7ED9FF6DC0FBFF6C99BAFF828787FF858A90FF6064
B087FFFFFF00FFFFFF00FFFFFF009DA3A1FFFFFFFFFFE1E6E4FFC7CBC9FFBFC3
C1FFBEC3C1FFBEC2C0FFBEC1BFFFBCC0BFFFBBC0BEFFBABFBDFFBFC4C2FFAEB1
AFFF6280A1FF838A8DFF92999BFFAEAFAFFF808388FF5355C2FA2828EE4DFFFF
FF00FFFFFF009EA5A2FFFFFFFFFFE2E7E4FFE2E6E4FFE1E6E4FFE0E5E3FFE0E5
E2FFDEE4E1FFDDE3E0FFDCE1DFFFDAE0DEFFD9DFDDFFB9BEBCFFFEFEFEFF7A8C
A7FF999DA2FFAFB2B5FF818594FE6D6DDDFF3131EED0FFFFFF00FFFFFF00A0A6
A3FFFFFFFFFFE4E8E6FFC9CECBFFC0C5C2FFBFC4C1FFBFC3C0FFBDC1BFFFBCC1
BFFFBDC2C0FFC4C9C6FFC6CCC9FFB5BAB7FFFFFFFFFFFDFDFDFF797CB1FE5E61
B7FE7778CEFF6868EDFF3030F0C8FFFFFF00FFFFFF00A1A7A4FFFFFFFFFFE6EA
E8FFE5E9E7FFE4E8E6FFE2E7E5FFE1E6E3FFDFE4E1FFDDE3E0FFDBE1DEFFDAE0
DDFFCAD0CDFFCCCECDFFFFFFFFFFDBDDDDFD9FA5A3D02E2EEAA02C2CEDF52E2E
EDDD2B2BEF30FFFFFF00FFFFFF00A2A9A6FCFEFEFEFFEBEFEDFFE7EBE9FFE6EA
E8FFE4E8E6FFE2E7E4FFE0E5E3FFE1E6E4FFE6EAE8FFEBEFEDFFE9EAEAFFF5F6
F5FFCCD0CEF7A0A7A4D89EA4A213FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00A6ADAAAEDBDEDDFFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFCFCFCFFF0F2F1FFE4E7E6FFCFD3D1F8A2A8A6E9A0A6A45EA0A6
A302FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00A5AB
A821A7AEABAEA4AAA8FCA4AAA7FFA4AAA7FFA3AAA7FFA3A9A7FFA3A9A6FFA4AA
A7F5A5ABA9D2A4AAA8A0A2A8A561A1A8A506FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E0001F00C0000F00C0000F00C000
0F00C0000F00C0000F00C0000F00C0000F00C0000F00C0000F00C0000F00C000
0F00C0000F00C0000700C0000700C0000300C0000300C0000700C0007F00C001
FF00E007FF00}
OldCreateOrder = False
OnCreate = FormCreate
DesignSize = (
459
172)
PixelsPerInch = 96
TextHeight = 13
object btnCopy: TSpeedButton
Left = 8
Top = 58
Width = 23
Height = 22
Hint = 'Copy gradient to clipboard'
Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100
2000000000000004000000000000000000000000000000000000FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000
0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000
0000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000
0000FFFFFF00E39A6F00FFFFFF00E3996C00E2996D00E3996D00FFFFFF000000
0000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF000000
0000FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000000000
000000000000000000000000000000000000FF00FF00FF00FF00FF00FF000000
0000FFFFFF00E2956600E393630000000000FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF0000000000FF00FF00FF00FF00FF00FF000000
0000FFFFFF00FFFFFF00FFFFFF0000000000FFFFFF00E39A6F00FFFFFF00E399
6C00E2996D00E3996D00FFFFFF0000000000FF00FF00FF00FF00FF00FF000000
0000FFFFFF00E3915F00E28C580000000000FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF0000000000FF00FF00FF00FF00FF00FF000000
0000FFFFFF00FFFFFF00FFFFFF0000000000FFFFFF00E2956600E3936300FFFF
FF00E3926200E2936300FFFFFF0000000000FF00FF00FF00FF00FF00FF000000
0000FFFFFF00E2916000FFFFFF0000000000FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF0000000000FF00FF00FF00FF00FF00FF000000
0000FFFFFF00FFFFFF00FFFFFF0000000000FFFFFF00E3915F00E28C5800FFFF
FF00FFFFFF00E2936400FFFFFF0000000000FF00FF00FF00FF00FF00FF000000
000000000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFF
FF0000000000000000000000000000000000FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF0000000000FFFFFF00E2916000FFFFFF00FFFF
FF0000000000FFFFFF0000000000FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF0000000000FFFFFF00FFFFFF00FFFFFF00FFFF
FF000000000000000000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00000000000000000000000000000000000000
000000000000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00}
ParentShowHint = False
ShowHint = True
Transparent = False
OnClick = btnCopyClick
end
object btnPaste: TSpeedButton
Left = 8
Top = 82
Width = 23
Height = 22
Hint = 'Copy gradient to clipboard'
Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100
2000000000000004000000000000000000000000000000000000FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF000000000000000000000000000000
00000000000000000000000000000000000000000000FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF0000000000FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF0000000000FFFFFF00E39A6F00FFFF
FF00E3996C00E2996D00E3996D00FFFFFF0000000000FF00FF00FF00FF00FF00
FF000000000000000000000000000000000000000000FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000FF00FF00FF00FF000000
000056B9F50056B9F50056B9F50056B9F50000000000FFFFFF00E2956600E393
6300FFFFFF00E3926200E2936300FFFFFF0000000000FF00FF00FF00FF000000
000056B9F50056B9F50056B9F50056B9F50000000000FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000FF00FF00FF00FF000000
000056B9F50056B9F50056B9F50056B9F50000000000FFFFFF00E3915F00E28C
5800FFFFFF00FFFFFF00E2936400FFFFFF0000000000FF00FF00FF00FF000000
000056B9F50056B9F50056B9F50056B9F50000000000FFFFFF00FFFFFF00FFFF
FF00FFFFFF0000000000000000000000000000000000FF00FF00FF00FF000000
000056B9F50056B9F50056B9F50056B9F50000000000FFFFFF00E2916000FFFF
FF00FFFFFF0000000000FFFFFF0000000000FF00FF00FF00FF00FF00FF000000
000056B9F50056B9F50056B9F50056B9F50000000000FFFFFF00FFFFFF00FFFF
FF00FFFFFF000000000000000000FF00FF00FF00FF00FF00FF00FF00FF000000
000056B9F5000000000000000000000000000000000000000000000000000000
0000000000000000000000000000FF00FF00FF00FF00FF00FF00FF00FF000000
000056B9F50000000000BBE5F900BBE5F900BBE5F900BBE5F900BBE5F900BBE5
F9000000000056B9F50000000000FF00FF00FF00FF00FF00FF00FF00FF000000
000056B9F50056B9F50000000000BBE5F9000000000000000000BBE5F9000000
000056B9F50056B9F50000000000FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF0000000000000000000000000000000000BBE5F900BBE5F900000000000000
00000000000000000000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF0000000000000000000000000000000000FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00}
ParentShowHint = False
ShowHint = True
Transparent = False
OnClick = btnPasteClick
end
object btnCut: TSpeedButton
Left = 8
Top = 34
Width = 23
Height = 22
Hint = 'Copy gradient to clipboard'
Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100
2000000000000004000000000000000000000000000000000000FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00BBA19400975F450063423200A28D8200FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00CD866300AB623F008A50330062453700BDBDBE00B99F92006643
34005E3F3000A8918600FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00DD835500C3B2AA00B89C8E00854E3300C0C0C000C5826100AA62
3E00633C29002F252300FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00E1855700C5B3AA00BDAEA8008C523500BCB8B600D47C5200C2B2
AA00AE9486006B422D00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00DA987600E5865600B06641008F5538009C725D00C9754D00C1B9
B500BA9E90008F553600FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00C8B5AC00EB8E5D00DB8256009F5F400094604700BE744F00D57B
4F00B96B4500AD877400FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00C8B6AE00DE997600DF845600C68D7000CC784D00D27C
5100C6917700BDA79C00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00887366007160560086675500AB9E
9900FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00B8B4B1008E8074007E6E6300695D55007672
6E00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00BAB0AA00A2948B00A8A099008E817700635B
5500FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00BEB1AA00A1948B00C8C6C400CDC5C0006B5F
5600ADADAE00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00A99B9200B2A8A300C3C3C300E8E4E2007C6F
6600A8A9AA00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00BBB8B600A3968C00BCBAB900FF00FF00DDDCDC00BCB2
AB00A6A19E00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00BFB8B300B3A89E00FF00FF00FF00FF00CBCBCB00E2DD
DA00A1979000FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00}
ParentShowHint = False
ShowHint = True
Transparent = False
OnClick = btnCutClick
end
object btnUndo: TSpeedButton
Left = 8
Top = 10
Width = 23
Height = 22
Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100
2000000000000004000000000000000000000000000000000000FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FBD7
C500F8D5C300FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00F8DC
CF00F38A5700E1957100FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00EECBBA00F0855000DA865E00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00CA805C00F0885500EAC8B700FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00E1CDC300DB784700EF936700FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF008A462500954C2800A4542E00B65F3400C7693A00D6724000FF00
FF00FF00FF00FF00FF00AE5C3600EC865200F2CFBD00FF00FF00FF00FF00FF00
FF00FF00FF00954C2800DF733600EA824900F39A6A00F5B59400FF00FF00FF00
FF00FF00FF00FF00FF00A3664800E9845200F7C2A700FF00FF00FF00FF00FF00
FF00FF00FF00A3552E00EC824B00F38D5B00EC9C7600B6866F00E9D5CB00FF00
FF00FF00FF00FF00FF00A9745900E1825400F7BE9E00FF00FF00FF00FF00FF00
FF00FF00FF00B55F3400F39A6A00F49C7100F29465009D533000AA613B00DAB8
A700FF00FF00F6C5AE009D644600DE805100F7BDA100FF00FF00FF00FF00FF00
FF00FF00FF00C7693B00F7CAAE00FBDDCB00F4A37600F3946400B4623900B064
3E00BF816200BB846000A15E3900EE8B5A00F6C8B000FF00FF00FF00FF00FF00
FF00FF00FF00D6724000FF00FF00FF00FF00FBDECF00F5A57E00F49D7200C973
4700B7663C00B6653D00E2815300F6BCA100F6CBB700FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FBDACA00F5A67E00F6B6
9600F5B28F00F6B09100F6C1A800F6C5AE00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FBE0
D200F6C3A900F7CFBB00F9DBCD00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00
FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00}
ParentShowHint = False
ShowHint = True
Transparent = False
OnClick = btnUndoClick
end
object memComment: TMemo
Left = 40
Top = 8
Width = 397
Height = 113
Lines.Strings = (
'')
ScrollBars = ssBoth
TabOrder = 0
OnKeyPress = memCommentKeyPress
end
object btnOK: TButton
Left = 246
Top = 130
Width = 93
Height = 30
Anchors = [akRight, akBottom]
Caption = 'OK'
Default = True
ModalResult = 1
TabOrder = 1
end
object btnCancel: TButton
Left = 345
Top = 130
Width = 92
Height = 30
Anchors = [akRight, akBottom]
Caption = 'Cancel'
ModalResult = 2
TabOrder = 2
end
end

76
Forms/FlameComment.pas Normal file
View File

@ -0,0 +1,76 @@
{ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina }
unit FlameComment;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.StdCtrls, Vcl.Buttons, Translation;
type
TCommentForm = class(TForm)
memComment: TMemo;
btnOK: TButton;
btnCancel: TButton;
btnCopy: TSpeedButton;
btnPaste: TSpeedButton;
btnCut: TSpeedButton;
btnUndo: TSpeedButton;
procedure FormCreate(Sender: TObject);
procedure memCommentKeyPress(Sender: TObject; var Key: Char);
procedure btnUndoClick(Sender: TObject);
procedure btnCopyClick(Sender: TObject);
procedure btnPasteClick(Sender: TObject);
procedure btnCutClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
CommentForm: TCommentForm;
implementation
{$R *.dfm}
procedure TCommentForm.btnCopyClick(Sender: TObject);
begin
memComment.CopyToClipboard;
end;
procedure TCommentForm.btnCutClick(Sender: TObject);
begin
memComment.CutToClipboard;
end;
procedure TCommentForm.btnPasteClick(Sender: TObject);
begin
memComment.PasteFromClipboard;
end;
procedure TCommentForm.btnUndoClick(Sender: TObject);
begin
if memComment.CanUndo then memComment.Undo;
end;
procedure TCommentForm.FormCreate(Sender: TObject);
begin
btnOK.Caption := TextByKey('common-ok');
btnCancel.Caption := TextByKey('common-cancel');
self.Caption := TextByKey('editor-common-editcomment');
btnCopy.Hint := TextByKey('common-copy');
btnPaste.Hint := TextByKey('common-paste');
btnUndo.Hint := TextByKey('common-undo');
btnCut.Hint := TextByKey('common-cut');
end;
procedure TCommentForm.memCommentKeyPress(Sender: TObject; var Key: Char);
begin
if (Key = '<') or (Key = '>') then Key := #0; // prevent XML-scanner errors
end;
end.

View File

@ -128,6 +128,12 @@ object ExportDialog: TExportDialog
Width = 337
Height = 21
Anchors = [akLeft, akTop, akRight]
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
TabOrder = 0
end
end
@ -707,7 +713,7 @@ object ExportDialog: TExportDialog
Filter =
'JPEG Image (*.jpg)|*.jpg|PPM Image (*.ppm)|*.ppm|PNG Images (*.p' +
'ng)|*.png'
Left = 464
Top = 264
Left = 424
Top = 280
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
@ -27,7 +27,7 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, ComCtrls, ExtCtrls, Translation;
StdCtrls, Buttons, ComCtrls, ExtCtrls;
type
TExportDialog = class(TForm)
@ -91,11 +91,11 @@ type
FloatFormatSettings: TFormatSettings;
public
Filename: string;
ImageWidth, ImageHeight, Oversample, Batches, Strips: Integer;
ImageWidth, ImageHeight, Oversample: Integer;
Sample_Density, Filter_Radius: double;
Estimator, EstimatorMin, EstimatorCurve: double;
GammaTreshold: double;
Jitters: integer;
// Batches, Jitters: Integer;
end;
var
@ -103,7 +103,8 @@ var
Ratio: double;
implementation
uses Global, Main, ShellAPI;
uses Global, Main, ShellAPI, Translation;
{$R *.DFM}
@ -111,14 +112,12 @@ procedure TExportDialog.btnBrowseClick(Sender: TObject);
begin
SaveDialog.InitialDir := ExtractFileDir(txtFilename.text);
SaveDialog.Filename := txtFilename.Text;
case ExportFileFormat of
0: SaveDialog.DefaultExt := 'jpg';
1: SaveDialog.DefaultExt := 'ppm';
case ExportFileFormat of // AV: fixed
1: SaveDialog.DefaultExt := 'jpg';
2: SaveDialog.DefaultExt := 'ppm';
3: SaveDialog.DefaultExt := 'png';
end;
SaveDialog.filterIndex := ExportFileFormat;
SaveDialog.Filter := Format('Portable Pixmap (*.ppm)|*.ppm|%s|*.jpg;*.jpeg|%s|*.png|%s|*.*',
[TextByKey('common-filter-jpeg'), TextByKey('common-filter-png'),
TextByKey('common-filter-allfiles')]);
SaveDialog.FilterIndex := ExportFileFormat;
if SaveDialog.Execute then
begin
case SaveDialog.FilterIndex of
@ -144,11 +143,11 @@ begin
txtOversample.text := IntToSTr(Oversample);
udOversample.Position := Oversample;
Ratio := ImageWidth / ImageHeight;
Batches := 1;
//Batches := 1;
//Jitters := 1;
Estimator := 9.0;
EstimatorMin := 0.0;
EstimatorCurve := 0.4;
Jitters := 1;
GammaTreshold := MainCP.gamma_threshold; //0.01;
GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FloatFormatSettings);
txtEstimator.Text := FloatToStr(Estimator, FloatFormatSettings);
@ -197,18 +196,12 @@ end;
procedure TExportDialog.txtDensityChange(Sender: TObject);
begin
try
Sample_Density := StrToFloat(txtDensity.Text);
except
end;
Sample_Density := StrToFloatDef(txtDensity.Text, 200);
end;
procedure TExportDialog.txtFilterRadiusChange(Sender: TObject);
begin
try
Filter_Radius := StrToFloat(txtFilterRadius.Text);
except
end;
Filter_Radius := StrToFloatDef(txtFilterRadius.Text, 0.04);
end;
procedure TExportDialog.txtOversampleChange(Sender: TObject);
@ -217,46 +210,31 @@ begin
txtOversample.Text := IntToStr(udOversample.Max);
if StrToInt(txtOversample.Text) < udOversample.Min then
txtOversample.Text := IntToStr(udOversample.Min);
try
Oversample := StrToInt(txtOversample.Text);
except
end;
Oversample := StrToIntDef(txtOversample.Text, 2);
end;
procedure TExportDialog.txtEstimatorChange(Sender: TObject);
begin
Estimator := 0;
try
Estimator := StrToFloat(txtEstimator.Text, FloatFormatSettings);
except
end;
Estimator := StrToFloatDef(txtEstimator.Text, 0, FloatFormatSettings);
end;
procedure TExportDialog.txtEstimatorMinChange(Sender: TObject);
begin
EstimatorMin := 0;
try
EstimatorMin := StrToFloat(txtEstimatorMin.Text, FloatFormatSettings);
except
end;
EstimatorMin := StrToFloatDef(txtEstimatorMin.Text, 0, FloatFormatSettings);
end;
procedure TExportDialog.txtEstimatorCurveChange(Sender: TObject);
begin
EstimatorCurve := 0;
try
EstimatorCurve := StrToFloat(txtEstimatorCurve.Text, FloatFormatSettings);
except
end;
EstimatorCurve := StrToFloatDef(txtEstimatorCurve.Text, 0, FloatFormatSettings);
end;
procedure TExportDialog.txtGammaTresholdChange(Sender: TObject);
begin
//GammaTreshold := 0.01;
try
GammaTreshold := StrToFloat(txtGammaTreshold.Text, FloatFormatSettings);
except
end;
GammaTreshold := StrToFloatDef(txtGammaTreshold.Text, 0.01, FloatFormatSettings);
end;
procedure TExportDialog.lblFlam3LinkClick(Sender: TObject);
@ -291,6 +269,9 @@ begin
chkRender.Caption := TextByKey('export-paramoptions-dorender');
Label6.Caption := TextByKey('export-paramoptions-warningtitle');
Label15.Caption := TextByKey('export-paramoptions-warningtext');
// AV: fixed the order and moved here here since the filter never changes
SaveDialog.Filter := Format('%s|*.jpg;*.jpeg|Portable Pixmap (*.ppm)|*.ppm|%s|*.png',
[TextByKey('common-filter-jpeg'), TextByKey('common-filter-png')]);
end;
procedure TExportDialog.Panel1Resize(Sender: TObject);

View File

@ -1,553 +0,0 @@
object ExportCDialog: TExportCDialog
Left = 313
Top = 276
BorderStyle = bsDialog
Caption = 'Export Flame'
ClientHeight = 134
ClientWidth = 496
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
OnCreate = FormCreate
OnShow = FormShow
DesignSize = (
496
134)
PixelsPerInch = 96
TextHeight = 13
object btnOK: TButton
Left = 254
Top = 98
Width = 115
Height = 25
Anchors = [akTop, akRight]
Caption = '&OK'
Default = True
ModalResult = 1
TabOrder = 0
OnClick = btnOKClick
end
object btnCancel: TButton
Left = 376
Top = 98
Width = 111
Height = 25
Anchors = [akTop, akRight]
Caption = 'Cancel'
ModalResult = 2
TabOrder = 1
end
object GroupBox1: TGroupBox
Left = 8
Top = 237
Width = 481
Height = 57
Anchors = [akLeft, akTop, akRight]
Caption = ' Destination '
TabOrder = 2
Visible = False
DesignSize = (
481
57)
object btnBrowse: TSpeedButton
Left = 448
Top = 19
Width = 24
Height = 24
Hint = 'Browse...'
Anchors = [akTop, akRight]
Flat = True
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Arial'
Font.Style = [fsBold]
Glyph.Data = {
36030000424D3603000000000000360000002800000010000000100000000100
18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF
FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF75848F66808F
607987576E7B4E626F4456613948522E3A43252E351B222914191E0E12160E13
18FF00FFFF00FFFF00FF77879289A1AB6AB2D4008FCD008FCD008FCD048CC708
88BE0F82B4157CA91B779F1F7296224B5C87A2ABFF00FFFF00FF7A8A957EBED3
8AA4AE7EDCFF5FCFFF55CBFF4CC4FA41BCF537B3F02EAAEB24A0E5138CD42367
805E696DFF00FFFF00FF7D8E9879D2EC8BA4AD89C2CE71D8FF65D3FF5CCEFF51
C9FE49C1FA3FB9F534B0EE29A8E91085CD224B5B98B2BAFF00FF80919C81D7EF
7DC5E08CA6B080DDFE68D3FF67D4FF62D1FF58CDFF4EC7FC46BEF73BB6F231AC
EC2569817A95A1FF00FF83959F89DCF18CE2FF8DA8B18CBAC774D8FF67D4FF67
D4FF67D4FF5FD0FF54CDFF4BC5FC41BBF72EA2DB51677498B2BA869AA392E1F2
98E8FD80C4DE8EA7B081DEFD84E0FF84E0FF84E0FF84E0FF81DFFF7BDDFF74D8
FF6BD6FF56A9D18F9BA4889CA59AE6F39FEBFB98E8FE8BACB98BACB98AAAB788
A6B386A3AF839FAA819AA67F95A17C919D7A8E99798B957788938BA0A8A0EAF6
A6EEF99FEBFB98E8FE7ADAFF67D4FF67D4FF67D4FF67D4FF67D4FF67D4FF7788
93FF00FFFF00FFFF00FF8EA2ABA7EEF6ABF0F7A6EEF99FEBFB98E8FD71D4FB89
9EA78699A382949F7E909A7A8C97778893FF00FFFF00FFFF00FF8FA4ACA0D2DA
ABF0F7ABF0F7A6EEF99FEBFB8DA1AAB5CBD0FF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFBDCED48FA4AC8FA4AC8FA4AC8FA4AC8FA4ACB5CBD0FF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF}
ParentFont = False
ParentShowHint = False
ShowHint = True
OnClick = btnBrowseClick
end
object Label10: TPanel
Left = 8
Top = 20
Width = 105
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'File name'
ParentShowHint = False
ShowHint = True
TabOrder = 1
end
object txtFilename: TEdit
Left = 112
Top = 20
Width = 337
Height = 21
Anchors = [akLeft, akTop, akRight]
TabOrder = 0
end
end
object GroupBox3: TGroupBox
Left = 256
Top = 10
Width = 233
Height = 79
Anchors = [akTop, akRight]
Caption = ' Quality '
TabOrder = 3
DesignSize = (
233
79)
object udOversample: TUpDown
Left = 212
Top = 44
Width = 12
Height = 21
Anchors = [akTop, akRight]
Associate = txtOversample
Min = 1
Max = 4
Position = 2
TabOrder = 2
end
object Label5: TPanel
Left = 8
Top = 20
Width = 113
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'Filter radius'
ParentShowHint = False
ShowHint = True
TabOrder = 3
end
object txtFilterRadius: TEdit
Left = 120
Top = 20
Width = 105
Height = 21
Anchors = [akLeft, akTop, akRight]
TabOrder = 0
OnChange = txtFilterRadiusChange
end
object Label3: TPanel
Left = 8
Top = 44
Width = 113
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'Oversample'
ParentShowHint = False
ShowHint = True
TabOrder = 4
end
object txtOversample: TEdit
Left = 120
Top = 44
Width = 92
Height = 21
Anchors = [akLeft, akTop, akRight]
ReadOnly = True
TabOrder = 1
Text = '2'
OnChange = txtOversampleChange
end
end
object GroupBox2: TGroupBox
Left = 8
Top = 10
Width = 241
Height = 111
Anchors = [akLeft, akTop, akRight]
Caption = ' Size '
TabOrder = 4
DesignSize = (
241
111)
object Label13: TLabel
Left = 184
Top = 36
Width = 26
Height = 13
Anchors = [akLeft, akTop, akRight]
Caption = 'pixels'
Visible = False
end
object Label16: TLabel
Left = 168
Top = 22
Width = 15
Height = 36
Anchors = [akLeft, akTop, akRight]
Caption = '}'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -32
Font.Name = 'Times New Roman'
Font.Style = []
ParentFont = False
Visible = False
end
object chkMaintain: TCheckBox
Left = 8
Top = 76
Width = 225
Height = 17
Anchors = [akLeft, akTop, akRight]
Caption = 'Maintain aspect ratio'
Checked = True
State = cbChecked
TabOrder = 0
OnClick = chkMaintainClick
end
object Label1: TPanel
Left = 8
Top = 20
Width = 105
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'Width'
ParentShowHint = False
ShowHint = True
TabOrder = 3
end
object Label2: TPanel
Left = 8
Top = 44
Width = 105
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'Height'
ParentShowHint = False
ShowHint = True
TabOrder = 4
end
object cbHeight: TComboBox
Left = 112
Top = 44
Width = 121
Height = 21
Anchors = [akLeft, akTop, akRight]
ItemHeight = 13
TabOrder = 2
OnChange = txtHeightChange
Items.Strings = (
'200'
'240'
'480'
'600'
'768'
'1024'
'1200'
'2048'
'2400')
end
object cbWidth: TComboBox
Left = 112
Top = 20
Width = 121
Height = 21
Anchors = [akLeft, akTop, akRight]
ItemHeight = 13
TabOrder = 1
OnChange = txtWidthChange
Items.Strings = (
'320'
'640'
'800'
'1024'
'1280'
'1600'
'1920'
'2048'
'2560'
'3200')
end
end
object GroupBox4: TGroupBox
Left = 8
Top = 392
Width = 377
Height = 113
Anchors = [akLeft, akTop, akRight]
Caption = ' Parameters '
TabOrder = 5
Visible = False
DesignSize = (
377
113)
object udStrips: TUpDown
Left = 172
Top = 52
Width = 12
Height = 21
Associate = txtStrips
Min = 1
Max = 512
Position = 1
TabOrder = 2
end
object Label7: TPanel
Left = 8
Top = 20
Width = 105
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'Buffer depth'
ParentShowHint = False
ShowHint = True
TabOrder = 7
end
object Label8: TPanel
Left = 8
Top = 52
Width = 105
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'Strips'
ParentShowHint = False
ShowHint = True
TabOrder = 8
end
object Label9: TPanel
Left = 8
Top = 84
Width = 105
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'DE Radius'
ParentShowHint = False
ShowHint = True
TabOrder = 9
end
object txtEstimator: TEdit
Left = 112
Top = 84
Width = 73
Height = 21
TabOrder = 3
Text = '5'
end
object txtStrips: TEdit
Left = 112
Top = 52
Width = 60
Height = 21
TabOrder = 1
Text = '1'
end
object cmbDepth: TComboBox
Left = 112
Top = 20
Width = 73
Height = 21
Style = csDropDownList
ItemHeight = 13
TabOrder = 0
Items.Strings = (
'16-bit'
'32-bit'
'32-bit float'
'64-bit')
end
object Label14: TPanel
Left = 192
Top = 20
Width = 105
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'Gamma threshold'
ParentShowHint = False
ShowHint = True
TabOrder = 10
end
object Label12: TPanel
Left = 192
Top = 52
Width = 105
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'DE Curve'
ParentShowHint = False
ShowHint = True
TabOrder = 11
end
object Label11: TPanel
Left = 192
Top = 84
Width = 105
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'DE Minimum'
ParentShowHint = False
ShowHint = True
TabOrder = 12
end
object txtGammaTreshold: TEdit
Left = 296
Top = 20
Width = 73
Height = 21
Anchors = [akLeft, akTop, akRight]
TabOrder = 6
Text = '0.01'
OnChange = txtGammaTresholdChange
end
object txtEstimatorCurve: TEdit
Left = 296
Top = 52
Width = 73
Height = 21
Anchors = [akLeft, akTop, akRight]
TabOrder = 5
Text = '0.6'
end
object txtEstimatorMin: TEdit
Left = 296
Top = 84
Width = 73
Height = 21
Anchors = [akLeft, akTop, akRight]
TabOrder = 4
Text = '0'
end
end
object chkRender: TCheckBox
Left = 392
Top = 398
Width = 89
Height = 43
Anchors = [akTop, akRight]
Caption = 'Render'
Checked = True
State = cbChecked
TabOrder = 6
Visible = False
end
object Panel1: TPanel
Left = 8
Top = 296
Width = 481
Height = 89
Anchors = [akLeft, akTop, akRight]
BevelKind = bkSoft
BevelOuter = bvNone
Color = clInfoBk
TabOrder = 7
Visible = False
DesignSize = (
477
85)
object Label6: TLabel
Left = 8
Top = 4
Width = 453
Height = 24
Alignment = taCenter
Anchors = [akLeft, akTop, akRight]
AutoSize = False
Caption = 'WARNING!'
Font.Charset = DEFAULT_CHARSET
Font.Color = clInfoText
Font.Height = -19
Font.Name = 'MS Sans Serif'
Font.Style = [fsBold]
ParentFont = False
end
object Label15: TLabel
Left = 8
Top = 25
Width = 447
Height = 26
Alignment = taCenter
Anchors = [akLeft, akRight]
Caption =
'Fractals created with this version of Apophysis are not supporte' +
'd by the external renderer! To render 2D-only fractals, download' +
' the latest version of FLAM3 from http://www.flam3.com'
Color = clInfoBk
Font.Charset = DEFAULT_CHARSET
Font.Color = clInfoText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentColor = False
ParentFont = False
WordWrap = True
end
end
object txtDensity: TEdit
Left = 120
Top = 212
Width = 105
Height = 21
Anchors = [akLeft, akTop, akRight]
TabOrder = 8
Visible = False
OnChange = txtDensityChange
end
object Label4: TPanel
Left = 8
Top = 212
Width = 113
Height = 21
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'Density'
ParentShowHint = False
ShowHint = True
TabOrder = 9
Visible = False
end
object SaveDialog: TSaveDialog
DefaultExt = 'jpg'
Filter =
'JPEG Image (*.jpg)|*.jpg|PPM Image (*.ppm)|*.ppm|PNG Images (*.p' +
'ng)|*.png'
Left = 464
Top = 264
end
end

View File

@ -1,257 +0,0 @@
{
Apophysis Copyright (C) 2001-2004 Mark Townsend
Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov
Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
}
unit FormExportC;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, ComCtrls, ExtCtrls, Translation;
type
TExportCDialog = class(TForm)
btnOK: TButton;
btnCancel: TButton;
GroupBox1: TGroupBox;
btnBrowse: TSpeedButton;
txtFilename: TEdit;
SaveDialog: TSaveDialog;
GroupBox3: TGroupBox;
txtOversample: TEdit;
txtFilterRadius: TEdit;
udOversample: TUpDown;
GroupBox2: TGroupBox;
chkMaintain: TCheckBox;
cbWidth: TComboBox;
cbHeight: TComboBox;
GroupBox4: TGroupBox;
cmbDepth: TComboBox;
chkRender: TCheckBox;
txtStrips: TEdit;
udStrips: TUpDown;
txtEstimator: TEdit;
txtEstimatorMin: TEdit;
txtEstimatorCurve: TEdit;
txtGammaTreshold: TEdit;
Panel1: TPanel;
Label6: TLabel;
Label15: TLabel;
Label13: TLabel;
Label16: TLabel;
Label5: TPanel;
Label3: TPanel;
Label1: TPanel;
Label2: TPanel;
Label7: TPanel;
Label8: TPanel;
Label9: TPanel;
Label14: TPanel;
Label12: TPanel;
Label11: TPanel;
Label10: TPanel;
txtDensity: TEdit;
Label4: TPanel;
procedure FormCreate(Sender: TObject);
procedure btnBrowseClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure btnOKClick(Sender: TObject);
procedure txtWidthChange(Sender: TObject);
procedure chkMaintainClick(Sender: TObject);
procedure txtHeightChange(Sender: TObject);
procedure txtDensityChange(Sender: TObject);
procedure txtFilterRadiusChange(Sender: TObject);
procedure txtOversampleChange(Sender: TObject);
procedure txtGammaTresholdChange(Sender: TObject);
private
FloatFormatSettings: TFormatSettings;
Estimator, EstimatorMin, EstimatorCurve: double;
Jitters, Batches, Strips: integer;
public
Filename: string;
ImageWidth, ImageHeight, Oversample: Integer;
Sample_Density, Filter_Radius: double;
GammaTreshold: double;
end;
var
ExportCDialog: TExportCDialog;
Ratio: double;
implementation
uses Global, Main, ShellAPI;
{$R *.DFM}
procedure TExportCDialog.btnBrowseClick(Sender: TObject);
begin
SaveDialog.InitialDir := ExtractFileDir(txtFilename.text);
SaveDialog.Filename := txtFilename.Text;
SaveDialog.DefaultExt := 'png';
SaveDialog.filterIndex := ExportFileFormat;
SaveDialog.Filter := Format('%s|*.png|%s|*.*',
[TextByKey('common-filter-png'),
TextByKey('common-filter-allfiles')]);
if SaveDialog.Execute then
begin
ExportFileFormat := SaveDialog.FilterIndex;
renderPath := ExtractFilePath(SaveDialog.Filename);
end;
end;
procedure TExportCDialog.FormShow(Sender: TObject);
begin
txtFilename.Text := Filename;
cbWidth.Text := IntToStr(MainCp.Width);
cbHeight.Text := IntToStr(MainCp.Height);
ImageWidth := MainCp.Width;
ImageHeight := MainCp.Height;
txtDensity.text := FloatToStr(Sample_density);
// if cmbDepth.ItemIndex <> 2 then
// txtBatches.text := IntToStr(Round(Sample_density / 4));
txtFilterRadius.text := FloatToStr(Filter_Radius);
txtOversample.text := IntToSTr(Oversample);
udOversample.Position := Oversample;
Ratio := ImageWidth / ImageHeight;
Batches := 1;
Estimator := 9.0;
EstimatorMin := 0.0;
EstimatorCurve := 0.4;
Jitters := 1;
GammaTreshold := MainCP.gamma_threshold; //0.01;
GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, FloatFormatSettings);
txtEstimator.Text := FloatToStr(Estimator, FloatFormatSettings);
txtEstimatorMin.Text := FloatToStr(EstimatorMin, FloatFormatSettings);
txtEstimatorCurve.Text := FloatToStr(EstimatorCurve, FloatFormatSettings);
// txtJitters.Text := IntToStr(Jitters);
txtGammaTreshold.Text := FloatToStr(GammaTreshold, FloatFormatSettings);
end;
procedure TExportCDialog.btnOKClick(Sender: TObject);
begin
Filename := txtFilename.text;
ImageWidth := StrToInt(cbWidth.Text);
ImageHeight := StrToInt(cbHeight.Text);
end;
procedure TExportCDialog.txtWidthChange(Sender: TObject);
begin
try
ImageWidth := StrToInt(cbWidth.Text);
if chkMaintain.checked and cbWidth.Focused then
begin
ImageHeight := Round(ImageWidth / ratio);
cbHeight.Text := IntToStr(ImageHeight)
end;
except
end;
end;
procedure TExportCDialog.chkMaintainClick(Sender: TObject);
begin
Ratio := ImageWidth / ImageHeight;
end;
procedure TExportCDialog.txtHeightChange(Sender: TObject);
begin
try
ImageHeight := StrToInt(cbHeight.Text);
if chkMaintain.checked and cbHeight.Focused then
begin
ImageWidth := Round(ImageHeight * ratio);
cbWidth.Text := IntToStr(ImageWidth)
end;
except
end;
end;
procedure TExportCDialog.txtDensityChange(Sender: TObject);
begin
try
Sample_Density := StrToFloat(txtDensity.Text);
// if cmbDepth.ItemIndex <> 2 then
// txtBatches.text := IntToStr(Round(Sample_density / 4));
except
end;
end;
procedure TExportCDialog.txtFilterRadiusChange(Sender: TObject);
begin
try
Filter_Radius := StrToFloat(txtFilterRadius.Text);
except
end;
end;
procedure TExportCDialog.txtOversampleChange(Sender: TObject);
begin
if StrToInt(txtOversample.Text) > udOversample.Max then
txtOversample.Text := IntToStr(udOversample.Max);
if StrToInt(txtOversample.Text) < udOversample.Min then
txtOversample.Text := IntToStr(udOversample.Min);
try
Oversample := StrToInt(txtOversample.Text);
except
end;
end;
procedure TExportCDialog.txtGammaTresholdChange(Sender: TObject);
begin
//GammaTreshold := 0.01;
try
GammaTreshold := StrToFloat(txtGammaTreshold.Text, FloatFormatSettings);
except
end;
end;
procedure TExportCDialog.FormCreate(Sender: TObject);
begin
btnOK.Caption := TextByKey('common-ok');
btnCancel.Caption := TextByKey('common-cancel');
Label1.Caption := TextByKey('common-width');
Label2.Caption := TextByKey('common-height');
GroupBox2.Caption := TextByKey('common-size');
Label13.Caption := TextByKey('common-pixels');
chkMaintain.Caption := TextByKey('common-keepaspect');
GroupBox1.Caption := TextByKey('common-destination');
Label10.Caption := TextByKey('common-filename');
btnBrowse.Hint := TextByKey('common-browse');
GroupBox3.Caption := TextByKey('common-quality');
Label5.Caption := TextByKey('common-filterradius');
Label4.Caption := TextByKey('common-density');
Label3.Caption := TextByKey('common-oversample');
Label14.Caption := TextByKey('common-gammathreshold');
self.Caption := TextByKey('main-menu-file-exportchaotica');
GroupBox4.Caption := TextByKey('export-paramoptions-title');
Label7.Caption := TextByKey('export-paramoptions-bufferdepth');
Label8.Caption := TextByKey('export-paramoptions-strips');
Label9.Caption := TextByKey('export-paramoptions-estimatorradius');
Label12.Caption := TextByKey('export-paramoptions-estimatorcurve');
Label11.Caption := TextByKey('export-paramoptions-estimatormin');
chkRender.Caption := TextByKey('export-paramoptions-dorender');
Label6.Caption := TextByKey('export-paramoptions-warningtitle');
Label15.Caption := TextByKey('export-paramoptions-warningtext');
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
@ -27,7 +27,7 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, ComCtrls, Translation, Vcl.Buttons;
StdCtrls, ExtCtrls, ComCtrls, Vcl.Buttons;
type
TFavoritesForm = class(TForm)
@ -66,7 +66,8 @@ var
implementation
uses Global, ScriptForm;
uses Global, ScriptForm, Translation;
{$R *.DFM}
procedure TFavoritesForm.FormShow(Sender: TObject);
@ -85,15 +86,9 @@ begin
Listitem.Caption := s;
end;
if Favorites.Count <> 0 then
ScriptList.Selected := ScriptList.Items[0]
else
btnRemove.Enabled := False;
ScriptList.Selected := ScriptList.Items[0];
if ScriptList.Items.Count <= 1 then
begin
btnMoveUp.Enabled := False;
btnMoveDown.Enabled := False;
end;
ScriptListChange(Sender, ScriptList.Selected, ctText); // AV
end;
procedure TFavoritesForm.btnOKClick(Sender: TObject);
@ -131,7 +126,8 @@ begin
s := AppPath + 'Scripts';
if DirectoryExists(s) then
ScriptEditor.MainOpenDialog.InitialDir := s
else ScriptEditor.MainOpenDialog.InitialDir := ParamFolder;
else
ScriptEditor.MainOpenDialog.InitialDir := ParamFolder;
ScriptEditor.MainOpenDialog.Filter := Format('%s|*.aposcript;*.asc|%s|*.*',
[TextByKey('common-filter-scriptfiles'),
TextByKey('common-filter-allfiles')]);
@ -148,14 +144,9 @@ begin
s := Copy(s, 0, length(s) - Length(ExtractFileExt(s)));
Listitem.Caption := s;
ScriptList.Selected := ScriptList.Items[ScriptList.Items.Count - 1];
btnRemove.Enabled := True;
end;
if ScriptList.Items.Count <= 1 then
begin
btnMoveUp.Enabled := False;
btnMoveDown.Enabled := False;
end;
ScriptListChange(Sender, ScriptList.Selected, ctText); // AV
end;
procedure TFavoritesForm.btnRemoveClick(Sender: TObject);
@ -170,15 +161,9 @@ begin
if i < ScriptList.Items.Count then
ScriptList.Selected := ScriptList.Items[i]
else
ScriptList.Selected := ScriptList.Items[ScriptList.Items.Count - 1]
else
btnRemove.Enabled := False;
ScriptList.Selected := ScriptList.Items[ScriptList.Items.Count - 1];
if ScriptList.Items.Count <= 1 then
begin
btnMoveUp.Enabled := False;
btnMoveDown.Enabled := False;
end;
ScriptListChange(Sender, ScriptList.Selected, ctText); // AV
end;
procedure TFavoritesForm.btnSortClick(Sender: TObject);
@ -200,15 +185,28 @@ begin
end;
ScriptList.Items.EndUpdate;
scripts.Free;
ScriptListChange(Sender, ScriptList.Selected, ctText); // AV
end;
procedure TFavoritesForm.ScriptListChange(Sender: TObject; Item: TListItem;
Change: TItemChange);
var
n: smallint;
IsSel: boolean;
begin
// TODO: optimize old code
btnRemove.Enabled := (ScriptList.Items.Count > 0);
n := ScriptList.Items.Count;
IsSel := assigned(ScriptList.Selected);
if (Item.Index = ScriptList.Items.Count - 1) then
btnRemove.Enabled := (n > 0) and IsSel;
btnSort.Enabled := (n > 1);
if (n <= 1) or (not IsSel) then
begin
btnMoveDown.Enabled := False;
btnMoveUp.Enabled := False;
end
else begin
if (Item.Index = n - 1) then
btnMoveDown.Enabled := False
else
btnMoveDown.Enabled := True;
@ -216,11 +214,6 @@ begin
btnMoveUp.Enabled := False
else
btnMoveUp.Enabled := True;
if (ScriptList.Items.Count <= 1) then
begin
btnMoveDown.Enabled := False;
btnMoveUp.Enabled := False;
end;
end;
@ -250,7 +243,7 @@ procedure TFavoritesForm.btnClearClick(Sender: TObject);
begin
ScriptList.Items.Clear;
Faves.Clear;
btnRemove.Enabled := False;
ScriptListChange(Sender, ScriptList.Selected, ctText); // AV
end;
procedure TFavoritesForm.btnMoveDownClick(Sender: TObject);

View File

@ -241,19 +241,6 @@ object RenderForm: TRenderForm
DesignSize = (
233
97)
object lblRatio: TLabel
Left = 12
Top = 72
Width = 56
Height = 13
Caption = 'Aspect ratio'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
end
object pnlWidth: TPanel
Left = 8
Top = 20
@ -349,9 +336,9 @@ object RenderForm: TRenderForm
'3200')
end
object cbAspectRatio: TComboBox
Left = 101
Top = 70
Width = 123
Left = 100
Top = 68
Width = 125
Height = 21
Style = csDropDownList
Font.Charset = DEFAULT_CHARSET
@ -372,6 +359,21 @@ object RenderForm: TRenderForm
'16 : 10'
'21 : 9 (CinemaScope)')
end
object lblRatio: TPanel
Left = 8
Top = 68
Width = 92
Height = 21
BevelOuter = bvLowered
Caption = 'Aspect ratio'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentFont = False
TabOrder = 5
end
end
object GroupBox3: TGroupBox
Left = 248
@ -874,10 +876,6 @@ object RenderForm: TRenderForm
object TabOutput: TTabSheet
Caption = 'Output'
ImageIndex = 38
ExplicitLeft = 0
ExplicitTop = 0
ExplicitWidth = 0
ExplicitHeight = 0
object Output: TMemo
Left = 0
Top = 0
@ -958,13 +956,142 @@ object RenderForm: TRenderForm
OnClick = btnSnapshotClick
end
object SaveDialog: TSaveDialog
Left = 456
Left = 448
Top = 72
end
object ProgressTaskbar: TTaskbar
TaskBarButtons = <>
TaskBarButtons = <
item
Hint = 'Show image state...'
Icon.Data = {
0000010001001616000000000000900600001600000028000000160000002C00
0000010008000000000010020000000000000000000000010000000000005858
5800B0B0B000F9F9F90092929200EAEAEA0083838300DBDBDB00AEAEAE004747
47009F9F9F00E8E8E80081818100D9D9D90063636300BBBBBB00545454009D9D
9D008E8E8E007F7F7F00D7D7D7007070700052525200AAAAAA008C8C8C00E4E4
E4007D7D7D00D5D5D5006E6E6E00C6C6C6005F5F5F0050505000A8A8A8007B7B
7B00B5B5B5004E4E4E003F3F3F0097979700D1D1D100C2C2C2005B5B5B00B3B3
B300A4A4A4003D3D3D009595950086868600DEDEDE007777770068686800C0C0
C00059595900B1B1B1004A4A4A00A2A2A20084848400DCDCDC0075757500CDCD
CD006666660057575700AFAFAF004848480091919100DADADA00CBCBCB005555
55009E9E9E00C9C9C90062626200BABABA009C9C9C008D8D8D007E7E7E00D6D6
D600C7C7C700F2F2F200E3E3E3007C7C7C00D4D4D4005E5E5E0040404000FFFF
FF009898980089898900E1E1E100B4B4B400FDFDFD003E3E3E00EEEEEE008787
8700C1C1C100FBFBFB008585850076767600CECECE0000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000005050
5050505050505050505050505050505050505050000050505050505050505050
5050505050505050505050500000505050505050505050505050505050505050
5050505000002A2A2A5050505050502A2A2A5050505050502A2A2A5000002A2A
2A502A502A502A2A2A2A2A502A502A502A2A2A5000002A2A5050505050505050
5050505050505050502A2A500000505050165151033D3D58523D3D5151415152
505050500000502A502429584C332339374C583D51490952502A505000005050
50472E35121041462A432A394C523D1B5050505000005008505C412A2A451F26
162B4F2E402A433C502A505000005050502A3E3D2C172A0725500E102750050E
5050505000000F1E502A3D5D32545139073F505D53575713502A2A5000000040
50442A014B4B501C2A50444B04183E1C502A2A5000004E315021595050503B38
4D0E0A5A505A0459502A2A5000005050501F0E59502149064806025050500242
505050500000500D5034443F3F3F0C364D2D55505050553F502A505000005050
50412830305959301C1A4A5050504A59505050500000501B50241F0101010101
0101493E533E4901502A50500000505050112B24244541414141411F071F4141
505050500000202E50505050505050505050505050505050502A2A5000000B4C
2E5014502F504E273A152250085056502A2A2A5000005B0B195050505050501D
27005050505050502A2A2A500000FFFFFF00FFFFFF00FFFFFF001F8FC7000000
04000000040080000C0080000E0080000E0080000E0080000E00000006000000
04000000040080000C0080000E0080000E0080000E0080000E00000006000000
04001F8FC400}
end
item
Hint = 'Cancel current rendering'
Icon.Data = {
0000010001001616000000000000100800001600000028000000160000002C00
000001002000000000009007000000000000000000000000000000000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF005555550E545454495454
547E545454B2545454E5545454E5545454B25454547E545454495555550EFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF0054545450545454E7515151FF4E4E4EFF4B4B4BFF4848
48FF484848FF4B4B4BFF4E4E4EFF515151FF545454E754545450FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00565656115555
55A4535353FF4C4C4CFF555555FF757575FF989898FFBFBFBFFFC0C0C0FF9C9C
9CFF797979FF575757FF4C4C4CFF535353FF555555A456565611FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF0057575711565656E1525252FF494949FF8181
81FFD9D9D9FFE5E5E5FFEBEBEBFFEEEEEEFFEFEFEFFFEEEEEEFFEBEBEBFFE2E2
E2FF8C8C8CFF494949FF525252FF565656E157575711FFFFFF00FFFFFF00FFFF
FF00FFFFFF00565656A4525252FF555555FFB1B1B1FFE1E1E1FFECECECFFF3F3
F3FFF8F8F8FFFBFBFBFFFBFBFBFFFBFBFBFFF8F8F8FFF3F3F3FFECECECFFC2C2
C2FF585858FF525252FF565656A4FFFFFF00FFFFFF00FFFFFF00575757505555
55FF4A4A4AFFACACACFFE1E1E1FFEEEEEEFFF7F7F7FFFCFCFCFFFDFDFDFFFFFF
FFFFFFFFFFFFFFFFFFFFFDFDFDFFFCFCFCFFF7F7F7FFEEEEEEFFC2C2C2FF4A4A
4AFF555555FF57575750FFFFFF005959590E585858E74F4F4FFF7C7C7CFFDCDC
DCFFECECECFFF6F6F6FFE9E9E9FFEBEBEBFFEAEAEAFFE9E9E9FFE9E9E9FFE9E9
E9FFEAEAEAFFEBEBEBFFFAFAFAFFF7F7F7FFECECECFF8D8D8DFF4F4F4FFF5858
58E75959590E5B5B5B49585858FF595959FFC8C8C8FFE5E5E5FFF3F3F3FFF2F2
F2FF5F5F5FFF515151FF464646FF3E3E3EFF3B3B3BFF3E3E3EFF464646FF5151
51FFEBEBEBFFFCFCFCFFF3F3F3FFE2E2E2FF5B5B5BFF585858FF5B5B5B495D5D
5D7E565656FF717171FFD5D5D5FFEBEBEBFFF8F8F8FFF2F2F2FF545454FF4444
44FF363636FF2B2B2BFF272727FF2B2B2BFF363636FF444444FFEAEAEAFFFDFD
FDFFF8F8F8FFEBEBEBFF7C7C7CFF565656FF5D5D5D7E5F5F5FB2545454FF8989
89FFDCDCDCFFEEEEEEFFFBFBFBFFF2F2F2FF4D4D4DFF3B3B3BFF2A2A2AFF1B1B
1BFF131313FF1B1B1BFF2A2A2AFF3B3B3BFFE9E9E9FFFFFFFFFFFBFBFBFFEEEE
EEFF9E9E9EFF545454FF5F5F5FB2616161E5535353FFA4A4A4FFDDDDDDFFEFEF
EFFFFBFBFBFFF0F0F0FF4B4B4BFF383838FF252525FF121212FF000000FF1212
12FF252525FF383838FFE8E8E8FFFFFFFFFFFBFBFBFFEFEFEFFFC1C1C1FF5353
53FF616161E5636363E5555555FFA4A4A4FFDCDCDCFFEEEEEEFFFBFBFBFFF1F1
F1FF6A6A6AFF5E5E5EFF535353FF474747FF373737FF313131FF363636FF4040
40FFE9E9E9FFFFFFFFFFFBFBFBFFEEEEEEFFC0C0C0FF555555FF636363E56565
65B25A5A5AFF8A8A8AFFD5D5D5FFEEEEEEFFFAFAFAFFF4F4F4FF8C8C8CFF7A7A
7AFF686868FF565656FF4B4B4BFF464646FF474747FF4D4D4DFFEAEAEAFFFDFD
FDFFF8F8F8FFEBEBEBFF9B9B9BFF5A5A5AFF656565B26767677E606060FF7575
75FFDCDCDCFFF1F1F1FFF8F8F8FFF2F2F2FF939393FF838383FF747474FF6565
65FF5B5B5BFF565656FF565656FF595959FFEBEBEBFFFCFCFCFFF3F3F3FFE5E5
E5FF7C7C7CFF606060FF6767677E6B6B6B49676767FF636363FFC5C5C5FFECEC
ECFFF4F4F4FFEFEFEFFF979797FF8E8E8EFF818181FF747474FF6B6B6BFF6767
67FF656565FF686868FFE9E9E9FFF7F7F7FFECECECFFDADADAFF636363FF6767
67FF6B6B6B497070700E6F6F6FE7636363FF828282FFDCDCDCFFEDEDEDFFF3F3
F3FFEEEEEEFFF1F1F1FFF1F1F1FFF3F3F3FFF3F3F3FFF4F4F4FFF3F3F3FFF3F3
F3FFF6F6F6FFEEEEEEFFE1E1E1FF888888FF636363FF6F6F6FE77070700EFFFF
FF00727272506F6F6FFF5E5E5EFFA9A9A9FFDEDEDEFFECECECFFF2F2F2FFF6F6
F6FFFAFAFAFFFCFCFCFFFCFCFCFFFCFCFCFFF9F9F9FFF4F4F4FFECECECFFE1E1
E1FFB3B3B3FF5E5E5EFF6F6F6FFF72727250FFFFFF00FFFFFF00FFFFFF007575
75A46F6F6FFF686868FFAAAAAAFFD7D7D7FFE7E7E7FFECECECFFF0F0F0FFF1F1
F1FFF2F2F2FFF0F0F0FFEDEDEDFFE6E6E6FFDCDCDCFFAFAFAFFF686868FF6F6F
6FFF757575A4FFFFFF00FFFFFF00FFFFFF00FFFFFF0079797911787878E17171
71FF636363FF858585FFC2C2C2FFD6D6D6FFDFDFDFFFE3E3E3FFE3E3E3FFE0E0
E0FFD8D8D8FFCACACAFF858585FF636363FF717171FF787878E179797911FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF007D7D7D117B7B7BA4797979FF6E6E
6EFF6E6E6EFF7C7C7CFF8F8F8FFFA9A9A9FFA8A8A8FF8F8F8FFF7C7C7CFF6E6E
6EFF6E6E6EFF797979FF7B7B7BA47D7D7D11FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF007F7F7F507F7F7FE77B7B7BFF7676
76FF727272FF6E6E6EFF6E6E6EFF727272FF767676FF7B7B7BFF7F7F7FE77F7F
7F50FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF008585850E838383498383837E848484B28484
84E5848484E5848484B28383837E838383498585850EFFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FF87FF00FC00FF00F0003F00E0001F00C000
0F00C0000F008000070080000600800006000000020000000000000000000000
0000800004008000060080000600C0000E00C0000F00E0001F00F0003F00FC00
FF00FF87FF00}
end>
ProgressMaxValue = 100
TabProperties = []
OnThumbButtonClick = ProgressTaskbarThumbButtonClick
Left = 432
Top = 424
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,10 +27,10 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, Math, Buttons, Registry, ExtCtrls, MMSystem, // Windows7,
StdCtrls, ComCtrls, Math, Buttons, Registry, ExtCtrls, MMSystem,
System.Win.TaskbarCore, Vcl.Taskbar, Vcl.Samples.Spin, // AV
ControlPoint, RenderThread, cmap, RenderingCommon, RenderingInterface,
ShellAPI, Translation, ActiveX, ComObj;
ControlPoint, cmap, RenderThread, RenderingInterface,
ShellAPI, ActiveX, ComObj;
const
{$ifdef T500}
@ -39,6 +39,10 @@ const
rendersAV = 'rendersAV.flame';
{$endif}
type
TWin32Version = (wvUnknown, wvWin95, wvWin98, wvWinNT, wvWin2000, wvWinXP,
wvWinVista, wvWin7, wvWinFutureFromOuterSpace);
type
TRenderForm = class(TForm)
btnRender: TButton;
@ -93,12 +97,12 @@ type
chkSaveIncompleteRenders: TCheckBox;
lblCPUCores: TLabel;
cbAspectRatio: TComboBox;
lblRatio: TLabel;
chkEmbedFlame: TCheckBox;
chkPlaySound: TCheckBox;
btnSnapshot: TButton;
ProgressTaskbar: TTaskbar;
sbFilterRadius: TSpinButton;
lblRatio: TPanel;
procedure btnSaveLogClick(Sender: TObject);
procedure btnDonateClick(Sender: TObject);
procedure cbMaxMemoryChange(Sender: TObject);
@ -133,10 +137,12 @@ type
procedure txtDensityExit(Sender: TObject);
procedure cbWidthExit(Sender: TObject);
procedure cbHeightExit(Sender: TObject);
procedure ProgressTaskbarThumbButtonClick(Sender: TObject;
AButtonID: Integer);
private
StartTime, EndTime, oldElapsed, edt: TDateTime;
oldProg: double;
PhysicalMemory, ApproxMemory, TotalPhysicalMemory: int64;
ApproxSamples: int64;
procedure DoPostProcess;
@ -148,27 +154,28 @@ type
procedure ListPresets;
function WindowsExit(RebootParam: Longword = EWX_POWEROFF or EWX_FORCE): Boolean;
procedure Save(const str: string);
function IsLimitingMemory():boolean;
function IsLimitingMemory(): boolean;
procedure OnProgress(prog: double);
procedure ShowMemoryStatus;
public
Renderer: TRenderThread;
PhysicalMemory, ApproxMemory, TotalPhysicalMemory: int64;
ColorMap: TColorMap;
//ColorMap: TColorMap;
cp: TControlPoint;
Filename: string;
ImageWidth, ImageHeight, Oversample: Integer;
// BitsPerSample: integer; Brightness, Gamma, Vibrancy: double;
zoom, Sample_Density, Filter_Radius: double;
center: array[0..1] of double;
Sample_Density, Filter_Radius: double;
MaxMemory: integer;
bRenderAll: boolean;
procedure OnProgress(prog: double);
procedure ShowMemoryStatus;
RenderFlameFile: string; // AV
FlameNames: array of string; // AV
procedure ResetControls;
end;
function GetCpuCount: integer; // AV: this is used in Options
function GetWinVersion: TWin32Version; // AV: moved from Main
var
RenderForm: TRenderForm;
@ -177,7 +184,7 @@ var
implementation
uses
Main, Global, SavePreset, formPostProcess, PngImage, ImageMaker,Tracer;
Main, Global, SavePreset, formPostProcess, ImageMaker, Tracer, Translation;
{$R *.DFM}
@ -197,7 +204,6 @@ begin
txtOversample.Enabled := true;
//chkLimitMem.Enabled := true;
cbMaxMemory.enabled := true;
//cbBitsPerSample.Enabled := true;
chkPostProcess.Enabled := not IsLimitingMemory;
chkSaveIncompleteRenders.Enabled := not IsLimitingMemory;
btnRender.Enabled := true;
@ -225,7 +231,6 @@ begin
pnlOversample.Enabled := true;
pnlLimit.Enabled := true;
pnlTarget.Enabled := true;
//pnlBufferDepth.Enabled := true;
pnlWidth.Font.Color := clWindowText;
pnlHeight.Font.Color := clWindowText;
@ -234,27 +239,9 @@ begin
pnlOversample.Font.Color := clWindowText;
pnlLimit.Font.Color := clWindowText;
pnlTarget.Font.Color := clWindowText;
//pnlBufferDepth.Font.Color := clWindowText;
ShowMemoryStatus;
end;
procedure WinShellExecute(const Operation, AssociatedFile: string);
var
a1: string;
begin
a1 := Operation;
if a1 = '' then
a1 := 'open';
ShellExecute(
application.handle
, pchar(a1)
, pchar(AssociatedFile)
, ''
, ''
, SW_SHOWNORMAL
);
end;
function GetCpuCount: integer;
var
si: TSystemInfo;
@ -273,10 +260,11 @@ begin
TotalPhysicalMemory := GlobalMemoryInfo.dwTotalPhys div 1048576;
//TotalPhysicalMemory := TotalPhysicalMemory * 9 div 10; // assume that OS will take 10% of RAM ;)
if SingleBuffer then
ApproxMemory := int64(ImageHeight) * int64(ImageWidth) * sqr(Oversample) * 16 div 1048576
else
{$ifdef CPUX86}
ApproxMemory := int64(ImageHeight) * int64(ImageWidth) * sqr(Oversample) * 16 div 1048576;
{$else}
ApproxMemory := int64(ImageHeight) * int64(ImageWidth) * sqr(Oversample) * 32 div 1048576;
{$endif}
lblMemory.Caption := Format(TextByKey('render-resourceusage-infotext'), [ApproxMemory, PhysicalMemory]);
PBMem.Position := round(100 * (ApproxMemory / PhysicalMemory));
@ -372,7 +360,7 @@ begin
on e: Exception do begin
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-saveerror-log'));
tryAgain := (Application.MessageBox(PChar(TextByKey('render-status-saveerror-message1') + #13#10 + e.Message +
#13#10 + TextByKey('render-status-saveerror-message2')), 'Apophysis', MB_RETRYCANCEL or MB_ICONERROR) = IDRETRY);
#13#10 + TextByKey('render-status-saveerror-message2')), ApophysisSVN, MB_RETRYCANCEL or MB_ICONERROR) = IDRETRY);
// AV: displaying status in red
ProgressTaskBar.ProgressState := TTaskBarProgressState.Error;
end;
@ -419,7 +407,6 @@ begin
Trace2(MsgAnotherRunning);
exit;
end;
{
// AV: temporary commented out since undestroyed TBaseRenderer objects
// from Renderer.GetRenderer method cause regular large memory leaks!
@ -468,6 +455,7 @@ begin
if ShowProgress then begin
ProgressBar2.Position := round(100 * prog);
// AV: to display the progress on the taskbar
//ProgressTaskBar.ProgressState := TTaskBarProgressState.Normal; // AV
ProgressTaskBar.ProgressValue := ProgressBar2.Position; // AV
end;
@ -491,13 +479,32 @@ begin
Trunc(Remaining * 24 * 60 * 60 * 100) mod 100]);
end;
StatusBar.Panels[2].text := Format(TextByKey('render-status-slicestatus'), [(Renderer.Slice + 1), (Renderer.nrSlices)]);
//'Slice ' + IntToStr(Renderer.Slice + 1) + ' of ' + IntToStr(Renderer.nrSlices);
Application.ProcessMessages;
end;
procedure TRenderForm.ProgressTaskbarThumbButtonClick(Sender: TObject;
AButtonID: Integer);
begin
if AButtonID = 0 then
begin
if Assigned(Renderer) and (not bRenderAll) then begin
if Renderer.Suspended = false then
begin
Renderer.Suspend;
btnSnapshotClick(Sender);
Renderer.Resume;
end else
btnSnapshotClick(Sender);
end;
end
else
btnCancelClick(Sender);
end;
procedure TRenderForm.FormCreate(Sender: TObject);
begin
{$ifdef Apo7X64}
{$ifdef CPUX64}
cbMaxMemory.Items.Add('2048');
cbMaxMemory.Items.Add('3072');
cbMaxMemory.Items.Add('4096');
@ -519,12 +526,12 @@ begin
btnPause.Caption := TextByKey('common-pause');
btnCancel.Caption := TextByKey('common-close');
self.Caption := TextByKey('render-title');
self.Hint := self.Caption; // AV: hack
TabSettings.Caption := TextByKey('render-tab-settings-title');
TabOutput.Caption := TextByKey('render-tab-output-title');
btnGoTo.Hint := TextByKey('render-common-gotofolder');
GroupBox4.Caption := TextByKey('render-resourceusage-title');
pnlLimit.Caption := TextByKey('render-resourceusage-limit');
//pnlBufferDepth.Caption := TextByKey('render-resourceusage-bufferdepth');
chkSave.Caption := TextByKey('render-output-saveparams1');
chkEmbedFlame.Caption := TextByKey('render-output-saveparams2');
GroupBox6.Caption := TextByKey('render-completion-title');
@ -541,11 +548,18 @@ begin
btnDonate.Hint := TextByKey('common-donatehint');
btnSnapshot.Caption := TextByKey('render-status-dosnapshot'); // AV
btnSnapshot.Hint := TextByKey('render-status-dosnapshothint');
ProgressTaskbar.TaskbarButtons[1].Hint := TextByKey('render-status-stop');
ProgressTaskbar.TaskbarButtons[0].Hint := TextByKey('render-status-showimage');
// AV: fixed the filter order and moved this here since it never changes
SaveDialog.Filter := Format('%s|*.bmp;*.dib|%s|*.png|%s|*.jpg;*.jpeg|%s|*.bmp;*.dib;*.jpg;*.jpeg;*.png',
[TextByKey('common-filter-bitmap'), TextByKey('common-filter-png'),
TextByKey('common-filter-jpeg'), TextByKey('common-filter-allimages')]);
cp := TControlPoint.Create;
cbMaxMemory.ItemIndex := 0;
cbAspectRatio.ItemIndex := 1; // AV
// BitsPerSample := 0;
MainForm.Buttons.GetBitmap(2, btnSavePreset.Glyph);
// MainForm.Buttons.GetBitmap(9, btnDeletePreset.Glyph);
bRenderAll := false;
@ -576,11 +590,10 @@ end;
procedure TRenderForm.btnRenderClick(Sender: TObject);
var
t: string;
iCurrFlame: integer;
path, ext: string;
lim:integer;
ilm:boolean;
t, ext: string;
lim: integer;
ilm: boolean;
{ sl: TStringList;
tryAgain: boolean;
cancel: boolean;
@ -599,10 +612,9 @@ begin
on e: Exception do begin
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-saveerror-log'));
result := (Application.MessageBox(PChar(TextByKey('render-status-saveerror-message1') + #13#10 + e.Message +
#13#10 + TextByKey('render-status-saveerror-message2')), 'Apophysis', MB_RETRYCANCEL or MB_ICONERROR));
#13#10 + TextByKey('render-status-saveerror-message2')), ApophysisSVN, MB_RETRYCANCEL or MB_ICONERROR));
tryAgain := (result = IDRETRY);
cancel := (result = IDCANCEL);
ProgressBar2.ProgressBarState := pbstError;
end;
end;
until (tryAgain = false) or (cancel = true);
@ -624,34 +636,25 @@ begin
if not ilm then begin
if (ApproxMemory > {Total}PhysicalMemory) then
begin
if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-notenoughmemory1')), 'Apophysis', MB_ICONWARNING or MB_YESNO) then
exit;
if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-notenoughmemory1')),
ApophysisSVN, MB_ICONWARNING or MB_YESNO) then exit;
end;
{
if (ApproxMemory > PhysicalMemory) then
begin
if Application.MessageBox('There is not enough memory for this render. ' + #13 +
'You can use memory limiting, or - if you are sure that your system *should* ' + #13 +
'have the required amount of free RAM, you can try to allocate memory anyway. ' + #13#13 +
'Dou you want to try? (SLOW AND UNSTABLE - USE AT YOUR OWN RISK!!!)', 'Apophysis',
MB_ICONWARNING or MB_YESNO) <> IDYES then exit;
end;
}
end
else if (PhysicalMemory < lim) and (Approxmemory > PhysicalMemory) then begin
if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-notenoughmemory2')), 'Apophysis', MB_ICONWARNING or MB_YESNO) then
exit;
if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-notenoughmemory2')),
ApophysisSVN, MB_ICONWARNING or MB_YESNO) then exit;
end;
t := txtFilename.Text;
if t = '' then
begin
Application.MessageBox(PChar(TextByKey('render-status-nofilename')), 'Apophysis', 48);
Exit;
if t = '' then begin
Application.MessageBox(PChar(TextByKey('render-status-nofilename')), ApophysisSVN, 48);
exit;
end;
if FileExists(t) then
if Application.MessageBox(PChar(Format(TextByKey('render-status-fileexists-message1'), [t]) + #13#10 + TextByKey('render-status-fileexists-message2')),
'Apophysis', 52) = ID_NO then exit;
if Application.MessageBox(PChar(Format(TextByKey('render-status-fileexists-message1'),
[t]) + #13#10 + TextByKey('render-status-fileexists-message2')),
ApophysisSVN, 52) = ID_NO then exit;
if not DirectoryExists(ExtractFileDir(t)) then
raise Exception.Create(TextByKey('render-status-pathdoesnotexist')); // AV
@ -665,7 +668,7 @@ begin
{
// AV: how is it possible, if (udOversample.Min = 1) and (txtOversample.ReadOnly = true)?
if Oversample < 1 then
raise Exception.Create(TextByKey('render-status-invalidoversample')); // AV
raise Exception.Create(TextByKey('render-status-invalidoversample'));
}
if ImageWidth < 1 then
raise Exception.Create(TextByKey('render-status-invalidwidth')); // AV
@ -676,13 +679,13 @@ begin
if (ilm) then
if lim * 1024*1024 < ImageWidth * (int64(ImageHeight) * 4 + oversample) then begin
// Must be enough memory to hold the final image (RGBA)
if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-maxmemorytoosmall')), 'Apophysis', MB_ICONERROR or MB_YESNO) then
exit;
if IDYES <> Application.MessageBox(PChar(TextByKey('render-status-maxmemorytoosmall')),
ApophysisSVN, MB_ICONERROR or MB_YESNO) then exit;
end;
// AV: activate the taskbar progress
ProgressTaskBar.ProgressState := TTaskBarProgressState.Normal; // AV
ProgressTaskBar.ProgressValue := ProgressBar2.Position; // AV
ProgressTaskBar.ProgressValue := 0; // AV
txtFilename.Enabled := false;
btnBrowse.Enabled := false;
@ -693,7 +696,6 @@ begin
txtOversample.Enabled := false;
//chkLimitMem.Enabled := true;
cbMaxMemory.Enabled := false;
//cbBitsPerSample.Enabled := false;
cmbPreset.enabled := false;
chkSave.enabled := false;
chkPostProcess.enabled := false;
@ -715,7 +717,6 @@ begin
pnlOversample.Enabled := false;
pnlLimit.Enabled := false;
pnlTarget.Enabled := false;
//pnlBufferDepth.Enabled := false;
pnlWidth.Font.Color := clGrayText;
pnlHeight.Font.Color := clGrayText;
@ -724,7 +725,6 @@ begin
pnlOversample.Font.Color := clGrayText;
pnlLimit.Font.Color := clGrayText;
pnlTarget.Font.Color := clGrayText;
//pnlBufferDepth.Font.Color := clGrayText;
PageCtrl.TabIndex := 1;
@ -732,8 +732,8 @@ begin
if bRenderAll then
begin
path := ExtractFilePath(FileName);
ext := ExtractFileExt(FileName);
renderPath := ExtractFilePath(FileName); // AV
ext := ExtractFileExt(FileName); // AV
if Assigned(Renderer) then begin
Output.Lines.Add(TimeToStr(Now) + TextByKey('render-status-shuttingdownrender'));
@ -743,8 +743,9 @@ begin
Renderer := nil;
end;
for iCurrFlame := 0 to MainForm.ListView1.Items.Count-1 do
for iCurrFlame := 0 to High(FlameNames) {MainForm.ListView1.Items.Count-1} do
begin
{
MainForm.ListView1.ItemIndex := iCurrFlame;
cp.Free;
cp := TControlPoint.Create;
@ -753,20 +754,27 @@ begin
zoom := maincp.zoom;
Center[0] := MainForm.center[0];
Center[1] := MainForm.center[1];
FileName := path + cp.name + ext;
}
t := LoadXMLFlameText(RenderFlameFile, FlameNames[iCurrFlame]); // AV
if t = '' then continue; // AV: user may delete an item from opened file
MainForm.ParseXML(cp, t, true); // the same was done via ListView - but slower
FileName := renderPath + cp.name + ext;
Output.Lines.Add('--- ' + Format(TextByKey('render-status-log-title'), [ExtractFileName(FileName)]) + ' ---');
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-size'), [ImageWidth, ImageHeight]));
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-quality'), [sample_density]));
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-oversampling'), [oversample, filter_radius]));
if SingleBuffer then
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['32-bit float']))
else
{$ifdef CPUX86}
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['32-bit float']));
{$else}
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['64-bit float']));
{$endif}
if (ilm) then
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-memorylimit'), [MaxMemory]))
else
if (UpperCase(ExtractFileExt(FileName)) = '.PNG') and
if (UpperCase(ext) = '.PNG') and
(ImageWidth * ImageHeight >= 20000000) then
begin
Output.Lines.Add(TextByKey('render-status-log-largepng-message1'));
@ -783,20 +791,27 @@ begin
cp.spatial_oversample := Oversample;
cp.spatial_filter_radius := Filter_Radius;
cp.AdjustScale(ImageWidth, ImageHeight);
cp.Transparency := (PNGTransparency <> 0) and (UpperCase(ExtractFileExt(FileName)) = '.PNG');
renderPath := ExtractFilePath(Filename);
if chkSave.checked then
MainForm.SaveXMLFlame(cp, ExtractFileName(FileName), renderPath + rendersAV);
cp.Transparency := (PNGTransparency <> 0) and (UpperCase(ext) = '.PNG');
// renderPath := ExtractFilePath(Filename);
if chkSave.checked then begin // AV: added check for duplicates
t := ExtractFileName(FileName);
if XMLEntryExists(t, renderPath + rendersAV) then
t := t + FormatDateTime(' (MM-dd-yyyy hh-mm-ss)', Now);
MainForm.SaveXMLFlame(cp, t, renderPath + rendersAV);
end;
oldProg:=0;
oldElapsed:=0;
edt:=0;
ApproxSamples := Round(sample_density * sqr(power(2, cp.zoom)) * int64(ImageHeight) * int64(ImageWidth) / sqr(oversample) );
oldProg := 0;
oldElapsed := 0;
edt := 0;
ApproxSamples := Round(sample_density * sqr(power(2, cp.zoom)) *
int64(ImageHeight) * int64(ImageWidth) / sqr(oversample) );
ProgressTaskBar.ProgressState := TTaskBarProgressState.Normal; // AV
try
if not bRenderAll then exit;
if iCurrFlame = MainForm.ListView1.Items.Count-1 then bRenderAll := false;
if iCurrFlame = High(FlameNames){MainForm.ListView1.Items.Count-1} then
bRenderAll := false;
Renderer := TRenderThread.Create;
assert(Renderer <> nil);
@ -806,8 +821,8 @@ begin
else
Renderer.SetPriority(tpNormal);
}
Renderer.ExportBuffer := chkBinary.Checked;
// Renderer.BitsPerSample := BitsPerSample;
//Renderer.ExportBuffer := chkBinary.Checked;
if (ilm) then
Renderer.MaxMem := lim; //StrToInt(cbMaxMemory.text);
Renderer.OnProgress := OnProgress;
@ -815,7 +830,7 @@ begin
Renderer.SetCP(cp);
if chkEmbedFlame.checked then
Renderer.EmbedText(Trim(MainForm.RetrieveXML(cp))); // AV
Renderer.EmbedText(Trim(FlameToXML(cp))); // AV
Renderer.Priority := tpLower; // tpNormal;
Renderer.NrThreads := NrTreads;
@ -827,21 +842,23 @@ begin
except
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-rendererror-log'));
//Application.MessageBox('Error while rendering!', 'Apophysis', 48);
end;
end;
end;
end else
begin
if not Assigned(Renderer) then SetLength(FlameNames, 0); // AV: free memory
end // end RenderAll
else begin
Output.Lines.Add('--- ' + Format(TextByKey('render-status-log-title'), [ExtractFileName(FileName)]) + '" ---');
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-size'), [ImageWidth, ImageHeight]));
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-quality'), [sample_density]));
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-oversampling'), [oversample, filter_radius]));
if SingleBuffer then
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['32-bit float']))
else
{$ifdef CPUX86}
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['32-bit float']));
{$else}
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-bufferdepth'), ['64-bit float']));
{$endif}
if (ilm) then
Output.Lines.Add(' ' + Format(TextByKey('render-status-log-memorylimit'), [lim]))
@ -873,28 +890,33 @@ begin
cp.AdjustScale(ImageWidth, ImageHeight);
cp.Transparency := (PNGTransparency <> 0) and (UpperCase(ExtractFileExt(FileName)) = '.PNG');
renderPath := ExtractFilePath(Filename);
if chkSave.checked then
MainForm.SaveXMLFlame(cp, ExtractFileName(FileName), renderPath + rendersAV);
oldProg:=0;
oldElapsed:=0;
edt:=0;
ApproxSamples := Round(sample_density * sqr(power(2, cp.zoom)) * int64(ImageHeight) * int64(ImageWidth) / sqr(oversample) );
if chkSave.checked then begin // AV: added check for duplicates
t := ExtractFileName(FileName);
if XMLEntryExists(t, renderPath + rendersAV) then
t := t + FormatDateTime(' (MM-dd-yyyy hh-mm-ss)', Now);
MainForm.SaveXMLFlame(cp, t, renderPath + rendersAV);
end;
oldProg := 0;
oldElapsed := 0;
edt := 0;
ApproxSamples := Round(sample_density * sqr(power(2, cp.zoom)) *
int64(ImageHeight) * int64(ImageWidth) / sqr(oversample) );
try
Renderer := TRenderThread.Create;
assert(Renderer <> nil);
// Renderer.BitsPerSample := BitsPerSample;
if (ilm) then
Renderer.MaxMem := lim; //StrToInt(cbMaxMemory.text);
Renderer.ExportBuffer := chkBinary.Checked;
//Renderer.ExportBuffer := chkBinary.Checked;
Renderer.OnProgress := OnProgress;
Renderer.TargetHandle := self.Handle;
Renderer.SetCP(cp);
if chkEmbedFlame.checked then
Renderer.EmbedText(Trim(MainForm.RetrieveXML(cp))); // AV
Renderer.EmbedText(Trim(FlameToXML(cp))); // AV
{
if chkThreadPriority.Checked then
Renderer.SetPriority(tpLower)
@ -909,7 +931,7 @@ begin
except
Output.Lines.Add(TimeToStr(Now) + ' : ' + TextByKey('render-status-rendererror-log'));
Application.MessageBox(PChar(TextByKey('render-status-rendererror-message')), 'Apophysis', 48);
Application.MessageBox(PChar(TextByKey('render-status-rendererror-message')), ApophysisSVN, 48);
end;
end;
end;
@ -951,16 +973,24 @@ begin
txtOversample.Text := IntToStr(renderOversample);
Filter_Radius := max(renderFilterRadius, 0.1); // AV: fixed!
txtFilterRadius.Text := FloatToStr(RoundTo(Filter_Radius, -3)); // AV
cbWidth.Text := IntToStr(cp.Width);
cbHeight.Text := IntToStr(cp.Height);
ImageWidth := StrToInt(cbWidth.Text);
ImageHeight := StrToInt(cbHeight.Text);
// AV: fixed "Floating point division by zero" bug
// AV: fixed 'Floating point division by zero' bug
sample_density := max(renderDensity, 10);
txtDensity.Text := FloatToStr(sample_density);
// BitsPerSample := renderBitsPerSample;
ShowMemoryStatus;
// AV: fixed '"" is not a valid integer' bug
if bRenderAll then begin
ImageWidth := max(renderWidth, 100); // AV
ImageHeight := max(renderHeight, 100); // AV
end
else begin
ImageWidth := cp.Width; // AV
ImageHeight := cp.Height; // AV
end;
Ratio := ImageWidth / ImageHeight;
cbWidth.Text := IntToStr(ImageWidth); // AV
cbHeight.Text := IntToStr(ImageHeight); // AV
ShowMemoryStatus;
chkSaveIncompleteRenders.Checked := SaveIncompleteRenders;
chkPlaySound.Checked := PlaySoundOnRenderComplete; // AV
end;
@ -1041,7 +1071,8 @@ begin
end;
if ConfirmStopRender then begin
if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')), 'Apophysis', 36) = ID_NO then exit;
if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')),
ApophysisSVN, 36) = ID_NO then exit;
end;
bRenderAll := false;
@ -1056,6 +1087,7 @@ begin
ProgressTaskBar.ProgressValue := 0; // AV
ProgressTaskBar.ProgressState := TTaskBarProgressState.None; // AV
end else
Close;
end;
@ -1099,10 +1131,13 @@ begin
renderHeight := ImageHeight;
renderDensity := Sample_density;
renderOversample := Oversample;
// renderBitsPerSample := BitsPerSample;
EmbedFlame := chkEmbedFlame.Checked; // AV
SaveInFlame := chkSave.Checked; // AV
ProgressTaskBar.ProgressState := TTaskBarProgressState.None; // AV
if not Assigned(Renderer) then SetLength(FlameNames, 0); // AV: free memory
{ Write position to registry }
Registry := TRegistry.Create;
try
@ -1121,13 +1156,13 @@ procedure TRenderForm.btnPauseClick(Sender: TObject);
begin
if Assigned(Renderer) then
if Renderer.Suspended = false then begin
renderer.Suspend;
Renderer.Suspend;
btnPause.caption := TextByKey('common-resume');
btnSnapshot.Visible := true; // AV
// AV: displaying progress in yellow
ProgressTaskBar.ProgressState := TTaskBarProgressState.Paused;
end else begin
renderer.Resume;
Renderer.Resume;
btnPause.caption := TextByKey('common-pause');
btnSnapshot.Visible := false; // AV
// AV: restore the taskbar progress
@ -1139,8 +1174,8 @@ procedure TRenderForm.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
begin
if Assigned(Renderer) then
if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')), 'Apophysis', 36) = ID_NO then
CanClose := False
if Application.MessageBox(PChar(TextByKey('render-status-confirmstop')),
ApophysisSVN, 36) = ID_NO then CanClose := False
else
begin
if Assigned(Renderer) then
@ -1187,14 +1222,13 @@ begin
else
WriteLn(IFile, 'false');
WriteLn(IFile, IntToStr(cbMaxMemory.ItemIndex));
WriteLn(IFile, cbMaxMemory.Text);
WriteLn(IFile, '}');
WriteLn(IFile, '');
CloseFile(IFile);
except on EInOutError do
begin
Application.MessageBox(PChar(TextByKey('render-prestatus-saveerror-preset')),
PChar('Apophysis'), 16);
ApophysisSVN, 16);
Exit;
end;
end;
@ -1216,7 +1250,8 @@ begin
Renderer.DoSnapshot; // AV: to save mid-render images
Renderer.SaveImage(FileName);
if ShowRenderImage then // AV
// AV: show saved image if needed
if ShowRenderImage or (Sender = ProgressTaskbar.TaskBarButtons[0]) then
if FileExists(FileName) then
ShellExecute(Application.handle, PChar('open'),
PChar(ExtractFileName(FileName)), nil, PChar(renderPath),
@ -1236,8 +1271,7 @@ end;
procedure TRenderForm.btnBrowseClick(Sender: TObject);
var
fn: string;
ext: string;
fn, ext: string;
begin
SaveDialog.Filename := Filename;
case renderFileFormat of
@ -1245,28 +1279,19 @@ begin
2: SaveDialog.DefaultExt := 'png';
3: SaveDialog.DefaultExt := 'jpg';
end;
SaveDialog.filterIndex := renderFileFormat;
SaveDialog.Filter := Format('%s|*.bmp;*.dib;*.jpg;*.jpeg|%s|*.bmp;*.dib|%s|*.jpg;*.jpeg|%s|*.png|%s|*.*',
[TextByKey('common-filter-allimages'), TextByKey('common-filter-bitmap'),
TextByKey('common-filter-jpeg'), TextByKey('common-filter-png'),
TextByKey('common-filter-allfiles')]);
if OpenSaveFileDialog(RenderForm, SaveDialog.DefaultExt, SaveDialog.Filter, SaveDialog.InitialDir, TextByKey('common-browse'), fn, false, true, false, false) then
//if SaveDialog.Execute then
SaveDialog.FilterIndex := renderFileFormat;
if SaveDialog.Execute then
begin
SaveDialog.FileName := fn;
fn := SaveDialog.FileName;
ext := LowerCase(ExtractFileExt(fn));
if (ext = '.bmp') then renderFileFormat := 1;
if (ext = '.png') then renderFileFormat := 2;
if ((ext = '.jpg') or (ext = '.jpeg')) then renderFileFormat := 3;
{case SaveDialog.FilterIndex of
1: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.bmp');
2: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.png');
3: txtFilename.Text := ChangeFileExt(SaveDialog.Filename, '.jpg');
end; }
if (ext = '.jpg') or (ext = '.jpeg')then
renderFileFormat := 3
else if (ext = '.png') then
renderFileFormat := 2
else // if (ext = '.bmp') or (ext = '.dib') then
renderFileFormat := 1;
txtFileName.Text := ChangeFileExt(fn, ext);
//renderFileFormat := SaveDialog.FilterIndex;
renderPath := ExtractFilePath(SaveDialog.Filename);
renderPath := ExtractFilePath(fn);
end;
end;
@ -1312,7 +1337,7 @@ end;
procedure TRenderForm.cmbPresetChange(Sender: TObject);
var
chk: byte; //boolean; // AV
chk: shortint; // AV
i, j: integer;
FStrings: TStringList;
Title, Filename: string;
@ -1329,15 +1354,12 @@ begin
for i := 0 to FStrings.Count - 1 do
if Pos(LowerCase(Title) + ' {', Lowercase(FStrings[i])) <> 0 then
begin
//chk := chkMaintain.checked;
//chkMaintain.Checked := False;
chk := cbAspectRatio.ItemIndex; // AV
cbAspectRatio.ItemIndex := 0;
j := i + 1;
cbWidth.Text := FStrings[j];
inc(j);
cbHeight.text := FStrings[j];
//chkMaintain.Checked := chk;
cbAspectRatio.ItemIndex := chk;
inc(j);
txtDensity.text := FStrings[j];
@ -1347,13 +1369,9 @@ begin
txtOversample.text := FStrings[j];
inc(j);
txtFileName.Text := ChangeFileExt(txtFileName.Text, FStrings[j]);
inc(j);
//if Fstrings[j] = 'true' then (not IsLimitingMemory) else chkLimitMem.checked := false;
inc(j);
cbMaxMemory.ItemIndex := StrToInt(Fstrings[j]);
//cbMaxMemory.enabled := chkLimitMem.checked;
inc(j);
cbMaxMemory.Text := Fstrings[j];
inc(j, 2);
// AV: avoiding conflicts with 32- and 64-bit versions
cbMaxMemory.ItemIndex := min(StrToInt(FStrings[j]), cbMaxMemory.Items.Count-1);
break;
end;
finally
@ -1366,13 +1384,6 @@ begin
ShowMemoryStatus;
end;
{
procedure TRenderForm.chkMaintainClick(Sender: TObject);
begin
Ratio := ImageWidth / ImageHeight;
end;
}
procedure TRenderForm.DoPostProcess;
begin
frmPostProcess.cp := cp;
@ -1382,6 +1393,40 @@ begin
frmPostProcess.Show;
end;
function GetWinVersion: TWin32Version;
{ Returns current version of a host Win32 platform }
var
wMinor, wMajor: integer;
begin
Result := wvUnknown;
wMinor := Win32MinorVersion; // AV
wMajor := Win32MajorVersion; // AV
if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then
if (wMajor > 4) or ((wMajor = 4) and (wMinor > 0)) then
Result := wvWin98
else
Result := wvWin95
else
if wMajor <= 4 then
Result := wvWinNT
else if wMajor = 5 then
begin // AV
if wMinor = 0 then
Result := wvWin2000
else if wMinor >= 1 then
Result := wvWinXP
end
else if wMajor = 6 then
begin // AV
if wMinor = 0 then
Result := wvWinVista
else if wMinor >= 1 then
Result := wvWin7
end
else if wMajor >= 7 then
Result := wvWinFutureFromOuterSpace;
end;
function TRenderForm.WindowsExit(RebootParam: Longword = EWX_POWEROFF or EWX_FORCE): Boolean;
var
TTokenHd: THandle;
@ -1390,15 +1435,17 @@ var
rTTokenPvg: TTokenPrivileges;
pcbtpPreviousRequired: DWORD;
tpResult: Boolean;
WinVersion: TWin32Version; // AV
const
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
begin
if ((GetWinVersion = wvWinNT) or
(GetWinVersion = wvWin2000) or
(GetWinVersion = wvWinXP) or
(GetWinVersion = wvWinVista) or
(GetWinVersion = wvWin7) or
(GetWinVersion = wvWinFutureFromOuterSpace)) then
WinVersion := GetWinVersion; // AV: we don't need to calc it many times
if ((WinVersion = wvWinNT) or
(WinVersion = wvWin2000) or
(WinVersion = wvWinXP) or
(WinVersion = wvWinVista) or
(WinVersion = wvWin7) or
(WinVersion = wvWinFutureFromOuterSpace)) then
begin
tpResult := OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
@ -1436,7 +1483,7 @@ end;
procedure TRenderForm.btnGoToClick(Sender: TObject);
var
path:string;
path: string;
begin
path := ExtractFilePath(txtFilename.Text);
if (path <> '') then WinShellExecute('open', path);

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,7 +27,7 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Menus, ExtCtrls, ControlPoint, RenderThread, Translation;
Menus, ExtCtrls, ControlPoint, RenderThread;
type
TFullscreenForm = class(TForm)
@ -50,8 +50,7 @@ type
private
Remainder, StartTime, t: double;
imgLeft, imgTop,
imgWidth, imgHeight: integer;
imgLeft, imgTop, imgWidth, imgHeight: integer;
Closing: boolean;
Renderer: TRenderThread;
@ -68,8 +67,6 @@ type
public
Calculate : boolean;
cp: TControlPoint;
Zoom: double;
center: array[0..1] of double;
ActiveForm: TForm;
end;
@ -80,8 +77,7 @@ var
implementation
uses
Main, Math, Global,
Tracer;
Main, Math, Global, Tracer, Translation;
{$R *.DFM}
@ -118,9 +114,6 @@ begin
end;
cp.AdjustScale(imgWidth, imgHeight);
// cp.Zoom := MainForm.Zoom;
// cp.center[0] := MainForm.center[0];
// cp.center[1] := MainForm.center[1];
cp.sample_density := defSampleDensity;
StartTime := Now;
t := now;
@ -294,6 +287,12 @@ begin
RenderMore.Caption := TextByKey('fullscreen-popup-rendermore');
RenderStop.Caption := TextByKey('fullscreen-popup-stoprender');
cp := TControlPoint.Create;
// AV: moved following here from MainForm.mnuFullScreenClick
self.Width := Screen.Width;
self.Height := Screen.Height;
self.Top := 0;
self.Left := 0;
end;
procedure TFullscreenForm.FormDestroy(Sender: TObject);

View File

@ -81,16 +81,9 @@ object MainForm: TMainForm
OnKeyDown = FormKeyUpDown
OnKeyPress = FormKeyPress
OnKeyUp = FormKeyUpDown
OnResize = FormResize
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object Image1: TImage
Left = 48
Top = 104
Width = 105
Height = 105
end
object Splitter: TSplitter
Left = 161
Top = 22
@ -139,16 +132,6 @@ object MainForm: TMainForm
Ctl3D = True
ParentCtl3D = False
TabOrder = 1
object Shape1: TShape
Left = 1
Top = 1
Width = 159
Height = 649
Align = alClient
Brush.Color = clWindow
Pen.Color = clWindow
ExplicitHeight = 748
end
object ListView1: TListView
Left = 1
Top = 1
@ -175,6 +158,7 @@ object MainForm: TMainForm
OnColumnClick = ListViewColumnClick
OnDblClick = ListViewDblClick
OnEdited = ListViewEdited
OnSelectItem = ListViewSelectItem
end
end
object cbMain: TCoolBar
@ -212,6 +196,7 @@ object MainForm: TMainForm
ParentShowHint = False
ShowHint = True
TabOrder = 0
OnResize = ToolBarResize
object btNew: TToolButton
Left = 0
Top = 0
@ -425,9 +410,24 @@ object MainForm: TMainForm
ImageIndex = 69
OnClick = tbCurvesClick
end
object tbMutate: TToolButton
object tbImageSize: TToolButton
Left = 462
Top = 0
Hint = 'Image size | Change the image size'
Caption = 'tbImageSize'
ImageIndex = 14
OnClick = mnuImageSizeClick
end
object tbAnimate: TToolButton
Left = 485
Top = 0
Caption = 'Animator'
ImageIndex = 76
MenuItem = mnuAnimator
end
object tbMutate: TToolButton
Left = 508
Top = 0
Hint =
'Mutation | Show randomly generated modifications of the current ' +
'flame'
@ -435,23 +435,15 @@ object MainForm: TMainForm
ImageIndex = 17
OnClick = mnuMutateClick
end
object tbImageSize: TToolButton
Left = 485
Top = 0
Hint = 'Image size | Change the image size'
Caption = 'tbImageSize'
ImageIndex = 14
OnClick = mnuImageSizeClick
end
object tbMessages: TToolButton
Left = 508
Left = 531
Top = 0
Hint = 'Messages | Show error messages'
ImageIndex = 63
OnClick = tbMessagesClick
end
object tbOptions: TToolButton
Left = 531
Left = 554
Top = 0
Hint = 'Options | Change Apophysis default settings'
Caption = 'tbOptions'
@ -459,7 +451,7 @@ object MainForm: TMainForm
OnClick = mnuOptionsClick
end
object ToolButton15: TToolButton
Left = 554
Left = 577
Top = 0
Width = 8
Caption = 'ToolButton15'
@ -467,7 +459,7 @@ object MainForm: TMainForm
Style = tbsSeparator
end
object tbShowAlpha: TToolButton
Left = 562
Left = 585
Top = 0
Hint = 'Show transparency | Show the flame on a transparent background'
Caption = 'Show Alpha'
@ -476,7 +468,7 @@ object MainForm: TMainForm
OnClick = tbShowAlphaClick
end
object tbGuides: TToolButton
Left = 585
Left = 608
Top = 0
Hint = 'Show guidelines | Show flame thirds, center and golden ratio'
Caption = 'Show guides'
@ -486,7 +478,7 @@ object MainForm: TMainForm
OnClick = tbGuidesClick
end
object ToolButton16: TToolButton
Left = 608
Left = 631
Top = 0
Width = 8
Caption = 'ToolButton16'
@ -494,7 +486,7 @@ object MainForm: TMainForm
Style = tbsSeparator
end
object tbEditScript: TToolButton
Left = 616
Left = 639
Top = 0
Hint = 'Edit script | Edit the script code'
Caption = 'tbEditScript'
@ -502,7 +494,7 @@ object MainForm: TMainForm
OnClick = mnuEditScriptClick
end
object btnRunScript: TToolButton
Left = 639
Left = 662
Top = 0
Hint = 'Run script | Execute the current script'
Caption = 'btnRunScript'
@ -510,7 +502,7 @@ object MainForm: TMainForm
OnClick = mnuRunClick
end
object btnStopScript: TToolButton
Left = 662
Left = 685
Top = 0
Hint =
'Stop script | To stop an animation script, you can press any key' +
@ -520,7 +512,7 @@ object MainForm: TMainForm
OnClick = mnuStopClick
end
object ToolButton18: TToolButton
Left = 685
Left = 708
Top = 0
Width = 8
Caption = 'ToolButton18'
@ -528,7 +520,7 @@ object MainForm: TMainForm
Style = tbsSeparator
end
object tbDrag: TToolButton
Left = 693
Left = 716
Top = 0
Hint = 'Translate the image | Translate the fractal image using mouse'
Caption = 'tbDrag'
@ -539,7 +531,7 @@ object MainForm: TMainForm
OnClick = tbDragClick
end
object tbRotate: TToolButton
Left = 716
Left = 739
Top = 0
Hint = 'Rotate the camera | Rotate the fractal image using mouse'
Caption = 'tbRotate'
@ -549,7 +541,7 @@ object MainForm: TMainForm
OnClick = tbRotateClick
end
object tbZoomIn: TToolButton
Left = 739
Left = 762
Top = 0
Hint = 'Zoom in | Scale up the fractal image using mouse'
Caption = 'tbZoomIn'
@ -559,7 +551,7 @@ object MainForm: TMainForm
OnClick = tbzoomwindowClick
end
object tbZoomOut: TToolButton
Left = 762
Left = 785
Top = 0
Hint = 'Zoom out | Scale down the fractal image using mouse'
Caption = 'tbZoomOut'
@ -569,7 +561,7 @@ object MainForm: TMainForm
OnClick = tbzoomoutwindowClick
end
object ToolButton23: TToolButton
Left = 785
Left = 808
Top = 0
Width = 8
Caption = 'ToolButton23'
@ -630,131 +622,131 @@ object MainForm: TMainForm
Left = 104
Top = 280
Bitmap = {
494C01014C005000040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
494C01014D005000040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
0000000000003600000028000000400000004001000001002000000000000040
0100000000000000000000000000000000000000000000000000000000000000
000018435A002B6289004C8ABE0070A9CC00E3EDF50000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000004E4E4E002D2D2D00505050000000
00002E67850094C7F90091C9F9004185C900276BAE002D3B4700050505002525
2500000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000038383800B0B0B000353535005757
57004389AA00E0F2FF00549AD8001A7ABE004998C5003177B0009EACB8001515
1500000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000003A3A3A0062626200383838006FDF
9D0055B2A0007AB6D50090B7D10055C9E4005BDFF50078D0ED004491D1000F1B
2500000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000063636300ACACAC00575757004FCB
5C0057D77A0035B8830073B8D300C2F6FD0063DFF7005DE2F80079D3F0004392
D500E6F1FA000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000005C5C5C006D6D6D005F5F5F004FC4
45004BBA2C00D8BD6000B1A87F0077CBE700C7F7FD005EDCF5005AE1F7007BD4
F1004C9ADE00D6E8F70000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000006565650089898900656565007FBF
3600DDC56900FFC27000FFBF670086C3BA0079D3EE00C7F7FD005FDCF5005BE2
F7007AD6F20051A2E200DCEAF600000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000006E6E6E00A4A4A4006C6C6C00F8C6
6E00FFC87700FFC57200FFC46C0098D8CF0078D7E9007BD3EC00C4F6FD006CDD
F6006DCAED0063A3D70069A2D500E5EFF7000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000006969690071717100686868005757
570057575700575757005757570057575700575757002C5D6D007DD2EA00B2E3
F9008BC0E700AED3F600C4E0FC006BA2D4000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000077777700AAAAAA007474740072E2
9E007CE3A40078E3A00063E095005AE1950055E29300565656006CA1B00077BE
E700B4D2F000E5F3FF00ACD2EF005996CC000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000007777770097979700777777004FCB
5C0057D77A0042D16A0070C75E00B6B85000CBAE3F005B5B5B007C7C7C00426C
7A0058A5D80085B1DB00469DD000B1D8EE000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000077777700858585007A7A7A004FC4
45004BBA2C00D8BD6000FFBA6200FFB96500DBBB7D005E5E5E00656565004B4B
4B00000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000083838300AFAFAF007C7C7C007FBF
3600DDC56900FFC27000FFBF6700AECBAC0068E0F90060606000ACACAC005C5C
5C00000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000006C6C6C007474740068686800E6BC
7100EDBE7900ECBB7300ECB96D0084CDCF0084D8EB004B4B4B00686868003D3D
3D00000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000073737300A6A6A600696969005757
570057575700575757005757570057575700575757004D4D4D009A9A9A006262
6200000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000008989890076767600808080000000
000000000000000000000000000000000000000000006E6E6E00515151006666
6600000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
@ -3194,11 +3186,11 @@ object MainForm: TMainForm
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000424D3E000000000000003E000000
2800000040000000400100000100010000000000000A00000000000000000000
000000000000000000000000FFFFFF0000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000FFFFFFFFFFFFFFFFFF9FF80F81FFFFFF
000000000000000000000000FFFFFF00F07F000000000000100F000000000000
000F000000000000000F00000000000000070000000000000003000000000000
0001000000000000000000000000000000000000000000000000000000000000
0000000000000000000F000000000000000F000000000000000F000000000000
000F0000000000001F8F000000000000FFFFFFFFFFFFFFFFFF9FF80F81FFFFFF
F187E0078007C7FFE083C003C103C2FFC213C001C411F207C7138001C801F187
F111800188C8F10FC00080018308F903800C80019019F89387018001CC23F8FF
800380018027F07FC0818003240FFCFFC683C003203FFC1FFC17E00707FFFE1F
@ -3283,7 +3275,6 @@ object MainForm: TMainForm
Top = 168
object MainFile: TMenuItem
Caption = '&File'
OnClick = MainMenuClick
object New1: TMenuItem
Caption = 'New...'
ImageIndex = 65
@ -3374,7 +3365,6 @@ object MainForm: TMainForm
end
object MainEdit: TMenuItem
Caption = '&Edit'
OnClick = MainMenuClick
object mnuUndo: TMenuItem
Caption = '&Undo'
Enabled = False
@ -3461,6 +3451,12 @@ object MainForm: TMainForm
ShortCut = 119
OnClick = tbCurvesClick
end
object mnuAnimator: TMenuItem
Caption = 'Animator'
ImageIndex = 76
ShortCut = 122
OnClick = mnuAnimatorClick
end
object N5: TMenuItem
Caption = '-'
end
@ -3477,7 +3473,6 @@ object MainForm: TMainForm
end
object MainFlame: TMenuItem
Caption = 'Flame'
OnClick = MainMenuClick
object mnuResetLocation: TMenuItem
Caption = 'Reset Location'
ImageIndex = 12
@ -3629,7 +3624,6 @@ object MainForm: TMainForm
end
object AddTile: TMenuItem
Caption = 'Add equiaffine tile...'
OnClick = AddTileClick
object Rhombic1: TMenuItem
Tag = 1
Caption = 'Rhombus'
@ -3863,9 +3857,7 @@ object MainForm: TMainForm
end
end
object OpenDialog: TOpenDialog
Filter =
'Apophysis Parameter Files (*.apo)|*.apo|Apophysis 1.0 Parameters' +
' (*fla)|*.fla|IFS Files (*.ifs)|*.ifs'
Filter = 'Apophysis Parameter Files (*.flame)|*.flame'
Options = [ofHideReadOnly, ofPathMustExist, ofFileMustExist, ofEnableSizing]
Left = 24
Top = 456

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@ object MutateForm: TMutateForm
BorderStyle = bsSingle
Caption = 'Mutation'
ClientHeight = 398
ClientWidth = 422
ClientWidth = 414
Color = clBtnFace
Constraints.MinHeight = 400
Constraints.MinWidth = 400
@ -21,51 +21,28 @@ object MutateForm: TMutateForm
OnDestroy = FormDestroy
OnShow = FormShow
DesignSize = (
422
414
398)
PixelsPerInch = 96
TextHeight = 13
object GroupBox1: TGroupBox
Left = 8
object gbDirections: TGroupBox
Left = 24
Top = 8
Width = 409
Width = 360
Height = 273
Anchors = [akLeft, akTop, akRight, akBottom]
Caption = 'Directions'
TabOrder = 0
DesignSize = (
409
360
273)
object Panel10: TPanel
object pnlDirections: TPanel
Left = 12
Top = 20
Width = 384
Width = 335
Height = 238
Anchors = [akLeft, akTop, akRight, akBottom]
BevelOuter = bvNone
TabOrder = 0
object Panel6: TPanel
Left = 112
Top = 168
Width = 108
Height = 80
BevelOuter = bvLowered
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
TabOrder = 0
object Image6: TImage
Tag = 6
Left = 1
Top = 1
Width = 106
Height = 78
Align = alClient
PopupMenu = QualityPopup
Stretch = True
OnClick = MutantClick
end
end
object Panel7: TPanel
Left = 0
Top = 168
@ -75,18 +52,7 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
TabOrder = 1
object Image7: TImage
Tag = 7
Left = 1
Top = 1
Width = 106
Height = 78
Align = alClient
PopupMenu = QualityPopup
Stretch = True
OnClick = MutantClick
end
TabOrder = 0
end
object Panel4: TPanel
Left = 224
@ -97,18 +63,7 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
TabOrder = 2
object Image4: TImage
Tag = 4
Left = 1
Top = 1
Width = 106
Height = 78
Align = alClient
PopupMenu = QualityPopup
Stretch = True
OnClick = MutantClick
end
TabOrder = 1
end
object Panel0: TPanel
Left = 112
@ -120,7 +75,7 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
TabOrder = 3
TabOrder = 2
object Image0: TImage
Left = 1
Top = 1
@ -130,6 +85,8 @@ object MutateForm: TMutateForm
PopupMenu = QualityPopup
Stretch = True
OnClick = Image0Click
ExplicitLeft = 2
ExplicitTop = 0
end
end
object Panel8: TPanel
@ -141,18 +98,7 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
TabOrder = 4
object Image8: TImage
Tag = 8
Left = 1
Top = 1
Width = 106
Height = 78
Align = alClient
PopupMenu = QualityPopup
Stretch = True
OnClick = MutantClick
end
TabOrder = 3
end
object Panel3: TPanel
Left = 224
@ -163,18 +109,7 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
TabOrder = 5
object Image3: TImage
Tag = 3
Left = 1
Top = 1
Width = 106
Height = 78
Align = alClient
PopupMenu = QualityPopup
Stretch = True
OnClick = MutantClick
end
TabOrder = 4
end
object Panel2: TPanel
Left = 112
@ -185,18 +120,7 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
TabOrder = 6
object Image2: TImage
Tag = 2
Left = 1
Top = 1
Width = 106
Height = 78
Align = alClient
PopupMenu = QualityPopup
Stretch = True
OnClick = MutantClick
end
TabOrder = 5
end
object Panel1: TPanel
Left = 0
@ -207,18 +131,7 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
TabOrder = 7
object Image1: TImage
Tag = 1
Left = 1
Top = 1
Width = 106
Height = 78
Align = alClient
PopupMenu = QualityPopup
Stretch = True
OnClick = MutantClick
end
TabOrder = 6
end
object Panel5: TPanel
Left = 224
@ -229,37 +142,36 @@ object MutateForm: TMutateForm
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
TabOrder = 8
object Image5: TImage
Tag = 5
Left = 1
Top = 1
Width = 106
Height = 78
Align = alClient
PopupMenu = QualityPopup
Stretch = True
OnClick = MutantClick
TabOrder = 7
end
object Panel6: TPanel
Left = 112
Top = 168
Width = 108
Height = 80
BevelOuter = bvLowered
Caption = 'PrevPnl3'
Color = clBlack
ShowCaption = False
TabOrder = 8
end
end
end
object GroupBox2: TGroupBox
Left = 8
Top = 288
Width = 409
Width = 393
Height = 105
Anchors = [akLeft, akRight, akBottom]
Anchors = [akLeft, akBottom]
TabOrder = 1
DesignSize = (
409
393
105)
object scrollTime: TScrollBar
Left = 120
Left = 114
Top = 20
Width = 202
Height = 20
Anchors = [akLeft, akTop, akRight]
LargeChange = 5
Max = 50
Min = 1
@ -269,23 +181,23 @@ object MutateForm: TMutateForm
OnChange = scrollTimeChange
end
object cmbTrend: TComboBox
Left = 119
Left = 114
Top = 48
Width = 282
Width = 262
Height = 21
Style = csDropDownList
Anchors = [akLeft, akTop, akRight]
DropDownCount = 16
Sorted = True
TabOrder = 1
OnChange = cmbTrendChange
Items.Strings = (
'Random'
'Linear')
'Linear'
'Random')
end
object chkSameNum: TCheckBox
Left = 12
Top = 78
Width = 389
Width = 373
Height = 17
Anchors = [akLeft, akTop, akRight]
Caption = 'Same no. of transforms'
@ -305,11 +217,10 @@ object MutateForm: TMutateForm
TabOrder = 3
end
object txtTime: TEdit
Left = 328
Left = 318
Top = 20
Width = 73
Width = 60
Height = 21
Anchors = [akTop, akRight]
ReadOnly = True
TabOrder = 4
Text = '0.25'
@ -331,8 +242,8 @@ object MutateForm: TMutateForm
Enabled = False
Interval = 100
OnTimer = TimerTimer
Left = 168
Top = 80
Left = 184
Top = 136
end
object QualityPopup: TPopupMenu
Images = MainForm.Buttons

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,11 +28,11 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, ControlPoint, ComCtrls, Menus, Buttons, Cmap,
RenderingInterface, Translation, Curves;
RenderingInterface;
type
TMutateForm = class(TForm)
GroupBox1: TGroupBox;
gbDirections: TGroupBox;
Timer: TTimer;
GroupBox2: TGroupBox;
scrollTime: TScrollBar;
@ -48,29 +48,20 @@ type
N1: TMenuItem;
mnuMaintainSym: TMenuItem;
N2: TMenuItem;
Panel10: TPanel;
Panel6: TPanel;
Image6: TImage;
pnlDirections: TPanel;
Panel7: TPanel;
Image7: TImage;
Panel4: TPanel;
Image4: TImage;
Panel0: TPanel;
Image0: TImage;
Panel8: TPanel;
Image8: TImage;
Panel3: TPanel;
Image3: TImage;
Panel2: TPanel;
Image2: TImage;
Panel1: TPanel;
Image1: TImage;
Panel5: TPanel;
Image5: TImage;
pnlSpeed: TPanel;
txtTime: TEdit;
pnlTrend: TPanel;
//procedure Panel10Resize(Sender: TObject);
Panel6: TPanel;
procedure FormShow(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
@ -80,7 +71,6 @@ type
procedure TimerTimer(Sender: TObject);
procedure scrollTimeChange(Sender: TObject);
procedure cmbTrendChange(Sender: TObject);
procedure btnCancelClick(Sender: TObject);
procedure mnuHighQualityClick(Sender: TObject);
procedure mnuLowQualityClick(Sender: TObject);
procedure mnuMediumQualityClick(Sender: TObject);
@ -91,11 +81,11 @@ type
procedure mnuMaintainSymClick(Sender: TObject);
private
name: string;
bm: TBitmap;
PreviewDensity: double;
Updating: boolean;
cps: array[0..8] of TControlPoint;
Mutants: array[0..8] of TControlPoint;
MImages: array[1..8] of TImage; // AV
Render: TRenderer;
Time: double;
bstop: boolean;
@ -106,6 +96,8 @@ type
procedure ShowMain;
procedure ShowMutants;
procedure Interpolate;
procedure RandomCP(var cp: TControlPoint; const minT, maxT: integer); // AV: removed from ControlPoint
procedure SetVariation(var cp: TControlPoint); // AV: wrote a local method
public
Zoom: Double;
Center: array[0..1] of double;
@ -120,7 +112,7 @@ var
implementation
uses
Main, Global, Registry, Editor, Adjust, XFormMan;
Main, Global, Registry, Editor, XFormMan, Adjust, Translation;
{$R *.DFM}
@ -135,13 +127,12 @@ begin
MainCp.AdjustScale(width, height); // AV: restore normal size
if mnuResetLocation.checked then
begin
//MainForm.Mainzoom := cps[0].zoom;
MainForm.Center[0] := cps[0].Center[0];
MainForm.Center[1] := cps[0].Center[1];
end;
MainForm.RedrawTimer.enabled := true;
if EditForm.Visible then EditForm.UpdateDisplay;
// if AdjustForm.Visible then AdjustForm.UpdateDisplay;
if AdjustForm.Visible then AdjustForm.UpdateDisplay;
end;
procedure TMutateForm.UpdateDisplay;
@ -167,6 +158,26 @@ begin
ShowMutants;
end;
procedure TMutateForm.SetVariation(var cp: TControlPoint);
var
i, k, n: integer;
begin
if cmbTrend.ItemIndex = NRVAR then // AV: set random variations from selected
repeat
n := random(NrVar);
until Variations[n]
else // AV: sorted list is used from now
n := GetVariationIndex(cmbTrend.Items[cmbTrend.ItemIndex]);
for i := 0 to cp.NumXforms-1 do
begin
for k := 0 to NrVar-1 do // AV: simplified the calculations
cp.xform[i].SetVariation(k, 0);
cp.xform[i].SetVariation(n, 1);
end;
end;
procedure TMutateForm.ShowMain;
begin
cps[0].Width := Image0.Width;
@ -194,20 +205,21 @@ begin
Render.SetCP(cps[0]);
Render.Render;
BM.Assign(Render.GetImage);
Image0.Picture.Graphic := bm;
Image0.Picture.Graphic := Render.GetImage;
end;
procedure TMutateForm.ShowMutants;
var
i: integer;
i: byte;
//t: cardinal;
begin
if Visible = false then exit;
Updating := true;
//t := GetTickCount;
for i := 1 to 8 do
begin
mutants[i].Width := Image1.Width;
mutants[i].Height := Image1.Height;
mutants[i].Width := Image0.Width;
mutants[i].Height := Image0.Height;
mutants[i].spatial_filter_radius := defFilterRadius;
mutants[i].spatial_oversample := defOversample;
mutants[i].sample_density := PreviewDensity;
@ -230,51 +242,22 @@ begin
Render.SetCP(mutants[i]);
Render.Render;
BM.Assign(Render.GetImage);
case i of
1: begin
Image1.Picture.Graphic := bm;
Image1.Refresh;
end;
2: begin
Image2.Picture.Graphic := bm;
Image2.Refresh;
end;
3: begin
Image3.Picture.Graphic := bm;
Image3.Refresh;
end;
4: begin
Image4.Picture.Graphic := bm;
Image4.Refresh;
end;
5: begin
Image5.Picture.Graphic := bm;
Image5.Refresh;
end;
6: begin
Image6.Picture.Graphic := bm;
Image6.Refresh;
end;
7: begin
Image7.Picture.Graphic := bm;
Image7.Refresh;
end;
8: begin
Image8.Picture.Graphic := bm;
Image8.Refresh;
end;
end;
// AV: replaced separate TImages by an array
MImages[i].Picture.Graphic := Render.GetImage;
MImages[i].Refresh;
Updating := false;
end;
//ShowMessage((GetTickCount - t).ToString);
end;
procedure TMutateForm.Interpolate;
var i, j, k: Integer;
var i, j: Integer;
begin
if MainCp = nil then Exit;
//cps[0].Time := 0;
for i := 1 to 8 do
begin
if bstop then exit;
@ -283,45 +266,53 @@ begin
(* -X- something is not right here...
Mutants[i] may be destroyed already
Investigate? *)
Mutants[i].clear;
// AV: it's OK... Mutants are just placeholders for a new flame
Mutants[i].Clear;
Mutants[i].InterpolateX(cps[0], cps[i], Time / 100);
Mutants[i].cmapindex := cps[0].cmapindex;
Mutants[i].cmap := cps[0].cmap;
Mutants[i].background := MainCp.background;
if mnuMaintainSym.Checked then // maintain symmetry
for j := 0 to transforms - 1 do
if cps[0].xform[j].Symmetry = 1 then
mutants[i].xform[j].Assign(cps[0].xform[j]);
end;
end;
procedure TMutateForm.RandomCP(var cp: TControlPoint; const minT, maxT: integer); // AV
var
nrXforms, i: integer;
begin
nrXforms := random(MaxT - MinT + 1) + MinT;
for i := 0 to nrXforms - 1 do begin
cp.xform[i].density := 1.0 / nrXforms;
cp.xform[i].color := i / (nrXforms - 1);
cp.xform[i].RandomizeCoefs(cp.xform[i].c);
end;
SetVariation(cp); //AV
end;
procedure TMutateForm.RandomSet;
var i, j, k: Integer;
var i: byte;
begin
RandSeed := seed;
for i := 1 to 8 do
begin
cps[i].clear;
if chkSameNum.checked then
cps[i].RandomCP(transforms, transforms, false)
RandomCP(cps[i], transforms, transforms)
else
cps[i].RandomCP(mutantMinTransforms, mutantMaxTransforms, false);
if cmbTrend.ItemIndex = NRVAR then // AV
cps[i].SetVariation(vRandom)
else
for j := 0 to cps[i].NumXforms-1 do
begin
for k := 0 to NrVar-1 do // AV: simplified the calculations
cps[i].xform[j].SetVariation(k, 0);
cps[i].xform[j].SetVariation(cmbTrend.ItemIndex, 1);
end;
RandomCP(cps[i], mutantMinTransforms, mutantMaxTransforms);
{ // AV: now it's done inside InterpolateX method
if cps[0].HasFinalXForm = false then
begin
cps[i].xform[cps[i].NumXForms].Clear;
cps[i].xform[cps[i].NumXForms].symmetry := 1;
end;
}
end;
Interpolate;
end;
@ -361,7 +352,7 @@ var
i: integer;
begin
self.Caption := TextByKey('mutation-title');
GroupBox1.Caption := TextByKey('mutation-directions');
gbDirections.Caption := TextByKey('mutation-directions');
pnlSpeed.Caption := TextByKey('mutation-speed');
pnlTrend.Caption := TextByKey('mutation-trend');
chkSameNum.Caption := TextByKey('mutation-keepnumberoftransforms');
@ -375,10 +366,9 @@ begin
for i:= 0 to NRVAR -1 do // AV
cmbTrend.Items.Add(varnames(i));
cmbTrend.Sorted := False; // AV: 'random' item must be last
cmbTrend.Items.Add(TextByKey('mutation-randomtrend'));
bm := TBitMap.Create;
case MutatePrevQual of
0: begin
mnuLowQuality.Checked := true;
@ -401,7 +391,17 @@ begin
Mutants[i] := TControlPoint.Create;
end;
Time := 35;
for i := 1 to 8 do // AV: added array for speed
begin
MImages[i] := TImage.Create(self);
MImages[i].Parent := TPanel(self.FindComponent('Panel' + IntToStr(i)));
MImages[i].Align := alClient;
MImages[i].Tag := i;
MImages[i].OnClick := MutantClick;
MImages[i].PopupMenu := QualityPopup;
end;
Time := 25; // 35;
scrollTime.Position := 25;
txtTime.Text := '0.25'; // AV
cmbTrend.ItemIndex := NRVAR; // AV
@ -421,7 +421,6 @@ begin
cps[i].Free;
Mutants[i].Free;
end;
bm.free;
end;
procedure TMutateForm.Image0Click(Sender: TObject);
@ -439,30 +438,32 @@ var
cpt: TControlPoint;
begin
cpt := TControlPoint.Create;
cpt.Copy(cps[0], false, transforms); // AV
bstop := true;
// AV: optimized fast version without checking indices
// AV: optimized faster version without checking indices
i := TImage(Sender).Tag;
cps[0].Time := 0;
cps[i].Time := 1;
cps[0].InterpolateX(cps[0], cps[i], Time / 100);
cpt.InterpolateX(cps[0], cps[i], Time / 100);
if mnuMaintainSym.Checked then // maintain symmetry
begin
for i := 0 to transforms - 1 do
begin
if cpt.xform[i].Symmetry = 1 then
cps[0].xform[i].Assign(cpt.xform[i]);
if cps[0].xform[i].Symmetry = 1 then
cpt.xform[i].Assign(cps[0].xform[i]);
end;
end;
// AV: it's faster to make a copy by reference that use TControlPoint.Copy()
cps[0].Free; // AV
cps[0] := cpt; // AV
bstop := false;
ShowMain;
Interpolate;
ShowMutants;
UpdateFlame;
cpt.free;
end;
procedure TMutateForm.sbTimeChange(Sender: TObject);
@ -494,28 +495,15 @@ end;
procedure TMutateForm.cmbTrendChange(Sender: TObject);
var
i, j, k: integer;
i: byte;
begin
for i := 1 to 8 do
if cmbTrend.ItemIndex = NRVAR then
cps[i].SetVariation(VRandom) // AV
else
for j := 0 to cps[i].NumXforms-1 do
begin // AV
for k := 0 to NrVar-1 do
cps[i].xform[j].SetVariation(k, 0);
cps[i].xform[j].SetVariation(cmbTrend.ItemIndex, 1);
end;
SetVariation(cps[i]); //AV
Interpolate;
ShowMutants;
end;
procedure TMutateForm.btnCancelClick(Sender: TObject);
begin
ModalResult := mrCancel;
end;
procedure TMutateForm.mnuHighQualityClick(Sender: TObject);
begin
mnuHighQuality.Checked := True;
@ -605,30 +593,6 @@ begin
ShowMutants;
end;
(*
procedure TMutateForm.Panel10Resize(Sender: TObject);
const gap:integer = 4 ;
var
w, h : integer;
begin
w := (Panel10.Width - 2*gap) div 3;
h := (Panel10.Height - 2*gap) div 3;
Panel0.Width := w; Panel1.Width := w; Panel2.Width := w;
Panel3.Width := w; Panel4.Width := w; Panel5.Width := w;
Panel6.Width := w; Panel7.Width := w; Panel8.Width := w;
Panel0.Height := h; Panel1.Height := h; Panel2.Height := h;
Panel3.Height := h; Panel4.Height := h; Panel5.Height := h;
Panel6.Height := h; Panel7.Height := h; Panel8.Height := h;
Panel2.Left := w + gap; Panel0.Left := w + gap; Panel6.Left := w + gap;
Panel3.Left := 2*(w + gap); Panel4.Left := 2*(w + gap); Panel5.Left := 2*(w + gap);
Panel8.Top := h + gap; Panel0.Top := h + gap; Panel4.Top := h + gap;
Panel7.Top := 2*(h + gap); Panel6.Top := 2*(h + gap); Panel5.Top := 2*(h + gap);
end;
*)
end.

File diff suppressed because it is too large Load Diff

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
@ -27,8 +27,7 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, ControlPoint, RenderingInterface, Translation, Vcl.Menus,
Vcl.Imaging.PNGimage;
ExtCtrls, ControlPoint, RenderingInterface, Vcl.Menus, Vcl.Imaging.PNGimage;
type
TPreviewForm = class(TForm)
@ -57,7 +56,7 @@ var
implementation
uses Main, Global, ScriptForm;
uses Main, Global, ScriptForm, Translation;
{$R *.DFM}
@ -100,26 +99,27 @@ end;
procedure TPreviewForm.MakeScreenShotClick(Sender: TObject);
var
s: string;
pic: TPNGObject;
s, t: string;
pic: TPNGImage;
begin
if not DirectoryExists(ScreenShotPath) then
begin
CreateDir(AppPath + 'ScreenShots\');
ScreenShotPath := AppPath + 'ScreenShots\';
end;
s := ScreenShotPath + 'Apophysis Animation Preview' + FormatDateTime(' (MM-dd-yyyy hh-mm-ss)', Now) + '.bmp';
t := FormatDateTime(' (MM-dd-yyyy hh-mm-ss)', Now);
s := ScreenShotPath + 'Apophysis Animation Preview' + t + '.bmp';
try
if KeepFrame.Checked then
GetFormScreenShot(s)
else
begin
try
pic := TPNGObject.Create;
pic := TPNGImage.Create;
try
pic.Assign(Image.Picture.Bitmap);
if cp.name = '' then cp.name := RemoveExt(s);
pic.AddtEXt('ApoFlame', AnsiString(Trim(MainForm.RetrieveXML(cp))));
if cp.name = '' then cp.name := RemoveExt(s) + t;
pic.AddtEXt('ApoFlame', AnsiString(Trim(FlameToXML(cp))));
s := ChangeFileExt(s, '.png');
pic.SaveToFile(s);
finally
@ -130,9 +130,9 @@ begin
end;
end;
Application.MessageBox(PChar(Format(TextByKey('common-screenshot-saved'),
[ExtractFileName(s), ExtractFilePath(s)])), PChar('Apophysis AV'), MB_ICONINFORMATION);
[ExtractFileName(s), ExtractFilePath(s)])), ApophysisSVN, MB_ICONINFORMATION);
except
Application.MessageBox(PChar(TextByKey('common-screenshot-error')), PChar('Apophysis AV'), MB_ICONERROR);
Application.MessageBox(PChar(TextByKey('common-screenshot-error')), ApophysisSVN, MB_ICONERROR);
end;
end;

View File

@ -3,8 +3,8 @@ object SaveForm: TSaveForm
Top = 432
BorderStyle = bsDialog
Caption = 'Save Parameters'
ClientHeight = 153
ClientWidth = 517
ClientHeight = 197
ClientWidth = 528
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
@ -16,17 +16,16 @@ object SaveForm: TSaveForm
OnCreate = FormCreate
OnShow = FormShow
DesignSize = (
517
153)
528
197)
PixelsPerInch = 120
TextHeight = 16
object btnDefGradient: TSpeedButton
Left = 480
Top = 9
Left = 485
Top = 8
Width = 30
Height = 29
Hint = 'Browse...'
Anchors = [akTop, akRight]
Flat = True
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
@ -65,31 +64,10 @@ object SaveForm: TSaveForm
ShowHint = True
OnClick = btnDefGradientClick
end
object btnSave: TButton
Left = 310
Top = 116
Width = 93
Height = 30
Anchors = [akRight, akBottom]
Caption = '&Save'
Default = True
TabOrder = 2
OnClick = btnSaveClick
end
object btnCancel: TButton
Left = 410
Top = 116
Width = 92
Height = 30
Anchors = [akRight, akBottom]
Caption = 'Cancel'
TabOrder = 3
OnClick = btnCancelClick
end
object pnlTarget: TPanel
Left = 10
Top = 10
Width = 124
Width = 120
Height = 26
Cursor = crArrow
BevelOuter = bvLowered
@ -102,7 +80,7 @@ object SaveForm: TSaveForm
object pnlName: TPanel
Left = 10
Top = 39
Width = 124
Width = 120
Height = 26
Cursor = crArrow
BevelOuter = bvLowered
@ -112,42 +90,62 @@ object SaveForm: TSaveForm
TabOrder = 5
end
object txtFilename: TEdit
Left = 128
Left = 130
Top = 10
Width = 353
Height = 24
Anchors = [akLeft, akTop, akRight]
TabOrder = 0
Text = 'txtFilename'
end
object txtTitle: TEdit
Left = 128
Left = 130
Top = 39
Width = 383
Width = 381
Height = 24
Anchors = [akLeft, akTop, akRight]
TabOrder = 1
Text = 'txtTitle'
end
object optUseOldFormat: TRadioButton
object pnlComment: TPanel
Left = 10
Top = 79
Width = 304
Height = 21
Anchors = [akLeft, akTop, akRight]
Caption = 'Use classic flame format'
Checked = True
Top = 68
Width = 120
Height = 26
Cursor = crArrow
BevelOuter = bvLowered
Caption = 'Comment'
ParentShowHint = False
ShowHint = True
TabOrder = 6
TabStop = True
end
object optUseNewFormat: TRadioButton
Left = 10
Top = 101
Width = 304
Height = 21
Anchors = [akLeft, akTop, akRight]
Caption = 'Use new flame format'
Enabled = False
object txtComment: TMemo
Left = 130
Top = 68
Width = 381
Height = 77
Lines.Strings = (
'')
ScrollBars = ssBoth
TabOrder = 7
end
object btnCancel: TButton
Left = 413
Top = 159
Width = 92
Height = 30
Anchors = [akRight, akBottom]
Caption = 'Cancel'
TabOrder = 3
OnClick = btnCancelClick
end
object btnSave: TButton
Left = 305
Top = 159
Width = 93
Height = 30
Anchors = [akRight, akBottom]
Caption = '&Save'
Default = True
TabOrder = 2
OnClick = btnSaveClick
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
@ -39,8 +39,8 @@ type
btnDefGradient: TSpeedButton;
pnlTarget: TPanel;
pnlName: TPanel;
optUseOldFormat: TRadioButton;
optUseNewFormat: TRadioButton;
pnlComment: TPanel;
txtComment: TMemo;
procedure FormCreate(Sender: TObject);
procedure btnSaveClick(Sender: TObject);
procedure btnCancelClick(Sender: TObject);
@ -51,6 +51,7 @@ type
public
Title: string;
Filename: string;
Comment: string;
SaveType : ESaveType;
end;
@ -135,17 +136,17 @@ begin
if ((t = '') and txtTitle.Enabled) then
begin
Application.MessageBox(PChar(TextByKey('save-status-notitle')), 'Apophysis', 48);
Application.MessageBox(PChar(TextByKey('save-status-notitle')), PChar(ApophysisSVN), 48);
Exit;
end;
if f = '' then
begin
Application.MessageBox(PChar(TextByKey('save-status-invalidfilename')), 'Apophysis', 48);
Application.MessageBox(PChar(TextByKey('save-status-invalidfilename')), PChar(ApophysisSVN), 48);
Exit;
end;
if ExtractFileExt(f) = '' then
begin
Application.MessageBox(PChar(TextByKey('save-status-invalidfilename')), 'Apophysis', 48);
Application.MessageBox(PChar(TextByKey('save-status-invalidfilename')), PChar(ApophysisSVN), 48);
Exit;
end;
@ -166,17 +167,22 @@ begin
check := EntryExists(t, f);
end;
if check then begin if onestr then begin
if check then begin
if onestr then
begin
if Application.MessageBox(PChar(Format(TextByKey('save-status-alreadyexists2'), [f])),
'Apophysis', 52) = ID_NO then exit;
end else begin
PChar(ApophysisSVN), 52) = ID_NO then exit;
end
else begin
if Application.MessageBox(PChar(Format(TextByKey('save-status-alreadyexists'), [t, f])),
'Apophysis', 52) = ID_NO then exit;
end end;
PChar(ApophysisSVN), 52) = ID_NO then exit;
end
end;
if (t = '*') then t := '';
Title := t;
Filename := f;
Comment := Trim(txtComment.Lines.Text);
ModalResult := mrOK;
end;
@ -189,11 +195,9 @@ procedure TSaveForm.FormShow(Sender: TObject);
begin
txtFilename.Text := Filename;
txtTitle.Text := Title;
//btnSave.SetFocus;
txtComment.Lines.Text := Comment; // AV
self.Caption := TextByKey(SaveTypeTextKey(SaveType));
{if (SaveType = stSaveParameters) or (SaveType = stSaveAllParameters) then
self.Height := 160
else self.Height := 120; }
if (SaveType = stSaveGradient) then // AV
pnlName.Caption := TextByKey('save-namepal')
else pnlName.Caption := TextByKey('save-name');
@ -203,8 +207,11 @@ begin
if (not txtTitle.Enabled) then pnlName.Font.Color := clGrayText
else pnlName.Font.Color := clWindowText;
optUseOldFormat.Visible := (SaveType = stSaveParameters) or (SaveType = stSaveAllParameters);
optUseNewFormat.Visible := (SaveType = stSaveParameters) or (SaveType = stSaveAllParameters);
pnlComment.Visible := (SaveType = stSaveParameters) or (SaveType = stSaveTemplate);
txtComment.Visible := pnlComment.Visible;
if txtComment.Visible then
self.Height := 225
else self.Height := 160;
txtFileName.ReadOnly := (SaveType = stSaveTemplate); // AV
end;
@ -234,9 +241,8 @@ begin
btnSave.Caption := TextByKey('common-ok');
btnDefGradient.Hint := TextByKey('common-browse');
pnlTarget.Caption := TextByKey('common-destination');
pnlComment.Caption := TextByKey('common-comment');
//pnlName.Caption := TextByKey('save-name');
optUseOldFormat.Caption := TextByKey('save-oldformat');
optUseNewFormat.Caption := TextByKey('save-newformat');
end;
end.

View File

@ -12,14 +12,15 @@ object SavePresetForm: TSavePresetForm
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
Position = poDesktopCenter
OnCreate = FormCreate
DesignSize = (
349
66)
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 190
object btOK: TButton
Left = 180
Top = 37
Width = 75
Height = 25
@ -28,10 +29,10 @@ object SavePresetForm: TSavePresetForm
Default = True
ModalResult = 1
TabOrder = 1
OnClick = Button1Click
OnClick = btOKClick
end
object Button2: TButton
Left = 270
object btCancel: TButton
Left = 260
Top = 37
Width = 75
Height = 25

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
@ -32,11 +32,11 @@ uses
type
TSavePresetForm = class(TForm)
txtPresetName: TEdit;
Button1: TButton;
Button2: TButton;
btOK: TButton;
btCancel: TButton;
pnlName: TPanel;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure btOKClick(Sender: TObject);
private
{ Private declarations }
public
@ -50,11 +50,11 @@ implementation
{$R *.DFM}
procedure TSavePresetForm.Button1Click(Sender: TObject);
procedure TSavePresetForm.btOKClick(Sender: TObject);
begin
if txtPresetName.Text = '' then
begin
Application.MessageBox(PChar(TextByKey('savepreset-notitle')), 'Apophysis', 48);
Application.MessageBox(PChar(TextByKey('savepreset-notitle')), 'Apophysis AV', 48);
Exit;
end;
end;
@ -62,8 +62,8 @@ end;
procedure TSavePresetForm.FormCreate(Sender: TObject);
begin
self.Caption := TextBykey('savepreset-title');
button1.Caption := TextByKey('common-ok');
button2.Caption := TextByKey('common-cancel');
btOK.Caption := TextByKey('common-ok');
btCancel.Caption := TextByKey('common-cancel');
pnlName.Caption := TextByKey('savepreset-name');
end;

View File

@ -994,6 +994,9 @@ object ScriptEditor: TScriptEditor
'procedure Print(data: variant)'
'procedure AddSymmetry(symmetry_type: integer)'
'procedure PrepareToMorph(Flame1_Num: integer, Flame2_Num: intege' +
'r)'
'procedure Morph(Flame1_Num: integer, Flame2_Num: integer, Speed:' +
' double, interp_type: integer = 3)'
'procedure SetRenderBounds'
@ -1076,6 +1079,7 @@ object ScriptEditor: TScriptEditor
'property Name: string'
'property Batches: integer'
'property FinalXformEnabled: boolean'
'property Comment: string'
'var LimitVibrancy: boolean'
'var DateCode: readonly'
'procedure DecodeDate(date, year, month, day)'
@ -1228,7 +1232,7 @@ object ScriptEditor: TScriptEditor
'procedure Inc(num: integer)'
'function Odd(num: integer): boolean'
'function StringOfChar(symbol: char, count: integer): string'
'function GetEnvironmentVariable(sys_const: string): string;'
'function GetEnvironmentVariable(sys_const: string): string'
'const PI'
'const NVARS'
'const NumVariables'

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
@ -27,7 +27,7 @@ interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls, RenderThread, cmap, ControlPoint, Translation;
ComCtrls, StdCtrls, RenderThread, ControlPoint;
type
TScriptRenderForm = class(TForm)
@ -37,9 +37,9 @@ type
procedure FormCreate(Sender: TObject);
procedure btnCancelClick(Sender: TObject);
private
// PixelsPerUnit: double;
StartTime: TDateTime;
Remainder: TDateTime;
Filename: string;
procedure HandleThreadCompletion(var Message: TMessage);
message WM_THREAD_COMPLETE;
@ -47,12 +47,8 @@ type
message WM_THREAD_TERMINATE;
public
Renderer: TRenderThread;
ColorMap: TColorMap;
cp: TControlPoint;
Filename: string;
ImageWidth, ImageHeight, Oversample: Integer;
zoom, Sample_Density, Brightness, Gamma, Vibrancy, Filter_Radius: double;
center: array[0..1] of double;
procedure OnProgress(prog: double);
procedure Render;
procedure SetRenderBounds;
@ -64,20 +60,20 @@ var
implementation
uses Global, Math, FormRender, ScriptForm, Main;
uses Global, Math, FormRender, ScriptForm, Main, Translation;
{$R *.DFM}
procedure TScriptRenderForm.SetRenderBounds;
// AV: do not use it - just waste of time
begin
cp.copy(ScriptEditor.cp);
cp.AdjustScale(ScriptEditor.Renderer.Width, ScriptEditor.Renderer.Height);
// --?-- cp.CalcBoundBox;
cp.center[0] := ScriptEditor.cp.center[0];
cp.center[1] := ScriptEditor.cp.center[1];
cp.zoom := ScriptEditor.cp.zoom;
end;
procedure TScriptRenderForm.Render;
var
ScrRender: TScriptRender; // AV
begin
assert(not Assigned(Renderer));
Renderer := TRenderThread.Create;
@ -86,27 +82,27 @@ begin
ScriptEditor.Scripter.Paused := True;
StartTime := Now;
Remainder := 1;
cp.copy(ScriptEditor.cp);
Filename := ScriptEditor.Renderer.Filename;
//cp.copy(ScriptEditor.cp); // <-- AV: already done by RenderProc
ScrRender := ScriptEditor.Renderer; // AV: for speed
Filename := ScrRender.Filename;
cp.AdjustScale(ScriptEditor.Renderer.Width, ScriptEditor.Renderer.Height);
cp.AdjustScale(ScrRender.Width, ScrRender.Height);
//cp.Transparency := (PNGTransparency <> 0) and (UpperCase(ExtractFileExt(ScriptEditor.Renderer.FileName)) = '.PNG');
if (UpperCase(ExtractFileExt(ScriptEditor.Renderer.FileName)) = '.PNG') then
if (UpperCase(ExtractFileExt(FileName)) = '.PNG') then
begin // AV: added new property
cp.Transparency := (PNGTransparency <> 0);
if ScriptEditor.Renderer.EmbedParameters then
Renderer.EmbedText(Trim(MainForm.RetrieveXML(cp))); // AV
if ScrRender.EmbedParameters then
Renderer.EmbedText(Trim(FlameToXML(cp))); // AV
end
else
cp.Transparency := False; // AV
Renderer.OnProgress := OnProgress;
Renderer.SetCP(cp);
if (ScriptEditor.Renderer.MaxMemory > 0) then
Renderer.MaxMem := ScriptEditor.Renderer.MaxMemory;
if (ScrRender.MaxMemory > 0) then
Renderer.MaxMem := ScrRender.MaxMemory;
Renderer.TargetHandle := Handle;
renderPath := ExtractFilePath(ScriptEditor.Renderer.Filename);
renderPath := ExtractFilePath(Filename);
Renderer.Priority := tpLower;
Renderer.NrThreads := NrTreads; // AV: now works fine
@ -135,7 +131,6 @@ end;
procedure TScriptRenderForm.FormCreate(Sender: TObject);
begin
//Renderer := TRenderThread.Create;
self.Hint := TextByKey('script-rendering');
btnCancel.Caption := TextByKey('common-cancel');
cp := TControlPoint.Create;
@ -145,7 +140,7 @@ procedure TScriptRenderForm.btnCancelClick(Sender: TObject);
begin
ScriptEditor.Scripter.Halt;
Cancelled := True;
// Renderer.Stop;
if Assigned(Renderer) then begin
Renderer.Terminate;
Renderer.WaitFor;

View File

@ -20,7 +20,7 @@ type
public
procedure SetInfo(info:string);
end;
const DURATION: integer = 900;
var
SplashWindow: TSplashWindow;
@ -28,6 +28,9 @@ implementation
{$R *.dfm}
const
DURATION = 900;
procedure TSplashWindow.FormCreate(Sender: TObject);
begin
lblVersion.Caption := APP_VERSION + APP_BUILD;

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,9 +27,9 @@ unit Template;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Translation,
Dialogs, StdCtrls, ComCtrls, ImgList, ControlPoint, cmap, RenderingInterface, Main,
Global, Adjust, System.ImageList;
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ImgList, System.ImageList,
ControlPoint, cmap, RenderingInterface, Main, Global, Adjust, Translation;
type
TTemplateForm = class(TForm)
@ -47,54 +47,55 @@ type
private
{ Private declarations }
Files: TStringList; // AV: replaced "useless" hidded TListBox
procedure ListTemplateByFileName(filename: string);
procedure LoadUserTemplates;
procedure DropBlank;
procedure DropListItem(FileName: string; FlameName: string);
procedure ListTemplate;
public
{ Public declarations }
end;
var
TemplateForm: TTemplateForm;
const
blankFlameXML1 = '<flame name="Blank Flame" version="Apophysis" size="1500 1000" center="0 0" background="0 0 0">';
blankFlameXML2 = '<xform weight="0.5" color="0" linear3D="1" coefs="1 0 0 1 0 0" />';
blankFlameXML3 = '<palette count="256" format="RGB">';
procedure ListTemplateByFileName(filename:string);
implementation
{$R *.dfm}
function LoadUserTemplates2(mask: string): integer;
var
procedure TTemplateForm.LoadUserTemplates;
procedure LoadUserTemplates2(mask: string);
var
FindResult: integer;
SearchRec : TSearchRec;
Path : string;
begin
begin
Path := AppPath + 'Templates\'; // AV
result := 0;
FindResult := FindFirst(Path + Mask, faAnyFile - faDirectory, SearchRec);
while FindResult = 0 do
begin
ListTemplateByFileName(Path + SearchRec.Name);
result := result + 1;
FindResult := FindNext(SearchRec);
end;
{ free memory }
FindClose(SearchRec);
end;
function LoadUserTemplates: integer;
end;
begin
LoadUserTemplates2('*.flame');
LoadUserTemplates2('*.template');
Result := 0; // make RTL happy
end;
(*
function BlankXML: string;
const
blankFlameXML1 = '<flame name="Blank Flame" version="Apophysis AV" size="1500 1000" center="0 0" background="0 0 0">';
blankFlameXML2 = '<xform weight="0.5" color="0" linear3D="1" coefs="1 0 0 1 0 0" />';
blankFlameXML3 = '<palette count="256" format="RGB">';
var
i: integer;
i: smallint;
s: string;
const
break = ' ';
@ -107,10 +108,10 @@ begin
s := s + '</palette></flame>';
Result := s;
end;
*)
procedure DropBlank();
procedure TTemplateForm.DropBlank;
var
flameXML: string;
cp: TControlPoint;
bm: TBitmap;
Render: TRenderer;
@ -120,89 +121,84 @@ begin
Render := TRenderer.Create;
bm := TBitmap.Create;
cp.Clear;
flameXML := BlankXML;
MainForm.ParseXML(cp, PCHAR(flameXML), true);
cp.AdjustScale(TemplateForm.UsedThumbnails.Width, TemplateForm.UsedThumbnails.Height);
// AV: we don't need any parsing and cleaning here
cp.xform[0].density := 0.5; // AV: that's all we need to create a new flame
cp.cmap := MainCp.cmap; // AV: make black dots visible
cp.pixels_per_unit := 5; // AV: decrease the scale
cp.AdjustScale(UsedThumbnails.Width, UsedThumbnails.Height);
// start preview
cp.Width := TemplateForm.UsedThumbnails.Width;
cp.Height := TemplateForm.UsedThumbnails.Height;
cp.spatial_oversample := 1;
cp.spatial_filter_radius := 0.1;
cp.sample_density := 0.5; //3;
try
Render.SetCP(cp);
Render.Render;
finally
BM.Assign(Render.GetImage);
cp.Free;
Render.free;
end;
// Thumbnails
TemplateForm.UsedThumbnails.Add(bm, nil);
bm.Free; // AV: fixed multiple memory leaks!
ListItem := TemplateForm.TemplateList.Items.Add;
ListItem.Caption := 'Blank Flame';
ListItem.ImageIndex := 0;
TemplateForm.Files.Add('n/a');
//end preview
//
Application.ProcessMessages;
end;
procedure DropListItem(FileName: string; FlameName: string);
var
flameXML: string;
cp: TControlPoint;
bm: TBitmap;
Render: TRenderer;
ListItem: TListItem;
begin
cp := TControlPoint.Create;
Render := TRenderer.Create;
bm := TBitmap.Create;
cp.Clear;
flameXML := LoadXMLFlameText(filename, FlameName);
MainForm.ParseXML(cp, PCHAR(flameXML), true);
cp.AdjustScale(TemplateForm.UsedThumbnails.Width, TemplateForm.UsedThumbnails.Height);
// start preview
cp.Width := TemplateForm.UsedThumbnails.Width;
cp.Height := TemplateForm.UsedThumbnails.Height;
cp.spatial_oversample := 1;
//cp.spatial_oversample := 1; // <-- AV: true by default
cp.spatial_filter_radius := 0.1;
cp.sample_density := 3;
try
Render.SetCP(cp);
Render.Render;
finally
BM.Assign(Render.GetImage);
UsedThumbnails.Add(bm, nil);
finally
cp.Free;
Render.free;
end;
// Thumbnails
TemplateForm.UsedThumbnails.Add(bm, nil);
bm.Free; // AV: fixed multiple memory leaks!
ListItem := TemplateForm.TemplateList.Items.Add;
ListItem.Caption := FlameName;
ListItem.ImageIndex := TemplateForm.TemplateList.Items.Count - 1;
TemplateForm.Files.Add(FileName);
end;
{ Thumbnails}
ListItem := TemplateList.Items.Add;
ListItem.Caption := 'Blank Flame';
ListItem.ImageIndex := 0;
Files.Add('n/a');
//end preview
//
Application.ProcessMessages;
end;
procedure ListTemplateByFileName(filename:string);
procedure TTemplateForm.DropListItem(FileName: string; FlameName: string);
var
flameXML: string;
cp: TControlPoint;
bm: TBitmap;
Render: TRenderer;
ListItem: TListItem;
begin
cp := TControlPoint.Create;
Render := TRenderer.Create;
bm := TBitmap.Create;
//cp.Clear;
flameXML := LoadXMLFlameText(filename, FlameName);
MainForm.ParseXML(cp, flameXML, true); // AV: fixed - was PChar instead String
cp.AdjustScale(UsedThumbnails.Width, UsedThumbnails.Height);
// start preview
//cp.spatial_oversample := 1; // <-- AV: true by default
cp.spatial_filter_radius := 0.1;
cp.sample_density := 3;
try
Render.SetCP(cp);
Render.Render;
BM.Assign(Render.GetImage);
UsedThumbnails.Add(bm, nil);
finally
cp.Free;
Render.free;
bm.Free; // AV: fixed multiple memory leaks!
end;
{ Thumbnails }
ListItem := TemplateList.Items.Add;
ListItem.Caption := FlameName;
ListItem.ImageIndex := TemplateList.Items.Count - 1;
Files.Add(FileName);
//end preview
Application.ProcessMessages;
end;
procedure TTemplateForm.ListTemplateByFileName(filename:string);
{ List .flame file }
var
sel: integer;
i, p: integer;
Title: string;
FStrings: TStringList;
begin
sel := 0;
if not FileExists(FileName) then exit;
FStrings := TStringList.Create;
FStrings.LoadFromFile(FileName);
@ -214,46 +210,38 @@ begin
p := Pos('<flame ', LowerCase(FStrings[i]));
if (p <> 0) then
begin
MainForm.ListXMLScanner.LoadFromBuffer(PAnsiChar(Utf8String(FSTrings[i])));
MainForm.ListXMLScanner.LoadFromBuffer(PAnsiChar(Utf8String(FStrings[i]))); // AV
MainForm.ListXMLScanner.Execute;
if Length(pname) = 0 then
Title := '*untitled ' + ptime
else
Title := Trim(pname);
if Title <> '' then
begin { Otherwise bad format }
if Title <> '' then // Otherwise bad format
DropListItem(FileName, Title);
end;
end;
end;
end;
finally
FStrings.Free;
end;
end;
procedure ListTemplate;
procedure TTemplateForm.ListTemplate;
begin
TemplateForm.TemplateList.Items.BeginUpdate;
TemplateForm.TemplateList.Items.Clear;
TemplateForm.UsedThumbnails.Clear;
TemplateList.Items.BeginUpdate;
TemplateList.Items.Clear;
UsedThumbnails.Clear;
// AV: fixed - someone forgot to refresh the file list
TemplateForm.Files.Clear;
// hmmm...
(*for i := 0 to TemplateForm.UsedThumbnails.Count - 1 do
begin
TemplateForm.UsedThumbnails.GetBitmap(i, bm);
bm.Free;
end; *)
Files.Clear;
DropBlank;
ListTemplateByFileName(AppPath + templateFileName);
LoadUserTemplates;
TemplateForm.TemplateList.Items.EndUpdate;
TemplateForm.TemplateList.Selected := TemplateForm.TemplateList.Items[0];
TemplateList.Items.EndUpdate;
TemplateList.Selected := TemplateList.Items[0];
end;
procedure TTemplateForm.FormCreate(Sender: TObject);
@ -273,20 +261,21 @@ procedure TTemplateForm.TemplateListChange(Sender: TObject;
Item: TListItem; Change: TItemChange);
var
fn : string;
i: integer; // AV
begin
if (TemplateList.Selected = nil) then
btnOK.Enabled := false
else begin
if (TemplateList.Selected.Index >= 0) then begin
i := TemplateList.Selected.Index;
if (i >= 0) then begin
btnOK.Enabled := true;
if (TemplateList.Selected.Index > 0) then begin
fn := ChangeFileExt(ExtractFileName(Files[TemplateList.Selected.Index]), '');
if (i > 0) then begin
fn := ChangeFileExt(ExtractFileName(Files[i]), '');
if (LowerCase(fn) <> 'apophysisav') then
lblFile.Caption := TextByKey('template-filename') + fn
lblFile.Caption := TextByKey('template-filename') + #32 + fn
else lblFile.Caption := '';
end else begin
end else
lblFile.Caption := '';
end;
end else
btnOK.Enabled := false;
end;
@ -295,46 +284,66 @@ end;
procedure TTemplateForm.btnOKClick(Sender: TObject);
var
flameXML: string;
fn: string;
ci: integer;
blank: boolean;
i: integer;
begin
fn := Files[TemplateList.Selected.Index];
blank := (TemplateList.Selected.Index = 0);
if blank then
flameXML := BlankXML
else
flameXML := LoadXMLFlameText(fn, TemplateList.Selected.Caption);
MainForm.UpdateUndo;
MainForm.StopThread;
MainForm.InvokeLoadXML(flameXML);
// MainForm.StopThread; // AV: this is already done in the Main unit
i := TemplateList.Selected.Index; // AV
if (i = 0) then // AV: we don't need to waste time to parse an empty flame
begin
with MainCp do begin // AV: make a blank flame easier!
Clear;
name := 'Blank Flame';
// AV: fixed a bug with black flames on the black background
brightness := defBrightness;
gamma := defGamma;
gammaThreshRelative := defGammaThreshold;
contrast := defContrast;
vibrancy := defVibrancy;
sample_density := defSampleDensity;
{ AV: 2D-camera resetting }
center[0] := 0;
center[1] := 0;
zoom := 0;
FAngle := 0;
{ AV: 3D-camera resetting }
cameraPitch := 0;
cameraYaw := 0;
cameraRoll := 0;
cameraPersp := 0;
cameraZPos := 0;
cameraDOF := 0;
xform[0].density := 0.5; // AV: make the single xform visible
xform[1].symmetry := 1; // AV: hide final xform
CalcBoundBox;
end;
Transforms := 1;
EnableFinalXform := false;
end
else begin
flameXML := LoadXMLFlameText(Files[i], TemplateList.Selected.Caption);
MainForm.ParseXML(MainCP, flameXML, false);
Transforms := MainCp.TrianglesFromCP(MainTriangles);
end;
MainForm.Statusbar.Panels[3].Text := MainCp.name;
{if ResizeOnLoad then}
MainForm.ResizeImage;
MainForm.RedrawTimer.Enabled := True;
Application.ProcessMessages;
MainForm.UpdateWindows;
// AV: fixed a bug with black flames on the black background
if RandomizeTemplates or blank then // AV
if RandomizeTemplates then // AV
if (randGradient = 3) then // AV: only if user prefer new palettes
AdjustForm.mnuRandomize.Click
else begin // AV: use preset palette
ci := Random(NRCMAPS);
GetCMap(ci, 1, MainCp.cmap);
MainCp.cmapIndex := ci;
i := Random(NRCMAPS);
GetCMap(i, 1, MainCp.cmap);
MainCp.cmapIndex := i;
end;
if blank then // AV: fixed resetting values to 1
begin
MainCp.brightness := defBrightness;
MainCp.gamma := defGamma;
MainCp.gammaThreshRelative := defGammaThreshold;
MainCp.contrast := defContrast;
MainCp.Vibrancy := defVibrancy;
Maincp.sample_density := defSampleDensity;
end;
Application.ProcessMessages;
MainForm.UpdateWindows;
ModalResult := mrOK; // AV
end;

View File

@ -96,6 +96,10 @@ object TraceForm: TTraceForm
object TabFullscreen: TTabSheet
Caption = 'Fullscreen'
ImageIndex = 52
ExplicitLeft = 0
ExplicitTop = 0
ExplicitWidth = 0
ExplicitHeight = 0
object FullscreenTrace: TMemo
Left = 0
Top = 0
@ -116,9 +120,9 @@ object TraceForm: TTraceForm
end
end
object cbTraceLevel: TComboBox
Left = 280
Left = 240
Top = 0
Width = 121
Width = 147
Height = 21
Style = csDropDownList
Anchors = [akTop, akRight]

View File

@ -5,6 +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-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
@ -23,13 +24,13 @@
unit Tracer;
{$define TRACEFORM_HIDDEN}
//{$define TRACEFORM_HIDDEN}
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, Translation;
Dialogs, StdCtrls, ComCtrls;
type
TTraceForm = class(TForm)
@ -50,9 +51,7 @@ type
var
TraceForm: TTraceForm;
var
TraceLevel: integer;
TraceLevel: shortint;
const
MsgComplete = '< Received WM_THREAD_COMPLETE from RenderThread #';
@ -65,8 +64,7 @@ implementation
{$R *.dfm}
uses
Registry,
Global, Main;
Registry, Global, Main, Translation;
procedure TTraceForm.cbTraceLevelSelect(Sender: TObject);
begin
@ -92,26 +90,17 @@ begin
if Registry.ValueExists('Height') then
self.Height := Registry.ReadInteger('Height');
{$ifndef TRACEFORM_HIDDEN}
{$ifndef TRACEFORM_HIDDEN}
if Registry.ValueExists('TraceLevel') then
TraceLevel := Registry.ReadInteger('TraceLevel')
else
TraceLevel := 0;
MainForm.tbShowTrace.Visible := true;
MainForm.tbShowTrace.Enabled := true;
MainForm.tbTraceSeparator.Visible := true;
MainForm.tbTraceSeparator.Enabled := true;
{$else}
{$else}
TraceLevel := 0;
//MainForm.tbShowTrace.Visible := false;
//MainForm.tbShowTrace.Enabled := false;
//MainForm.tbTraceSeparator.Visible := false;
//MainForm.tbTraceSeparator.Enabled := false;
{$endif}
MainForm.mnuTrace.Visible := False; // AV
{$endif}
end;
Registry.CloseKey;

View File

@ -1,4 +1,4 @@
{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina }
{ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina }
unit VarOrderForm;
@ -6,9 +6,8 @@ interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, StrUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Editor, Translation, Vcl.StdCtrls,
Vcl.ComCtrls, Vcl.ExtCtrls, Vcl.Buttons;
System.Classes, Vcl.Graphics, Vcl.Forms, Vcl.Dialogs, Vcl.Buttons,
Vcl.Controls, Vcl.StdCtrls,Vcl.ComCtrls, Vcl.ExtCtrls, Editor;
type
TVarOrder = class(TForm)
@ -56,7 +55,7 @@ var
implementation
uses
XFormMan, Global; // to get default variation order
XFormMan, Global, Translation; // to get default variation order
{$R *.dfm}
@ -66,7 +65,7 @@ begin
if not assigned(VarListView.Selected) then
begin
Application.MessageBox(PChar(TextByKey('varorder-noselected')),
PChar('Apophysis AV'), MB_ICONWARNING);
'Apophysis AV', MB_ICONWARNING);
exit;
end;
@ -108,7 +107,7 @@ begin
if not assigned(VarListView.Selected) then
begin
Application.MessageBox(PChar(TextByKey('varorder-noselected')),
PChar('Apophysis AV'), MB_ICONWARNING);
'Apophysis AV', MB_ICONWARNING);
exit;
end;
@ -123,7 +122,7 @@ begin
if not assigned(VarListView.Selected) then
begin
Application.MessageBox(PChar(TextByKey('varorder-noselected')),
PChar('Apophysis AV'), MB_ICONWARNING);
'Apophysis AV', MB_ICONWARNING);
exit;
end;
@ -150,7 +149,7 @@ begin
if not assigned(VarListView.Selected) then
begin
Application.MessageBox(PChar(TextByKey('varorder-noselected')),
PChar('Apophysis AV'), MB_ICONWARNING);
'Apophysis AV', MB_ICONWARNING);
exit;
end;
@ -255,7 +254,7 @@ begin
or (s = 'affine3D') or (s = 'spherecrop') then
ListItem.ImageIndex := 6 // violet
else
ListItem.ImageIndex := 5 // blue;
ListItem.ImageIndex := 5 // green;
end;
procedure TVarOrder.ShowSelected(const i: integer);

View File

@ -250,8 +250,8 @@ object frmPostProcess: TfrmPostProcess
end
end
object btnSave: TButton
Left = 588
Top = 510
Left = 580
Top = 509
Width = 97
Height = 25
Anchors = [akRight, akBottom]
@ -270,7 +270,6 @@ object frmPostProcess: TfrmPostProcess
State = cbChecked
TabOrder = 3
Visible = False
OnClick = chkFitToWindowClick
end
object ColorDialog: TColorDialog
Left = 612

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,8 +28,7 @@ interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, RenderingInterface, controlpoint, StdCtrls, ComCtrls,
Translation;
Dialogs, ExtCtrls, RenderingInterface, ControlPoint, StdCtrls, ComCtrls;
type
TfrmPostProcess = class(TForm)
@ -56,7 +55,7 @@ type
btnApply: TButton;
pnlRelGamma: TPanel;
txtRelGamma: TEdit;
procedure chkFitToWindowClick(Sender: TObject);
// procedure chkFitToWindowClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnSaveClick(Sender: TObject);
procedure btnApplyClick(Sender: TObject);
@ -87,18 +86,13 @@ type
mousepos: TPoint;
BkgColor: TColor;
Filter,
Gamma, Brightness, RelGamma,
Contrast, Vibrancy: double;
Filter, Gamma, Brightness, RelGamma, Contrast, Vibrancy: double;
ImCount: shortint; // AV: the number of saved images
NewName: string; // AV
procedure UpdateFlame;
procedure SetDefaultValues;
procedure OnProgress(prog: double);
public
cp : TControlPoint;
@ -113,7 +107,7 @@ var
implementation
uses
Registry, Global, Main;
Registry, Global, Main, Translation;
{$R *.dfm}
@ -319,6 +313,7 @@ end;
///////////////////////////////////////////////////////////////////////////////
procedure TfrmPostProcess.btnSaveClick(Sender: TObject);
var NewName: string; // AV
begin
inc(ImCount);
if ImCount = 0 then
@ -554,15 +549,16 @@ begin
chkFitToWindow.Caption := TextByKey('postprocess-fittowindow');
end;
{
procedure TfrmPostProcess.chkFitToWindowClick(Sender: TObject);
begin
{if (chkFitToWindow.Checked) then begin
if (chkFitToWindow.Checked) then begin
Image.Stretch := true;
Image.Align := alClient;
end else begin
Image.Stretch := false;
Image.Align := alNone;
end; }
end;
end;
}
end.

Binary file not shown.

177
IO/Binary.pas Normal file
View File

@ -0,0 +1,177 @@
unit Binary;
interface
const
HIB_BLOCKSIZE = $10; // 16 bytes
HIB_MAXOFFSET = $0F; // HIB_BLOCKSIZE - 1
type
// low-level binary types
TBlock = array[0..HIB_MAXOFFSET] of byte;
TWord = array[0..1] of byte;
TDWord = array[0..3] of byte;
TQWord = array[0..7] of byte;
THibRawString = array of byte;
// procedures to write blocks at low level
procedure WriteData2(var target: TBlock; data: TWord; pos: integer);
procedure WriteData4(var target: TBlock; data: TDWord; pos: integer);
procedure WriteData8(var target: TBlock; data: TQWord; pos: integer);
// procedures to read blocks at low level
procedure ReadData2(source: TBlock; var data: TWord; pos: integer);
procedure ReadData4(source: TBlock; var data: TDWord; pos: integer);
procedure ReadData8(source: TBlock; var data: TQWord; pos: integer);
// procedures to write typed data to blocks
procedure Int16ToBlock(var target: TBlock; pos: integer; data: SmallInt);
procedure Int32ToBlock(var target: TBlock; pos: integer; data: Integer);
procedure LongWordToBlock(var target: TBlock; pos: integer; data: LongWord);
procedure Int64ToBlock(var target: TBlock; pos: integer; data: Int64);
procedure SingleToBlock(var target: TBlock; pos: integer; data: Single);
procedure DoubleToBlock(var target: TBlock; pos: integer; data: Double);
// procedures to read typed data from blocks
function BlockToInt16(source: TBlock; pos: integer): SmallInt;
function BlockToInt32(source: TBlock; pos: integer): Integer;
function BlockToLongWord(source: TBlock; pos: integer): LongWord;
function BlockToInt64(source: TBlock; pos: integer): Int64;
function BlockToSingle(source: TBlock; pos: integer): Single;
function BlockToDouble(source: TBlock; pos: integer): Double;
implementation
procedure ReadData2(source: TBlock; var data: TWord; pos: integer);
const size = 2;
var i: integer;
begin
for i := 0 to size - 1 do
if i + pos < HIB_BLOCKSIZE then
data[i] := source[i + pos];
end;
procedure ReadData4(source: TBlock; var data: TDWord; pos: integer);
const size = 4;
var i: integer;
begin
for i := 0 to size - 1 do
if i + pos < HIB_BLOCKSIZE then
data[i] := source[i + pos];
end;
procedure ReadData8(source: TBlock; var data: TQWord; pos: integer);
const size = 8;
var i: integer;
begin
for i := 0 to size - 1 do
if i + pos < HIB_BLOCKSIZE then
data[i] := source[i + pos];
end;
procedure WriteData2(var target: TBlock; data: TWord; pos: integer);
const size = 2;
var i: integer;
begin
for i := 0 to size - 1 do
if i + pos < HIB_BLOCKSIZE then
target[i + pos] := data[i];
end;
procedure WriteData4(var target: TBlock; data: TDWord; pos: integer);
const size = 4;
var i: integer;
begin
for i := 0 to size - 1 do
if i + pos < HIB_BLOCKSIZE then
target[i + pos] := data[i];
end;
procedure WriteData8(var target: TBlock; data: TQWord; pos: integer);
const size = 8;
var i: integer;
begin
for i := 0 to size - 1 do
if i + pos < HIB_BLOCKSIZE then
target[i + pos] := data[i];
end;
function BlockToInt16(source: TBlock; pos: integer): SmallInt;
var temp: TWord; data: SmallInt;
begin
ReadData2(source, temp, pos);
Move(temp, data, SizeOf(TWord));
Result := data;
end;
function BlockToInt32(source: TBlock; pos: integer): Integer;
var temp: TDWord; data: Integer;
begin
ReadData4(source, temp, pos);
Move(temp, data, SizeOf(TDWord));
Result := data;
end;
function BlockToLongWord(source: TBlock; pos: integer): LongWord;
var temp: TDWord; data: LongWord;
begin
ReadData4(source, temp, pos);
Move(temp, data, SizeOf(TDWord));
Result := data;
end;
function BlockToInt64(source: TBlock; pos: integer): Int64;
var temp: TQWord; data: Int64;
begin
ReadData8(source, temp, pos);
Move(temp, data, SizeOf(TQWord));
Result := data;
end;
function BlockToSingle(source: TBlock; pos: integer): Single;
var temp: TDWord; data: Single;
begin
ReadData4(source, temp, pos);
Move(temp, data, SizeOf(TDWord));
Result := data;
end;
function BlockToDouble(source: TBlock; pos: integer): Double;
var temp: TQWord; data: Double;
begin
ReadData8(source, temp, pos);
Move(temp, data, SizeOf(TQWord));
Result := data;
end;
procedure Int16ToBlock(var target: TBlock; pos: integer; data: SmallInt);
var temp: TWord;
begin
Move(data, temp, SizeOf(TWord));
WriteData2(target, temp, pos);
end;
procedure Int32ToBlock(var target: TBlock; pos: integer; data: Integer);
var temp: TDWord;
begin
Move(data, temp, SizeOf(TDWord));
WriteData4(target, temp, pos);
end;
procedure LongWordToBlock(var target: TBlock; pos: integer; data: LongWord);
var temp: TDWord;
begin
Move(data, temp, SizeOf(TDWord));
WriteData4(target, temp, pos);
end;
procedure Int64ToBlock(var target: TBlock; pos: integer; data: Int64);
var temp: TQWord;
begin
Move(data, temp, SizeOf(TQWord));
WriteData8(target, temp, pos);
end;
procedure SingleToBlock(var target: TBlock; pos: integer; data: single);
var temp: TDWord;
begin
Move(data, temp, SizeOf(TDWord));
WriteData4(target, temp, pos);
end;
procedure DoubleToBlock(var target: TBlock; pos: integer; data: double);
var temp: TQWord;
begin
Move(data, temp, SizeOf(TQWord));
WriteData8(target, temp, pos);
end;
end.

48
IO/CommandLine.pas Normal file
View File

@ -0,0 +1,48 @@
unit CommandLine;
interface
uses RegularExpressionsCore;
type TCommandLine = class
public
CreateFromTemplate: boolean;
TemplateFile: string;
TemplateName: string;
//Lite: boolean;
procedure Load;
end;
implementation
procedure TCommandLine.Load;
var
Regex: TPerlRegEx;
begin
Regex := TPerlRegEx.Create;
Regex.RegEx := '-template\s+"(.+)"\s+"(.+)"';
Regex.Options := [preSingleLine, preCaseless];
Regex.Subject := CmdLine; // Utf8String(CmdLine);
CreateFromTemplate := false;
if Regex.Match then
if Regex.GroupCount = 2 then begin
CreateFromTemplate := true;
TemplateFile := Regex.Groups[1];
TemplateName := Regex.Groups[2];
end;
Regex.Destroy;
{ // AV: this is not so useful since NXFORMS still equals to 100
Regex := TPerlRegEx.Create;
Regex.RegEx := '-lite';
Regex.Options := [preSingleLine, preCaseless];
Regex.Subject := CmdLine; // Utf8String(CmdLine);
CreateFromTemplate := false;
if Regex.Match then
Lite := true;
Regex.Destroy;
}
end;
end.

99
IO/MissingPlugin.pas Normal file
View File

@ -0,0 +1,99 @@
{
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
}
unit MissingPlugin;
interface
uses Windows, Global, Classes, LoadTracker, ComCtrls, SysUtils,
ControlPoint, Translation;
const RegisteredAttributes : array[0..29] of string = (
'weight', 'color', 'symmetry', 'color_speed', 'coefs', 'chaos',
'plotmode', 'opacity', 'post', 'var', 'var1', 'var_color',
'name', 'linear3D', 'GlynnSim3_thickness2', 'var_order',
'perspective', 'perspective_dist', 'perspective_angle',
'fan', 'rings', 'waves', 'popcorn', 'bent', 'secant', 'arch',
'droste', 'droste_r1', 'droste_r2', 'Spherical3D'
);
var MissingPluginList : TStringList;
Parsing : boolean;
ErrorMessageString : string;
procedure BeginParsing;
procedure CheckAttribute(attr: string);
function EndParsing(cp : TControlPoint; var statusPanelText : string): boolean;
procedure AnnoyUser;
implementation
procedure BeginParsing;
begin
// AV: moved into main unit to be sure that it's created only 1 time
//MissingPluginList := TStringList.Create;
MissingPluginList.Clear; // AV
if (AutoOpenLog = true) then
if (LoadForm.Showing = false) then
LoadForm.Show;
end;
procedure CheckAttribute(attr: string);
var i : integer;
begin
for i := 0 to Length(RegisteredAttributes)-1 do
if attr = RegisteredAttributes[i] then exit;
if MissingPluginList.IndexOf(attr) < 0 then
MissingPluginList.Add(attr);
end;
function EndParsing(cp : TControlPoint; var statusPanelText : string): boolean;
var
str, str2 : string;
i : integer;
newl : TStringList;
begin
str2 := TextByKey('main-status-variationsorvariables');
if (cp.used_plugins.Count > 0) then begin
newl := TStringList.Create;
for i := 0 to MissingPluginList.Count - 1 do begin
if cp.used_plugins.IndexOf(MissingPluginList[i]) >= 0 then
newl.Add(MissingPluginList[i]);
end;
str2 := TextByKey('main-status-plugins');
// MissingPluginList.Free;
// MissingPluginList := newl; // AV: here was a memory leak
MissingPluginList.Clear; // AV
MissingPluginList.Assign(newl); // AV
newl.Free; // AV
end;
if MissingPluginList.Count > 0 then
begin
statusPanelText := Format(TextByKey('main-status-loadingerrorcount'), [MissingPluginList.Count]);
for i := 0 to MissingPluginList.Count - 1 do
str := str + #13#10 + ' - ' + MissingPluginList[i];
ErrorMessageString := Format(TextByKey('main-status-morepluginsneeded'), [cp.name, str2]) + str;
LoadForm.Output.Text := LoadForm.Output.Text +
ErrorMessageString + #13#10#13#10;
Result := false;
end else begin
statusPanelText := TextByKey('main-status-noloadingerrors');
ErrorMessageString := '';
Result := true;
end;
// AV: moved into main unit to be sure that it's destroyed only 1 time
//MissingPluginList.Free;
MissingPluginList.Clear; // AV
end;
procedure AnnoyUser;
begin
if (ErrorMessageString = '') or (not WarnOnMissingPlugin) then exit;
MessageBox($00000000, PChar(ErrorMessageString), PChar('Apophysis AV'), MB_ICONHAND or MB_OK);
end;
end.

1474
IO/Settings.pas Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +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-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,7 +27,7 @@ unit BucketFillerThread;
interface
uses
Classes, Windows, ControlPoint, RenderingInterface, XForm;
Classes, Windows, ControlPoint;
type
TBucketFillerThread = class(TThread)
@ -39,7 +40,7 @@ type
nrbatches: integer;
batchcounter: Pinteger;
ColorMap: TColorMapArray;
//ColorMap: TColorMapArray;
CriticalSection: TRTLCriticalSection;
AddPointsProc: procedure (const points: TPointsArray) of object;
@ -53,8 +54,6 @@ type
implementation
//uses SysUtils, FormRender;
///////////////////////////////////////////////////////////////////////////////
constructor TBucketFillerThread.Create(cp: TControlPoint);
begin

View File

@ -27,7 +27,7 @@ unit ImageMaker;
interface
uses
Windows, Graphics, ControlPoint, RenderingCommon, PngImage, Bezier;
Windows, Graphics, ControlPoint, RenderingCommon, Vcl.Imaging.PngImage, Bezier;
type TPalette = record
logpal : TLogPalette;
@ -97,7 +97,7 @@ type
implementation
uses
Math, SysUtils, JPEG, Global, Types;
Math, SysUtils, Vcl.Imaging.JPEG, Global, Types;
{ TImageMaker }
@ -108,12 +108,11 @@ type
red: byte;
end;
// AV: specific types used only for transparency
PByteArray = ^TByteArray;
TByteArray = array[0..0] of byte;
// PLongintArray = ^TLongintArray;
// TLongintArray = array[0..0] of Longint;
TByteArray = array[0..0] of byte; // AV: single-element array?! why not [word] instead [0..0]?!
PRGBArray = ^TRGBArray;
TRGBArray = array[0..0] of TRGB;
TRGBArray = array[0..0] of TRGB; // AV: single-element array?! why not [word] instead [0..0]?!
///////////////////////////////////////////////////////////////////////////////
constructor TImageMaker.Create;
@ -394,7 +393,6 @@ var
f_select : double;
f_select_int, f_coef_idx : integer;
arr_filt_width : integer;
c : array of double;
ss : integer;
scf:boolean;
scfact : double;
@ -407,7 +405,6 @@ var
bx, by: integer;
label zero_alpha;
begin
SetLength(c, 4);
if fcp.gamma = 0 then
gamma := fcp.gamma
@ -716,7 +713,7 @@ end;
procedure TImageMaker.SaveImage(FileName: String);
var
i,row: integer;
PngObject: TPngObject;
PngObject: TPNGImage;
rowbm, rowpng: PByteArray;
JPEGImage: TJPEGImage;
PNGerror: boolean;
@ -725,7 +722,7 @@ begin
if UpperCase(ExtractFileExt(FileName)) = '.PNG' then begin
pngError := false;
PngObject := TPngObject.Create;
PngObject := TPNGImage.Create;
try
PngObject.Assign(FBitmap);
if fcp.Transparency then // PNGTransparency <> 0

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

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 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,7 +28,7 @@ type
TOnFinish = procedure of object;
TOnProgress = procedure(prog: double) of object;
{$ifdef Apo7X64}
{$ifdef CPUX64}
TBucket = Record
Red,
Green,
@ -55,6 +55,7 @@ type
procedure TrimWorkingSet;
implementation
uses Windows;
procedure TrimWorkingSet;

View File

@ -23,16 +23,14 @@
}
unit RenderingImplementation;
{$ifdef Apo7X64}
{$else}
{$ifndef CPUX64}
{$define _ASM_}
{$endif}
interface
uses
{$ifndef _ASM_}
{$else}
{$ifdef _ASM_}
AsmRandom,
{$endif}
Windows, Classes, Forms, Graphics, Global,

View File

@ -26,8 +26,8 @@ unit RenderingInterface;
interface
uses
Windows, Graphics, Classes, RenderingCommon,
Controlpoint, ImageMaker, PngImage, Translation;
Windows, Graphics, Classes, RenderingCommon, ImageMaker,
ControlPoint, Vcl.Imaging.PngImage, Translation;
///////////////////////////////////////////////////////////////////////////////
//
@ -51,7 +51,7 @@ type
Green,
Blue:
{$ifdef Apo7X64}
{$ifdef CPUX64}
double
{$else}
single
@ -71,9 +71,6 @@ type
const
MAX_FILTER_WIDTH = 25;
//const
//SizeOfBucket: array[0..3] of byte = (32, 32, 32, 32);
function TimeToString(t: TDateTime): string;
type
@ -296,9 +293,7 @@ type
implementation
uses
Math, SysUtils, Forms,
RenderingImplementation,
Binary, Global;
Math, SysUtils, Forms, RenderingImplementation, Binary, Global;
///////////////////////////////////////////////////////////////////////////////
//
@ -309,6 +304,7 @@ procedure TBaseRenderer.Hibernate(filePath: string);
begin
// todo
end;
procedure TBaseRenderer.Resume(filePath: string);
begin
// todo
@ -344,10 +340,11 @@ begin
// entered memory - imagesize
MaxMemory := FMaxMem * 1024 * 1024 - 4 * image_Height * int64(image_Width);
if (SingleBuffer) then
ApproxMemory := 16 * sqr(oversample) * image_Height * int64(image_Width)
else
{$ifdef CPUX86}
ApproxMemory := 16 * sqr(oversample) * image_Height * int64(image_Width);
{$else}
ApproxMemory := 32 * sqr(oversample) * image_Height * int64(image_Width);
{$endif}
assert(MaxMemory > 0);
if MaxMemory <= 0 then exit;
@ -816,10 +813,12 @@ begin
try
// FStop := 0;
// TrimWorkingSet;
if SingleBuffer then
TimeTrace(Format(TextByKey('common-trace-allocating'), [BucketSize * 16 / 1048576]))
else
{$ifdef CPUX86}
TimeTrace(Format(TextByKey('common-trace-allocating'), [BucketSize * 16 / 1048576]));
{$else}
TimeTrace(Format(TextByKey('common-trace-allocating'), [BucketSize * 32 / 1048576]));
{$endif}
AllocateBuckets;

View File

@ -3,15 +3,9 @@ unit CurvesControl;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Math, ControlPoint,
Windows, SysUtils, Classes, Math, ControlPoint,
Graphics, Controls, Forms, Bezier, CustomDrawControl, Vcl.ExtCtrls;
const
point_size: double = 8;
accurancy: double = 3;
channel_count: integer = 4;
padding = 3;
const
MAX_CHANNEL = 3;
@ -73,6 +67,9 @@ implementation
uses Main, Editor, Mutate, Adjust;
const
point_size: double = 8;
constructor TCurvesControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
@ -94,6 +91,7 @@ begin
FrameCreate;
end;
destructor TCurvesControl.Destroy;
begin
FCP.Destroy;
@ -101,7 +99,7 @@ begin
end;
procedure TCurvesControl.SetCp(cp: TControlPoint);
var i, j: integer;
var i, j: smallint;
begin
FCP.Copy(cp, true);
for i := 0 to 3 do
@ -113,6 +111,7 @@ begin
Invalidate;
FFrame.Invalidate;
end;
procedure TCurvesControl.UpdateFlame;
begin
MainForm.StopThread;
@ -130,6 +129,7 @@ procedure TCurvesControl.FrameMouseLeave(Sender: TObject);
begin
FrameMouseUp(nil, mbLeft, [], 0, 0);
end;
procedure TCurvesControl.FrameMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
ps_half: double;
@ -152,12 +152,12 @@ begin
Break;
end;
end;
procedure TCurvesControl.FrameMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
m: BezierPoints;
tmp: BezierPoint;
i: Integer;
j: Integer;
i, j: shortint;
begin
if (y < 0) then Exit;
@ -194,10 +194,10 @@ begin
FCP.curvePoints[i,j].y := FPoints[i,j].y;
end;
FFrame.Refresh;
end;
end;
procedure TCurvesControl.FrameMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
FDragIndex := -1;
@ -207,9 +207,9 @@ begin
end;
procedure TCurvesControl.FrameCreate;
var i: integer;
var i: shortint;
begin
for i := 0 to channel_count - 1 do
for i := 0 to MAX_CHANNEL do
begin
FPoints[i][0].x := 0.00; FPoints[i][0].y := 0.00; FWeights[i][0] := 1;
FPoints[i][1].x := 0.00; FPoints[i][1].y := 0.00; FWeights[i][1] := 1;
@ -220,12 +220,14 @@ begin
FDragIndex := -1;
FDragging := false;
end;
procedure TCurvesControl.FrameResize(Sender: TObject);
begin
FRect.x0 := 0; FRect.y0 := 0;
FRect.x1 := self.Width - 1;
FRect.y1 := self.Height - 1;
end;
procedure TCurvesControl.FramePaint(Sender: TObject);
var
clientRect: TRect;
@ -261,7 +263,7 @@ begin
LineTo(Round(FRect.x1), Round(0.25 * y * FRect.y1));
end;
for i := 0 to channel_count - 1 do begin
for i := 0 to MAX_CHANNEL do begin
for j := 0 to 3 do
wsum[i] := wsum[i] + FWeights[i][j];
for j := 0 to 3 do
@ -282,9 +284,11 @@ begin
end;
procedure TCurvesControl.PaintCurve(Bitmap: TBitmap; c: integer; p: BezierPoints; w: BezierWeights; widgets: boolean);
const
step = 0.001; // AV
var
pos0, pos1: BezierPoint;
t, step: Double;
t: Double;
r, g, b: array [0 .. MAX_CHANNEL] of integer;
rgbv: integer;
begin
@ -303,7 +307,6 @@ begin
rgbv := RGB(r[c], g[c], b[c]);
t := 0;
step := 0.001;
BezierSolve(0, p, w, pos1);
pos0.x := 0; pos0.y := pos1.y;
@ -332,18 +335,19 @@ begin
LineTo(Round(FRect.x1), Round(pos0.y));
if widgets then begin
t := point_size / 2.0; // AV
Brush.Color := rgbv;
Ellipse(
Round(p[1].x - point_size / 2.0),
Round(p[1].y - point_size / 2.0),
Round(p[1].x + point_size / 2.0),
Round(p[1].y + point_size / 2.0)
Round(p[1].x - t),
Round(p[1].y - t),
Round(p[1].x + t),
Round(p[1].y + t)
);
Ellipse(
Round(p[2].x - point_size / 2.0),
Round(p[2].y - point_size / 2.0),
Round(p[2].x + point_size / 2.0),
Round(p[2].y + point_size / 2.0)
Round(p[2].x - t),
Round(p[2].y - t),
Round(p[2].x + t),
Round(p[2].y + t)
);
end;
end;
@ -355,12 +359,14 @@ begin
FChannelIndex := Integer(value);
FFrame.Refresh;
end;
procedure TCurvesControl.SetWeightLeft(value: double);
begin
FWeights[FChannelIndex][1] := value;
FCP.curveWeights[FChannelIndex][1] := value;
FFrame.Refresh;
end;
procedure TCurvesControl.SetWeightRight(value: double);
begin
FWeights[FChannelIndex][2] := value;
@ -372,10 +378,12 @@ function TCurvesControl.GetChannel: TCurvesChannel;
begin
Result := FActiveChannel;
end;
function TCurvesControl.GetWeightLeft: double;
begin
Result := FWeights[FChannelIndex][1];
end;
function TCurvesControl.GetWeightRight: double;
begin
Result := FWeights[FChannelIndex][2];

View File

@ -5,6 +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-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

337
System/MathExpressions.pas Normal file
View File

@ -0,0 +1,337 @@
{ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina }
unit MathExpressions;
interface
uses
System.Rtti, System.SysUtils, System.Bindings.EvalProtocol,
System.Bindings.Evaluator, System.Bindings.EvalSys, System.Bindings.Methods;
function CalculateExpression(const Expr: string): string;
var
InDegrees: boolean;
implementation
uses
System.Math, Windows, Translation;
var
LScope: IScope;
function Sine: IInvokable;
begin
Result := MakeInvokable(
function(Args: TArray<IValue>): IValue
var
IAValue: IValue;
ANum: Double;
begin
// AV: check the number of passed parameters
if Length(Args) <> 1 then begin
MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
['Sin()', 1, Length(Args)])), 'Apophysis AV', 48);
exit;
end;
IAValue := Args[0];
try
ANum := IAValue.GetValue.AsExtended; // AV: check the parameter type
if InDegrees then // AV: translate the parameter into radians
ANum := DegToRad(ANum);
Exit(TValueWrapper.Create(RoundTo(sin(ANum), -6)));
except
MessageBox(0, PChar('Sin(): ' + TextByKey('formula-wrongdatatype')),
'Apophysis AV', 16);
end;
end
);
end;
function CoSine: IInvokable;
begin
Result := MakeInvokable(
function(Args: TArray<IValue>): IValue
var
IAValue: IValue;
ANum: Double;
begin
// AV: check the number of passed parameters
if Length(Args) <> 1 then begin
MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
['Cos()', 1, Length(Args)])), 'Apophysis AV', 48);
exit;
end;
IAValue := Args[0];
try
ANum := IAValue.GetValue.AsExtended;
if InDegrees then // AV: translate the parameter into radians
ANum := DegToRad(ANum);
Exit(TValueWrapper.Create(RoundTo(cos(ANum), -6)));
except
MessageBox(0, PChar('Cos(): ' + TextByKey('formula-wrongdatatype')),
'Apophysis AV', 16);
end;
end
);
end;
function ArcSine: IInvokable;
begin
Result := MakeInvokable(
function(Args: TArray<IValue>): IValue
var
IAValue: IValue;
AValue: Double;
begin
// AV: check the number of passed parameters
if Length(Args) <> 1 then begin
MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
['ArcSin()', 1, Length(Args)])), 'Apophysis AV', 48);
exit;
end;
IAValue := Args[0];
try
AValue := IAValue.GetValue.AsExtended;
if InRange(AValue, -1, 1) then
begin
AValue := arcsin(AValue);
if InDegrees then
AValue := RadToDeg(AValue);
Exit(TValueWrapper.Create(RoundTo(AValue, -6)));
end
else
MessageBox(0, PChar('ArcSin(): ' + TextByKey('formula-outofrange')),
'Apophysis AV', 48);
except
MessageBox(0, PChar('ArcSin(): ' + TextByKey('formula-wrongdatatype')),
'Apophysis AV', 16);
end;
end
);
end;
function ArcCoSine: IInvokable;
begin
Result := MakeInvokable(
function(Args: TArray<IValue>): IValue
var
IAValue: IValue;
AValue: Double;
begin
//AV: check the number of passed parameters
if Length(Args) <> 1 then begin
MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
['ArcCos()', 1, Length(Args)])), 'Apophysis AV', 48);
exit;
end;
IAValue := Args[0];
try
AValue := IAValue.GetValue.AsExtended;
if InRange(AValue, -1, 1) then
begin
AValue := arccos(AValue);
if InDegrees then
AValue := RadToDeg(AValue);
Exit(TValueWrapper.Create(RoundTo(AValue, -6)));
end
else
MessageBox(0, PChar('ArcCos(): ' + TextByKey('formula-outofrange')),
'Apophysis AV', 48);
except
MessageBox(0, PChar('ArcCos(): ' + TextByKey('formula-wrongdatatype')),
'Apophysis AV', 16);
end;
end
);
end;
function ArcTangentYX: IInvokable;
begin
Result := MakeInvokable(
function(Args: TArray<IValue>): IValue
var
IYValue, IXValue: IValue;
AValue: Double;
begin
// AV: check the number of passed parameters
if Length(Args) <> 2 then begin
MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
['ArcTan2()', 2, Length(Args)])), 'Apophysis AV', 48);
exit;
end;
IYValue := Args[0];
IXValue := Args[1];
try
AValue := arctan2(IYValue.GetValue.AsExtended,
IXValue.GetValue.AsExtended);
if InDegrees then
AValue := RadToDeg(AValue);
Exit(TValueWrapper.Create(RoundTo(AValue, -6)));
except
MessageBox(0, PChar('ArcTan2(): ' + TextByKey('common-invalidformat')),
'Apophysis AV', 16);
end;
end
);
end;
function SquareRoot: IInvokable;
begin
Result := MakeInvokable(
function(Args: TArray<IValue>): IValue
var
IAValue: IValue;
ANum: Double;
begin
// AV: check the number of passed parameters
if Length(Args) <> 1 then begin
MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
['Sqrt()', 1, Length(Args)])), 'Apophysis AV', 48);
exit;
end;
IAValue := Args[0];
try
ANum := IAValue.GetValue.AsExtended;
if ANum >= 0 then
Exit(TValueWrapper.Create(RoundTo(sqrt(ANum), -6)))
else
MessageBox(0, PChar('Sqrt(): ' + TextByKey('formula-unsigned')),
'Apophysis AV', 48);
except
MessageBox(0, PChar('Sqrt(): ' + TextByKey('formula-wrongdatatype')),
'Apophysis AV', 16);
end;
end
);
end;
function NatLog: IInvokable;
begin
Result := MakeInvokable(
function(Args: TArray<IValue>): IValue
var
IAValue: IValue;
ANum: Double;
begin
// AV: check the number of passed parameters
if Length(Args) <> 1 then begin
MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
['Ln()', 1, Length(Args)])), 'Apophysis AV', 48);
exit;
end;
IAValue := Args[0];
try
ANum := IAValue.GetValue.AsExtended;
if ANum > 0 then
Exit(TValueWrapper.Create(RoundTo(ln(ANum), -6)))
else
MessageBox(0, PChar('Ln(): ' + TextByKey('formula-unsigned')),
'Apophysis AV', 48);
except
MessageBox(0, PChar('Ln(): ' + TextByKey('formula-wrongdatatype')),
'Apophysis AV', 16);
end;
end
);
end;
function PowerXY: IInvokable;
begin
Result := MakeInvokable(
function(Args: TArray<IValue>): IValue
var
IYValue, IXValue: IValue;
ANum: Double;
begin
// AV: check the number of passed parameters
if Length(Args) <> 2 then begin
MessageBox(0, PChar(Format(TextByKey('formula-wrongargscount'),
['Power()', 2, Length(Args)])), 'Apophysis AV', 48);
exit;
end;
IXValue := Args[0];
IYValue := Args[1];
try
ANum := IXValue.GetValue.AsExtended;
if ANum >= 0 then
Result := TValueWrapper.Create(RoundTo(power(ANum,
IYValue.GetValue.AsExtended), -6))
else
MessageBox(0, PChar('Power(): ' + TextByKey('formula-unsigned')),
'Apophysis AV', 48);
except
MessageBox(0, PChar('Power(): ' + TextByKey('common-invalidformat')),
'Apophysis AV', 16);
end;
end
);
end;
procedure RegisterMathFunctions;
begin
TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
Sine, 'sin', 'sin', '', True, '', nil));
TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
CoSine, 'cos', 'cos', '', True, '', nil));
TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
ArcSine, 'arcsin', 'arcsin', '', True, '', nil));
TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
ArcCoSine, 'arccos', 'arccos', '', True, '', nil));
TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
ArcTangentYX, 'arctan2', 'arctan2', '', True, '', nil));
TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
SquareRoot, 'sqrt', 'sqrt', '', True, '', nil));
TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
PowerXY, 'power', 'power', '', True, '', nil));
TBindingMethodsFactory.RegisterMethod(TMethodDescription.Create(
NatLog, 'ln', 'ln', '', True, '', nil));
LScope := BasicOperators;
TDictionaryScope(LScope).Map.Add('pi', TValueWrapper.Create(pi));
TDictionaryScope(LScope).Map.Add('exp', TValueWrapper.Create(exp(1)));
// AV: add the registered methods
LScope := TNestedScope.Create(LScope, TBindingMethodsFactory.GetMethodScope);
end;
function CalculateExpression(const Expr: string): string;
var
LCompiledExpr : ICompiledBinding;
LResult : TValue;
begin
Result := '';
try
LCompiledExpr := Compile(Expr, LScope);
LResult := LCompiledExpr.Evaluate(LScope, nil, nil).GetValue;
if not LResult.IsEmpty then
Result := LResult.ToString;
except
Result := '';
MessageBox(0, PChar(TextByKey('formula-cannotevaluate')),
'Apophysis AV', 16);
end;
end;
///////////////////////////////////////////////////////////////////////////////
initialization
RegisterMathFunctions;
end.

View File

@ -33,27 +33,31 @@ begin
Regex.Subject := text;
if Regex.Match and (Regex.GroupCount >= group) then
Result := String(Regex.Groups[group])
Result := Regex.Groups[group]
else Result := def;
Regex.Free;
end;
function GetBoolPart(text, expression: string; group: integer; def: boolean): boolean;
begin
Result := GetFloatPart(text, expression, group, StrToFloat(IfThen(def, '1', '0'))) <> 0;
end;
function GetIntPart(text, expression: string; group: integer; def: integer): integer;
var str: string;
begin
str := GetStringPart(text, expression, group, '');
Result := StrToIntDef(str, def);
end;
function GetFloatPart(text, expression: string; group: integer; def: extended): extended;
var str: string;
begin
str := GetStringPart(text, expression, group, '');
Result := StrToFloatDef(str, def);
end;
function Get2IntPart(text, expression: string; group: integer; def: integer): T2Int;
const expr : string = '(\d+)\s+(\d+)';
var str, s1, s2: string;
@ -64,6 +68,7 @@ begin
Result.i1 := StrToIntDef(s1, def);
Result.i2 := StrToIntDef(s2, def);
end;
function Get2FloatPart(text, expression: string; group: integer; def: extended): T2Float;
const expr : string = '([\d.eE+-]+)\s+([\d.eE+-]+)';
var str, s1, s2: string;
@ -74,6 +79,7 @@ begin
Result.f1 := StrToFloatDef(s1, def);
Result.f2 := StrToFloatDef(s2, def);
end;
function GetRGBPart(text, expression: string; group: integer; def: integer): TRGB;
const expr : string = '(\d+)\s+(\d+)\s+(\d+)';
var str, s1, s2, s3: string;

View File

@ -1,633 +0,0 @@
{ unit sdStringTable
Author: Nils Haeck M.Sc. (n.haeck@simdesign.nl)
Original Date: 28 May 2007
Version: 1.1
Copyright (c) 2007 - 2010 Simdesign BV
It is NOT allowed under ANY circumstances to publish or copy this code
without accepting the license conditions in accompanying LICENSE.txt
first!
This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
ANY KIND, either express or implied.
Please visit http://www.simdesign.nl/xml.html for more information.
}
unit sdStringTable;
interface
{$i NativeXml.inc}
uses
Classes, SysUtils, Contnrs;
type
// A record describing a string by its first position and length (Count)
TsdStringRec = record
First: Pbyte;
Count: integer;
end;
// A string reference item used in string reference lists (do not use directly)
TsdRefString = class
private
FID: integer;
FFrequency: integer;
FFirst: Pbyte;
FCharCount: integer;
protected
procedure SetString(const SR: TsdStringRec);
function CompareToSR(const SR: TsdStringRec): integer;
function StringRec: TsdStringRec;
public
destructor Destroy; override;
function AsString: UTF8String;
property CharCount: integer read FCharCount;
property Frequency: integer read FFrequency;
end;
// A list of string reference items (do not use directly)
TsdRefStringList = class(TObjectList)
private
function GetItems(Index: integer): TsdRefString;
protected
// Assumes list is sorted by StringID
function IndexOfID(AID: integer; var Index: integer): boolean;
// Assumes list is sorted by string rec
function IndexOfSR(const AStringRec: TsdStringRec; var Index: integer): boolean;
public
property Items[Index: integer]: TsdRefString read GetItems; default;
end;
// A string table, holding a collection of unique strings, sorted in 2 ways
// for fast access. Strings can be added with AddString or AddStringRec,
// and should be updated with SetString. When a string is added or updated,
// an ID is returned which the application can use to retrieve the string,
// using GetString.
TsdStringTable = class(TPersistent)
private
FByID: TsdRefStringList;
FBySR: TsdRefStringList;
protected
procedure DecFrequency(AItem: TsdRefString; ByIdIndex: integer);
function NextUniqueID: integer;
public
constructor Create;
destructor Destroy; override;
procedure Clear;
// Add a new string rec, return fresh ID or ID of existing item, and increase
// the existing item's ref count
function AddStringRec(const SR: TsdStringRec): integer;
// Add a new string S to the table, the function returns its ID.
function AddString(const S: UTF8String): integer;
// Get the refstring by ID
function ById(index: integer): TsdRefString;
// Delete refstring by ID
procedure Delete(ByIdIndex: integer);
// determine if the stringrec exists
function ExistStringRec(const SR: TsdStringRec): boolean;
// Get the string of refstring with ID
function GetString(ID: integer): UTF8String;
// Set the string value of refstring with ID.
procedure SetString(var ID: integer; const S: UTF8String);
// Number of refstrings
function StringCount: integer;
procedure SaveToFile(const AFileName: string);
procedure SaveToStream(S: TStream);
end;
{utility functions}
// convert a string into a string rec
function sdStringToSR(const S: Utf8String): TsdStringRec;
// convert a string rec into a string
function sdSRToString(const SR: TsdStringRec): Utf8String;
// compare two string recs. This is NOT an alphabetic compare. SRs are first
// compared by length, then by first byte, then last byte then second, then
// N-1, until all bytes are compared.
function sdCompareSR(const SR1, SR2: TsdStringRec): integer;
// compare 2 bytes
function sdCompareByte(Byte1, Byte2: byte): integer;
// compare 2 integers
function sdCompareInteger(Int1, Int2: integer): integer;
function sdUtf16ToUtf8Mem(Src: Pword; Dst: Pbyte; Count: integer): integer;
function sdUtf8ToUtf16Mem(var Src: Pbyte; Dst: Pword; Count: integer): integer;
procedure sdStreamWrite(S: TStream; const AString: AnsiString);
procedure sdStreamWriteStringRec(S: TStream; const AStringRec: TsdStringRec);
procedure sdStreamWriteRefString(S: TStream; ARefString: TsdRefString);
implementation
{ TsdRefString }
function TsdRefString.AsString: UTF8String;
begin
Result := sdSRToString(StringRec);
end;
function TsdRefString.CompareToSR(const SR: TsdStringRec): integer;
begin
if SR.Count = 0 then
begin
// shortcut
Result := 1;
exit;
end;
Result := sdCompareSR(StringRec, SR);
end;
destructor TsdRefString.Destroy;
begin
FreeMem(FFirst);
inherited;
end;
procedure TsdRefString.SetString(const SR: TsdStringRec);
begin
FCharCount := SR.Count;
ReallocMem(FFirst, FCharCount);
Move(SR.First^, FFirst^, FCharCount);
end;
function TsdRefString.StringRec: TsdStringRec;
begin
Result.First := FFirst;
Result.Count := FCharCount;
end;
{ TsdRefStringList }
function TsdRefStringList.GetItems(Index: integer): TsdRefString;
begin
Result := Get(Index);
end;
function TsdRefStringList.IndexOfID(AID: integer; var Index: integer): boolean;
var
Min, Max: integer;
begin
Result := False;
// Find position - binary method
Index := 0;
Min := 0;
Max := Count;
while Min < Max do
begin
Index := (Min + Max) div 2;
case sdCompareInteger(Items[Index].FID, AID) of
-1: Min := Index + 1;
0: begin
Result := True;
exit;
end;
1: Max := Index;
end;
end;
Index := Min;
end;
function TsdRefStringList.IndexOfSR(const AStringRec: TsdStringRec; var Index: integer): boolean;
var
Min, Max: integer;
SR: TsdStringRec;
begin
Result := False;
// Find position - binary method
Index := 0;
Min := 0;
Max := Count;
while Min < Max do
begin
Index := (Min + Max) div 2;
SR := TsdRefString(Get(Index)).StringRec;
case sdCompareSR(SR, AStringRec) of
-1: Min := Index + 1;
0: begin
Result := True;
exit;
end;
1: Max := Index;
end;
end;
Index := Min;
end;
{ TsdStringTable }
function TsdStringTable.AddString(const S: UTF8String): integer;
var
SR: TsdStringRec;
begin
SR := sdStringToSR(S);
Result := AddStringRec(SR);
end;
function TsdStringTable.AddStringRec(const SR: TsdStringRec): integer;
var
BySRIndex: integer;
Item: TsdRefString;
NewSR: TsdStringRec;
Res: boolean;
begin
// zero-length string
if SR.Count = 0 then
begin
Result := 0;
exit;
end;
// Try to find the new string
if FBySR.IndexOfSR(SR, BySRIndex) then
begin
Item := FBySR.Items[BySRIndex];
inc(Item.FFrequency);
Result := Item.FID;
exit;
end;
// Not found.. must make new item
Item := TsdRefString.Create;
Item.SetString(SR);
NewSR := Item.StringRec;
Item.FID := NextUniqueID;
FById.Add(Item);
Item.FFrequency := 1;
// debug:
//SetLength(Item.FValue, Item.FCount);
//Move(Item.FirstPtr(FBase)^, Item.FValue[1], Item.FCount);
// Insert in BySR lists
Res := FBySR.IndexOfSR(NewSR, BySRIndex);
assert(Res = False);
FBySR.Insert(BySRIndex, Item);
Result := Item.FID;
end;
function TsdStringTable.ById(index: integer): TsdRefString;
begin
Result := FById[Index];
end;
procedure TsdStringTable.Clear;
begin
FByID.Clear;
FBySR.Clear;
end;
constructor TsdStringTable.Create;
begin
inherited Create;
FByID := TsdRefStringList.Create(False);
FBySR := TsdRefStringList.Create(True);
end;
procedure TsdStringTable.DecFrequency(AItem: TsdRefString; ByIdIndex: integer);
var
BySRIndex: integer;
Res: boolean;
begin
dec(AItem.FFrequency);
assert(AItem.FFrequency >= 0);
if AItem.FFrequency = 0 then
begin
// We must remove it
FById.Delete(ByIdIndex);
Res := FBySR.IndexOfSR(AItem.StringRec, BySRIndex);
assert(Res = True);
FBySR.Delete(BySRIndex);
end;
end;
procedure TsdStringTable.Delete(ByIdIndex: integer);
var
Item: TsdRefString;
BySRIndex: integer;
Res: boolean;
begin
Item := FById[ByIdIndex];
if Item = nil then
exit;
FById.Delete(ByIdIndex);
Res := FBySR.IndexOfSR(Item.StringRec, BySRIndex);
assert(Res = True);
FBySR.Delete(BySRIndex);
end;
destructor TsdStringTable.Destroy;
begin
FreeAndNil(FByID);
FreeAndNil(FBySR);
inherited;
end;
function TsdStringTable.ExistStringRec(const SR: TsdStringRec): boolean;
var
BySRIndex: integer;
begin
// zero-length string
if SR.Count = 0 then
begin
Result := False;
exit;
end;
// Try to find the new string
Result := FBySR.IndexOfSR(SR, BySRIndex);
end;
function TsdStringTable.GetString(ID: integer): UTF8String;
var
Index, Count: integer;
Item: TsdRefString;
begin
if ID = 0 then
begin
Result := '';
exit;
end;
// Find the ID
if FByID.IndexOfID(ID, Index) then
begin
Item := FById[Index];
Count := Item.FCharCount;
SetLength(Result, Count);
Move(Item.FFirst^, Result[1], Count);
exit;
end;
Result := '';
end;
function TsdStringTable.NextUniqueID: integer;
begin
if FById.Count = 0 then
Result := 1
else
Result := FByID[FByID.Count - 1].FID + 1;
end;
procedure TsdStringTable.SaveToFile(const AFileName: string);
var
F: TFileStream;
begin
F := TFileStream.Create(AFileName, fmCreate);
try
SaveToStream(F);
finally
F.Free;
end;
end;
procedure TsdStringTable.SaveToStream(S: TStream);
var
i: integer;
R: UTF8String;
begin
for i := 0 to FBySR.Count - 1 do
begin
R := FBySR[i].AsString + #13#10;
S.Write(R[1], length(R));
end;
end;
procedure TsdStringTable.SetString(var ID: integer; const S: UTF8String);
var
ByIdIndex: integer;
Item: TsdRefString;
SR: TsdStringRec;
begin
// Make temp string record
SR := sdStringtoSR(S);
// Do we have a ref string with this ID?
if (ID > 0) and FByID.IndexOfID(ID, ByIdIndex) then
begin
// Is the string still the same?
Item := FById[ByIdIndex];
if Item.CompareToSR(SR) = 0 then
exit;
// The string changed..
DecFrequency(Item, ByIdIndex);
end;
ID := AddStringRec(SR);
end;
{utility functions}
function TsdStringTable.StringCount: integer;
begin
Result := FBySR.Count;
end;
function sdStringToSR(const S: UTF8String): TsdStringRec;
begin
Result.Count := length(S);
if Result.Count = 0 then
Result.First := nil
else
Result.First := @S[1];
end;
function sdSRToString(const SR: TsdStringRec): UTF8String;
begin
SetLength(Result, SR.Count);
if SR.Count > 0 then
Move(SR.First^, Result[1], SR.Count);
end;
function sdCompareByte(Byte1, Byte2: byte): integer;
begin
if Byte1 < Byte2 then
Result := -1
else
if Byte1 > Byte2 then
Result := 1
else
Result := 0;
end;
function sdCompareInteger(Int1, Int2: integer): integer;
begin
if Int1 < Int2 then
Result := -1
else
if Int1 > Int2 then
Result := 1
else
Result := 0;
end;
function sdCompareSR(const SR1, SR2: TsdStringRec): integer;
var
Count: integer;
First1, First2, Last1, Last2: Pbyte;
begin
// Compare string length first
Result := sdCompareInteger(SR1.Count, SR2.Count);
if Result <> 0 then
exit;
// Compare first
Result := sdCompareByte(SR1.First^, SR2.First^);
if Result <> 0 then
exit;
Count := SR1.Count;
// Setup First & Last pointers
First1 := SR1.First;
First2 := SR2.First;
Last1 := First1; inc(Last1, Count);
Last2 := First2; inc(Last2, Count);
// Compare each time last ptrs then first ptrs, until they meet in the middle
repeat
dec(Last1);
dec(Last2);
if First1 = Last1 then
exit;
Result := sdCompareByte(Last1^, Last2^);
if Result <> 0 then
exit;
inc(First1); inc(First2);
if First1 = Last1 then
exit;
Result := sdCompareByte(First1^, First2^);
if Result <> 0 then
exit;
until False;
end;
function sdUtf16ToUtf8Mem(Src: Pword; Dst: Pbyte; Count: integer): integer;
// Convert an Unicode (UTF16 LE) memory block to UTF8. This routine will process
// Count wide characters (2 bytes size) to Count UTF8 characters (1-3 bytes).
// Therefore, the block at Dst must be at least 1.5 the size of the source block.
// The function returns the number of *bytes* written.
var
W: word;
DStart: Pbyte;
begin
DStart := Dst;
while Count > 0 do
begin
W := Src^;
inc(Src);
if W <= $7F then
begin
Dst^ := byte(W);
inc(Dst);
end else
begin
if W > $7FF then
begin
Dst^ := byte($E0 or (W shr 12));
inc(Dst);
Dst^ := byte($80 or ((W shr 6) and $3F));
inc(Dst);
Dst^ := byte($80 or (W and $3F));
inc(Dst);
end else
begin // $7F < W <= $7FF
Dst^ := byte($C0 or (W shr 6));
inc(Dst);
Dst^ := byte($80 or (W and $3F));
inc(Dst);
end;
end;
dec(Count);
end;
Result := integer(Dst) - integer(DStart);
end;
function sdUtf8ToUtf16Mem(var Src: Pbyte; Dst: Pword; Count: integer): integer;
// Convert an UTF8 memory block to Unicode (UTF16 LE). This routine will process
// Count *bytes* of UTF8 (each character 1-3 bytes) into UTF16 (each char 2 bytes).
// Therefore, the block at Dst must be at least 2 times the size of Count, since
// many UTF8 characters consist of just one byte, and are mapped to 2 bytes. The
// function returns the number of *wide chars* written. Note that the Src block must
// have an exact number of UTF8 characters in it, if Count doesn't match then
// the last character will be converted anyway (going past the block boundary!)
var
W: word;
C: byte;
DStart: Pword;
SClose: Pbyte;
begin
DStart := Dst;
SClose := Src;
inc(SClose, Count);
while integer(Src) < integer(SClose) do
begin
// 1st byte
W := Src^;
inc(Src);
if W and $80 <> 0 then
begin
W := W and $3F;
if W and $20 <> 0 then
begin
// 2nd byte
C := Src^;
inc(Src);
if C and $C0 <> $80 then
// malformed trail byte or out of range char
Continue;
W := (W shl 6) or (C and $3F);
end;
// 2nd or 3rd byte
C := Src^;
inc(Src);
if C and $C0 <> $80 then
// malformed trail byte
Continue;
Dst^ := (W shl 6) or (C and $3F);
inc(Dst);
end else
begin
Dst^ := W;
inc(Dst);
end;
end;
Result := (integer(Dst) - integer(DStart)) div 2;
end;
procedure sdStreamWrite(S: TStream; const AString: AnsiString);
var
L: integer;
begin
L := Length(AString);
if L > 0 then
begin
S.Write(AString[1], L);
end;
end;
procedure sdStreamWriteStringRec(S: TStream; const AStringRec: TsdStringRec);
begin
S.Write(PAnsiChar(AStringRec.First)^, AStringRec.Count);
end;
procedure sdStreamWriteRefString(S: TStream; ARefString: TsdRefString);
begin
if ARefString = nil then
exit;
S.Write(PAnsiChar(ARefString.FFirst)^, ARefString.FCharCount);
end;
end.

View File

@ -204,6 +204,7 @@ begin
Result := True;
end
end;
function TVariationAffine3D.ResetVariable(const Name: string): boolean;
begin
Result := False;

View File

@ -40,7 +40,7 @@ procedure TVariationCothSpiral.CalcFunction;
var
t, aux, sn, cn, snh, cnh: double;
begin
t := (random - 0.5) * 6.28318530717959;
t := (random - 0.5) * PI2;
SinCos(ta * t, sn, cn);
SinhCosh(t, snh, cnh);

View File

@ -35,8 +35,7 @@ const
var_c1_name='curl_c1';
var_c2_name='curl_c2';
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
{$define _ASM_}
{$endif}

View File

@ -7,15 +7,14 @@ interface
uses
BaseVariation, XFormMan;
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
{$define _ASM_}
{$endif}
type
TVariationDisc2 = class(TBaseVariation)
private
rot, add, c, k, sinadd, cosadd: double;
rot, add, p, k, sinadd, cosadd: double;
public
constructor Create;
@ -49,7 +48,7 @@ end;
procedure TVariationDisc2.Prepare;
var t: double;
begin
c := vvar / PI;
p := vvar / PI;
k := rot * PI;
SinCos(add, sinadd, cosadd);
cosadd := cosadd - 1;
@ -73,7 +72,7 @@ var
r, sinr, cosr: extended;
begin
SinCos(k * (FTx^ + FTy^), sinr, cosr);
r := c * arctan2(FTx^, FTy^);
r := p * arctan2(FTx^, FTy^);
FPx^ := FPx^ + (sinr + cosadd) * r;
FPy^ := FPy^ + (cosr + sinadd) * r;
{$else}
@ -82,7 +81,7 @@ asm
fld qword ptr [edx]
fld qword ptr [edx + 8]
fpatan
fmul qword ptr [eax + c]
fmul qword ptr [eax + p]
fld qword ptr [edx]
fadd qword ptr [edx + 8]
fmul qword ptr [eax + k]

View File

@ -6,8 +6,7 @@ interface
uses
BaseVariation, XFormMan;
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
{$define _ASM_}
{$endif}

View File

@ -5,6 +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-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
@ -40,9 +41,8 @@ interface
uses
BaseVariation, XFormMan, Settings, // Translation,
Classes, //TStrings/TStringList
SysUtils, //FindFirst/FindNext/FindClose
Forms; //MessageBox
Classes, //TFileStream
SysUtils; //FindFirst/FindNext/FindClose
type
TPluginVariationClass = class of TPluginVariation;
@ -108,10 +108,10 @@ type
PluginData : TPluginData;
end;
procedure InitializePlugins;
//procedure InitializePlugins;
const CurrentPlatform =
{$ifdef Apo7X64}
{$ifdef CPUX64}
$00000040
{$else}
$00000020
@ -122,7 +122,7 @@ const CurrentPlatform =
implementation
uses
Windows, //LoadLibrary
Windows, //LoadLibrary / MessageBox
Global;
{ TPluginVariation }
@ -206,31 +206,31 @@ begin
Result := '';
end;
///////////////////////////////////////////////////////////////////////////////
{ //////////////////////////////////////////////////////////////////////////}
function TPluginVariation.GetNrVariables: integer;
begin
Result := PluginData.PluginVarGetNrVariables;
end;
///////////////////////////////////////////////////////////////////////////////
{////////////////////////////////////////////////////////////////////////////}
function TPluginVariation.GetVariableNameAt(const Index: integer): string;
begin
Result := String(PluginData.PluginVarGetVariableNameAt(Index));
end;
///////////////////////////////////////////////////////////////////////////////
{////////////////////////////////////////////////////////////////////////////}
function TPluginVariation.SetVariable(const Name: string; var value: double): boolean;
begin
Result := PluginData.PluginVarSetVariable(MyVariation,PAnsiChar(AnsiString(Name)),value);
end;
///////////////////////////////////////////////////////////////////////////////
{////////////////////////////////////////////////////////////////////////////}
function TPluginVariation.GetVariable(const Name: string; var value: double): boolean;
begin
Result := PluginData.PluginVarGetVariable(MyVariation,PAnsiChar(AnsiString(Name)),value);
end;
///////////////////////////////////////////////////////////////////////////////
{ ////////////////////////////////////////////////////////////////////////}
function TPluginVariation.ResetVariable(const Name: string) : boolean;
var
dummy: double;
@ -281,7 +281,7 @@ begin
end;
end;
///////////////////////////////////////////////////////////////////////////////
{////////////////////////////////////////////////////////////////////////////}
procedure InitializePlugins;
var
searchResult: TSearchRec;
@ -334,8 +334,7 @@ begin
@PluginVarResetVariable := GetProcAddress(PluginHandle,'PluginVarResetVariable');
RegisterVariation(TVariationPluginLoader.Create(PluginData), @PluginVarInit3D <> nil, @PluginVarInitDC <> nil);
//RegisterVariationFile(ExtractFilePath(Application.ExeName) + 'Plugins\' + searchResult.Name, name);
RegisterVariationFile(PluginPath + searchResult.Name, name); // AV: fixed!
//RegisterVariationFile(PluginPath + searchResult.Name, name); // AV: fixed!
end;
end else begin
errno := GetLastError;
@ -346,14 +345,20 @@ begin
until (FindNext(searchResult) <> 0);
SysUtils.FindClose(searchResult); //Since we use Windows unit (LoadLibrary)
// AV: now we can build the list of variation names
FillVarNamesList;
// AV: replaced Application.MessageBox by a more faster one from Windows unit
if msg <> '' then
Application.MessageBox(
MessageBox(0,
PChar('There were problems with some of the plugins:' + #13#10#13#10 + msg),
'Warning', MB_ICONWARNING or MB_OK); // TextByKey('common-loaderror1')
'Apophysis AV Warning', MB_ICONWARNING or MB_OK); // TextByKey('common-loaderror1')
end;
end;
///////////////////////////////////////////////////////////////////////////////
{ ////////////////////////////////////////////////////////////////////////// }
initialization
InitializePlugins;
end.

View File

@ -9,14 +9,22 @@ uses
type
TVariationHeart = class(TBaseVariation)
private
use3D: byte;
procedure Calc3D;
public
constructor Create;
class function GetName: string; override;
class function GetInstance: TBaseVariation; override;
function GetNrVariables: integer; override;
function GetVariableNameAt(const Index: integer): string; override;
function SetVariable(const Name: string; var value: double): boolean; override;
function GetVariable(const Name: string; var value: double): boolean; override;
procedure CalcFunction; override;
procedure GetCalcFunction(var f: TCalcFunction); override;
end;
@ -26,6 +34,12 @@ uses
Math;
////////////////////////
procedure TVariationHeart.GetCalcFunction(var f: TCalcFunction);
begin
if use3D <> 0 then
f := Calc3D
else f := CalcFunction;
end;
procedure TVariationHeart.CalcFunction;
var
@ -39,9 +53,26 @@ begin
FPy^ := FPy^ - r * cosr;
end;
procedure TVariationHeart.Calc3D;
var
FAngle, r, sinr, cosr: double;
begin
FAngle := arctan2(FTx^, FTy^);
r := sqrt(sqr(FTx^) + sqr(FTy^));
Sincos(r * FAngle, sinr, cosr);
r := r * vvar;
FPx^ := FPx^ + r * sinr;
FPy^ := FPy^ - r * cosr;
FAngle := arctan2(FTz^, FTy^);
r := sqrt(sqr(FTx^) + sqr(FTz^));
cosr := cos(r * FAngle);
FPz^ := FPz^ - vvar * r * cosr;
end;
constructor TVariationHeart.Create;
begin
inherited Create;
use3D := 0;
end;
class function TVariationHeart.GetInstance: TBaseVariation;
@ -54,8 +85,43 @@ begin
Result := 'heart';
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationHeart.GetVariableNameAt(const Index: integer): string;
begin
case Index of
0: Result := 'heart_use3D';
else
Result := '';
end;
end;
function TVariationHeart.GetNrVariables: integer;
begin
Result := 1;
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationHeart.SetVariable(const Name: string; var value: double): boolean;
begin
Result := False;
if Name = 'heart_use3D' then begin
if (Value > 1) then Value := 1;
if (Value < 0) then Value := 0;
use3D := Round(Value);
Result := True;
end;
end;
function TVariationHeart.GetVariable(const Name: string; var value: double): boolean;
begin
Result := False;
if Name = 'heart_use3D' then begin
Value := use3D;
Result := True;
end;
end;
//////////////////////////////
initialization
RegisterVariation(TVariationClassLoader.Create(TVariationHeart), false, false);
RegisterVariation(TVariationClassLoader.Create(TVariationHeart), true, false);
end.

View File

@ -4,14 +4,12 @@ unit varJulia;
interface
uses
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
AsmRandom,
{$endif}
BaseVariation, XFormMan;
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
{$define _ASM_}
{$endif}

View File

@ -26,8 +26,7 @@ unit varJulia3Djf; // original variation code by Joel Faber, modified & optimize
interface
uses
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
AsmRandom,
{$endif}
BaseVariation, XFormMan;
@ -36,8 +35,7 @@ const
var_name = 'julia3D';
var_n_name='julia3D_power';
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
{$define _ASM_}
{$endif}

View File

@ -26,8 +26,7 @@ unit varJulia3Dz;
interface
uses
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
AsmRandom,
{$endif}
BaseVariation, XFormMan;
@ -36,8 +35,7 @@ const
var_name = 'julia3Dz';
var_n_name='julia3Dz_power';
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
{$define _ASM_}
{$endif}

View File

@ -3,8 +3,7 @@ unit varJuliaN;
interface
uses
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
AsmRandom,
{$endif}
BaseVariation, XFormMan;
@ -14,8 +13,7 @@ const
var_n_name='julian_power';
var_c_name='julian_dist';
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
{$define _ASM_}
{$endif}

View File

@ -26,8 +26,7 @@ unit varJuliaScope;
interface
uses
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
AsmRandom,
{$endif}
BaseVariation, XFormMan;
@ -37,8 +36,7 @@ const
var_n_name='juliascope_power';
var_c_name='juliascope_dist';
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
{$define _ASM_}
{$endif}

View File

@ -60,7 +60,7 @@ uses
procedure TVariationNGon.Prepare;
begin
cpower := -0.5 * ngon_power;
csides := 2.0 * PI / ngon_sides;
csides := PI2 / ngon_sides; // AV: replaced 2.0 * PI by the const
csidesinv := 1.0 / csides;
end;
@ -68,9 +68,11 @@ procedure TVariationNGon.CalcFunction;
var
r_factor, theta, phi, amp: double;
begin
if (FTX^ = 0) and (FTY^ = 0) then r_factor := 0
else r_factor := Power(FTx^ * FTx^ + FTy^ * FTy^, cpower);
// AV: this check for a single case just slow down overall calculations
// since these 2 conditions are evaluated in every point
{ if (FTX^ = 0) and (FTY^ = 0) then
else } // <-- this will be true anyway
r_factor := Power(FTx^ * FTx^ + FTy^ * FTy^, cpower);
theta := ArcTan2(FTy^, FTx^);
@ -78,11 +80,12 @@ begin
if (phi > 0.5 * csides) then
phi := phi - csides;
// AV: and yeah, if (r_factor = 0) then also (amp = 0) so we must not calc it
amp := (ngon_corners * (1.0 / cos(phi) - 1.0) + ngon_circle) * VVAR * r_factor;
FPx^ := FPx^ + amp * FTx^;
FPy^ := FPy^ + amp * FTy^;
FPz^ := FPz^ + VVAR * FTz^;
FPz^ := FPz^ + VVAR * FTz^; // <-- AV: I don't like this since we have pre_zscale
end;
///////////////////////////////////////////////////////////////////////////////

View File

@ -29,8 +29,7 @@ interface
uses
BaseVariation, XFormMan;
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
{$define _ASM_}
{$endif}

View File

@ -87,6 +87,7 @@ begin
else if blurtype = 2 then f := CalcFunctionGaussian
else f := CalcFunction;
end;
procedure TVariationPostFalloff2.CalcFunction;
var
in_x, in_y, in_z, d: double;
@ -104,6 +105,7 @@ begin
FPz^ := VVAR * (in_z + mul_z * random * d);
color^ := Abs(Frac(color^ + mul_c * random * d));
end;
procedure TVariationPostFalloff2.CalcFunctionRadial;
var
in_x, in_y, in_z, d, r_in: double;
@ -130,6 +132,7 @@ begin
FPz^ := VVAR * (sins);
color^ := Abs(Frac(color^ + mul_c * random * d));
end;
procedure TVariationPostFalloff2.CalcFunctionGaussian;
var
in_x, in_y, in_z, d: double;

View File

@ -0,0 +1,254 @@
{
Apophysis Copyright (C) 2001-2004 Mark Townsend
Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov
Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
}
unit varPostMobius;
interface
uses
BaseVariation, XFormMan;
type
TVariationPostMobius = class(TBaseVariation)
private
Re_A, Im_A, Re_B, Im_B, Re_C, Im_C, Re_D, Im_D: double;
mobius_invert : byte;
procedure CalcInvert;
public
constructor Create;
class function GetName: string; override;
class function GetInstance: TBaseVariation; override;
function GetNrVariables: integer; override;
function GetVariableNameAt(const Index: integer): string; override;
function SetVariable(const Name: string; var value: double): boolean; override;
function GetVariable(const Name: string; var value: double): boolean; override;
function ResetVariable(const Name: string): boolean; override;
procedure CalcFunction; override;
procedure GetCalcFunction(var f: TCalcFunction); override;
end;
implementation
uses
Math;
///////////////////////////////////////////////////////////////////////////////
procedure TVariationPostMobius.GetCalcFunction(var f: TCalcFunction);
begin // AV: this helps to increase the calc speed
if (mobius_invert <> 0) then
f := CalcInvert
else f := CalcFunction;
end;
procedure TVariationPostMobius.CalcFunction;
const EPS = 1E-100;
var
uRe, uIm, vRe, vIm, vDenom : double;
begin
uRe := (Re_A) * FPX^ - (Im_A) * FPY^ + (Re_B);
uIm := (Re_A) * FPY^ + (Im_A) * FPX^ + (Im_B);
vRe := (Re_C) * FPX^ - (Im_C) * FPY^ + (Re_D);
vIm := (Re_C) * FPY^ + (Im_C) * FPX^ + (Im_D);
vDenom := vRe * vRe + vIm * vIm;
if abs(vDenom) < EPS then vDenom := EPS;
FPx^ := VVAR * (uRe*vRe + uIm*vIm) / vDenom;
FPy^ := VVAR * (uIm*vRe - uRe*vIm) / vDenom;
end;
procedure TVariationPostMobius.CalcInvert; // inverse Mobius transformation
const EPS = 1E-100;
var
uRe, uIm, vRe, vIm, vDenom : double;
begin
uRe := (Re_D) * FPX^ - (Im_D) * FPY^ - (Re_B);
uIm := (Re_D) * FPY^ + (Im_D) * FPX^ - (Im_B);
vRe := -(Re_C) * FPX^ + (Im_C) * FPY^ + (Re_A);
vIm := -(Re_C) * FPY^ - (Im_C) * FPX^ + (Im_A);
vDenom := vRe * vRe + vIm * vIm;
if abs(vDenom) < EPS then vDenom := EPS;
FPx^ := VVAR * (uRe*vRe + uIm*vIm) / vDenom;
FPy^ := VVAR * (uIm*vRe - uRe*vIm) / vDenom;
end;
///////////////////////////////////////////////////////////////////////////////
constructor TVariationPostMobius.Create;
begin
Re_A := 1; Im_A := 0;
Re_B := 0; Im_B := 0;
Re_C := 0; Im_C := 0;
Re_D := 1; Im_D := 0;
mobius_invert := 0;
end;
///////////////////////////////////////////////////////////////////////////////
class function TVariationPostMobius.GetInstance: TBaseVariation;
begin
Result := TVariationPostMobius.Create;
end;
///////////////////////////////////////////////////////////////////////////////
class function TVariationPostMobius.GetName: string;
begin
Result := 'post_mobius';
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationPostMobius.GetVariableNameAt(const Index: integer): string;
begin
case Index of
0: Result := 'post_mobius_Re_A';
1: Result := 'post_mobius_Im_A';
2: Result := 'post_mobius_Re_B';
3: Result := 'post_mobius_Im_B';
4: Result := 'post_mobius_Re_C';
5: Result := 'post_mobius_Im_C';
6: Result := 'post_mobius_Re_D';
7: Result := 'post_mobius_Im_D';
8: Result := 'post_mobius_invert';
else
Result := '';
end
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationPostMobius.SetVariable(const Name: string; var value: double): boolean;
begin
Result := False;
if Name = 'post_mobius_Re_A' then begin
Re_A := Value;
Result := True;
end else if Name = 'post_mobius_Im_A' then begin
Im_A := Value;
Result := True;
end else if Name = 'post_mobius_Re_B' then begin
Re_B := Value;
Result := True;
end else if Name = 'post_mobius_Im_B' then begin
Im_B := Value;
Result := True;
end else if Name = 'post_mobius_Re_C' then begin
Re_C := Value;
Result := True;
end else if Name = 'post_mobius_Im_C' then begin
Im_C := Value;
Result := True;
end else if Name = 'post_mobius_Re_D' then begin
Re_D := Value;
Result := True;
end else if Name = 'post_mobius_Im_D' then begin
Im_D := Value;
Result := True;
end else if Name = 'post_mobius_invert' then begin
if (Value > 1) then Value := 1;
if (Value < 0) then Value := 0;
mobius_invert := Round(Value);
Result := True;
end
end;
function TVariationPostMobius.ResetVariable(const Name: string): boolean;
begin
Result := False;
if Name = 'post_mobius_Re_A' then begin
Re_A := 1;
Result := True;
end else if Name = 'post_mobius_Im_A' then begin
Im_A := 0;
Result := True;
end else if Name = 'post_mobius_Re_B' then begin
Re_B := 0;
Result := True;
end else if Name = 'post_mobius_Im_B' then begin
Im_B := 0;
Result := True;
end else if Name = 'post_mobius_Re_C' then begin
Re_C := 0;
Result := True;
end else if Name = 'post_mobius_Im_C' then begin
Im_C := 0;
Result := True;
end else if Name = 'post_mobius_Re_D' then begin
Re_D := 1;
Result := True;
end else if Name = 'post_mobius_Im_D' then begin
Im_D := 0;
Result := True;
end else if Name = 'post_mobius_invert' then begin
mobius_invert := 0;
Result := True;
end
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationPostMobius.GetNrVariables: integer;
begin
Result := 9
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationPostMobius.GetVariable(const Name: string; var value: double): boolean;
begin
Result := False;
if Name = 'post_mobius_Re_A' then begin
Value := Re_A;
Result := True;
end else if Name = 'post_mobius_Im_A' then begin
Value := Im_A;
Result := True;
end else if Name = 'post_mobius_Re_B' then begin
Value := Re_B;
Result := True;
end else if Name = 'post_mobius_Im_B' then begin
Value := Im_B;
Result := True;
end else if Name = 'post_mobius_Re_C' then begin
Value := Re_C;
Result := True;
end else if Name = 'post_mobius_Im_C' then begin
Value := Im_C;
Result := True;
end else if Name = 'post_mobius_Re_D' then begin
Value := Re_D;
Result := True;
end else if Name = 'post_mobius_Im_D' then begin
Value := Im_D;
Result := True;
end else if Name = 'post_mobius_invert' then begin
Value := mobius_invert;
Result := True;
end
end;
///////////////////////////////////////////////////////////////////////////////
initialization
RegisterVariation(TVariationClassLoader.Create(TVariationPostMobius), false, false);
end.

View File

@ -7,8 +7,7 @@ interface
uses
BaseVariation, XFormMan;
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
{$define _ASM_}
{$endif}

View File

@ -1,4 +1,4 @@
{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina }
{ Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina }
unit varPower;
@ -9,14 +9,22 @@ uses
type
TVariationPower = class(TBaseVariation)
private
use3D: byte;
procedure Calc3D;
public
constructor Create;
class function GetName: string; override;
class function GetInstance: TBaseVariation; override;
function GetNrVariables: integer; override;
function GetVariableNameAt(const Index: integer): string; override;
function SetVariable(const Name: string; var value: double): boolean; override;
function GetVariable(const Name: string; var value: double): boolean; override;
procedure CalcFunction; override;
procedure GetCalcFunction(var f: TCalcFunction); override;
end;
@ -27,14 +35,35 @@ uses
////////////////////////
procedure TVariationPower.GetCalcFunction(var f: TCalcFunction);
begin
if use3D <> 0 then f := Calc3D // AV: added optional 3d-support
else f := CalcFunction;
end;
procedure TVariationPower.Calc3D; // AV
var
r, FSinA, FCosA: double;
begin
r := sqrt(sqr(FTx^) + sqr(FTy^) + sqr(FTz^)) + 1E-300;
FSinA := FTx^ / r;
FCosA := FTy^ / r;
r := vvar * Math.Power(r, FSinA);
FPx^ := FPx^ + r * FCosA;
FPy^ := FPy^ + r * FSinA;
// transform the plane into 3d-shape
r := vvar * Math.Power(r, FCosA);
FPz^ := FPz^ + r * FCosA; //FSinA;
end;
procedure TVariationPower.CalcFunction;
var
r, FLength, FSinA, FCosA: double;
r, FSinA, FCosA: double;
begin
FLength := sqrt(sqr(FTx^) + sqr(FTy^)) + 1E-300;
FSinA := FTx^ / FLength;
FCosA := FTy^ / FLength;
r := vvar * Math.Power(FLength, FSinA);
r := sqrt(sqr(FTx^) + sqr(FTy^)) + 1E-300;
FSinA := FTx^ / r;
FCosA := FTy^ / r;
r := vvar * Math.Power(r, FSinA);
FPx^ := FPx^ + r * FCosA;
FPy^ := FPy^ + r * FSinA;
end;
@ -42,6 +71,7 @@ end;
constructor TVariationPower.Create;
begin
inherited Create;
use3D := 0;
end;
class function TVariationPower.GetInstance: TBaseVariation;
@ -54,8 +84,44 @@ begin
Result := 'power';
end;
function TVariationPower.GetNrVariables: integer;
begin
Result := 1;
end;
function TVariationPower.GetVariableNameAt(const Index: integer): string;
begin
case Index of
0: Result := 'power_use3D';
else
Result := '';
end;
end;
function TVariationPower.GetVariable(const Name: string;
var value: double): boolean;
begin
Result := False;
if Name = 'power_use3D' then begin
Value := use3D;
Result := True;
end;
end;
function TVariationPower.SetVariable(const Name: string;
var value: double): boolean;
begin
Result := False;
if Name = 'power_use3D' then begin
if (Value > 1) then Value := 1;
if (Value < 0) then Value := 0;
use3D := Round(Value);
Result := True;
end;
end;
//////////////////////////////
initialization
RegisterVariation(TVariationClassLoader.Create(TVariationPower), false, false);
RegisterVariation(TVariationClassLoader.Create(TVariationPower), true, false);
end.

254
Variations/varPreMobius.pas Normal file
View File

@ -0,0 +1,254 @@
{
Apophysis Copyright (C) 2001-2004 Mark Townsend
Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov
Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
}
unit varPreMobius;
interface
uses
BaseVariation, XFormMan;
type
TVariationPreMobius = class(TBaseVariation)
private
Re_A, Im_A, Re_B, Im_B, Re_C, Im_C, Re_D, Im_D: double;
mobius_invert : byte;
procedure CalcInvert;
public
constructor Create;
class function GetName: string; override;
class function GetInstance: TBaseVariation; override;
function GetNrVariables: integer; override;
function GetVariableNameAt(const Index: integer): string; override;
function SetVariable(const Name: string; var value: double): boolean; override;
function GetVariable(const Name: string; var value: double): boolean; override;
function ResetVariable(const Name: string): boolean; override;
procedure CalcFunction; override;
procedure GetCalcFunction(var f: TCalcFunction); override;
end;
implementation
uses
Math;
///////////////////////////////////////////////////////////////////////////////
procedure TVariationPreMobius.GetCalcFunction(var f: TCalcFunction);
begin // AV: this helps to increase the calc speed
if (mobius_invert <> 0) then
f := CalcInvert
else f := CalcFunction;
end;
procedure TVariationPreMobius.CalcFunction;
const EPS = 1E-100;
var
uRe, uIm, vRe, vIm, vDenom : double;
begin
uRe := (Re_A) * FTx^ - (Im_A) * FTy^ + (Re_B);
uIm := (Re_A) * FTy^ + (Im_A) * FTx^ + (Im_B);
vRe := (Re_C) * FTx^ - (Im_C) * FTy^ + (Re_D);
vIm := (Re_C) * FTy^ + (Im_C) * FTx^ + (Im_D);
vDenom := vRe * vRe + vIm * vIm;
if abs(vDenom) < EPS then vDenom := EPS;
FTx^ := VVAR * (uRe*vRe + uIm*vIm) / vDenom;
FTy^ := VVAR * (uIm*vRe - uRe*vIm) / vDenom;
end;
procedure TVariationPreMobius.CalcInvert; // inverse Mobius transformation
const EPS = 1E-100;
var
uRe, uIm, vRe, vIm, vDenom : double;
begin
uRe := (Re_D) * FTX^ - (Im_D) * FTY^ - (Re_B);
uIm := (Re_D) * FTY^ + (Im_D) * FTx^ - (Im_B);
vRe := -(Re_C) * FTx^ + (Im_C) * FTy^ + (Re_A);
vIm := -(Re_C) * FTy^ - (Im_C) * FTx^ + (Im_A);
vDenom := vRe * vRe + vIm * vIm;
if abs(vDenom) < EPS then vDenom := EPS;
FTx^ := VVAR * (uRe*vRe + uIm*vIm) / vDenom;
FTy^ := VVAR * (uIm*vRe - uRe*vIm) / vDenom;
end;
///////////////////////////////////////////////////////////////////////////////
constructor TVariationPreMobius.Create;
begin
Re_A := 1; Im_A := 0;
Re_B := 0; Im_B := 0;
Re_C := 0; Im_C := 0;
Re_D := 1; Im_D := 0;
mobius_invert := 0;
end;
///////////////////////////////////////////////////////////////////////////////
class function TVariationPreMobius.GetInstance: TBaseVariation;
begin
Result := TVariationPreMobius.Create;
end;
///////////////////////////////////////////////////////////////////////////////
class function TVariationPreMobius.GetName: string;
begin
Result := 'pre_mobius';
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationPreMobius.GetVariableNameAt(const Index: integer): string;
begin
case Index of
0: Result := 'pre_mobius_Re_A';
1: Result := 'pre_mobius_Im_A';
2: Result := 'pre_mobius_Re_B';
3: Result := 'pre_mobius_Im_B';
4: Result := 'pre_mobius_Re_C';
5: Result := 'pre_mobius_Im_C';
6: Result := 'pre_mobius_Re_D';
7: Result := 'pre_mobius_Im_D';
8: Result := 'pre_mobius_invert';
else
Result := '';
end
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationPreMobius.SetVariable(const Name: string; var value: double): boolean;
begin
Result := False;
if Name = 'pre_mobius_Re_A' then begin
Re_A := Value;
Result := True;
end else if Name = 'pre_mobius_Im_A' then begin
Im_A := Value;
Result := True;
end else if Name = 'pre_mobius_Re_B' then begin
Re_B := Value;
Result := True;
end else if Name = 'pre_mobius_Im_B' then begin
Im_B := Value;
Result := True;
end else if Name = 'pre_mobius_Re_C' then begin
Re_C := Value;
Result := True;
end else if Name = 'pre_mobius_Im_C' then begin
Im_C := Value;
Result := True;
end else if Name = 'pre_mobius_Re_D' then begin
Re_D := Value;
Result := True;
end else if Name = 'pre_mobius_Im_D' then begin
Im_D := Value;
Result := True;
end else if Name = 'pre_mobius_invert' then begin
if (Value > 1) then Value := 1;
if (Value < 0) then Value := 0;
mobius_invert := Round(Value);
Result := True;
end
end;
function TVariationPreMobius.ResetVariable(const Name: string): boolean;
begin
Result := False;
if Name = 'pre_mobius_Re_A' then begin
Re_A := 1;
Result := True;
end else if Name = 'pre_mobius_Im_A' then begin
Im_A := 0;
Result := True;
end else if Name = 'pre_mobius_Re_B' then begin
Re_B := 0;
Result := True;
end else if Name = 'pre_mobius_Im_B' then begin
Im_B := 0;
Result := True;
end else if Name = 'pre_mobius_Re_C' then begin
Re_C := 0;
Result := True;
end else if Name = 'pre_mobius_Im_C' then begin
Im_C := 0;
Result := True;
end else if Name = 'pre_mobius_Re_D' then begin
Re_D := 1;
Result := True;
end else if Name = 'pre_mobius_Im_D' then begin
Im_D := 0;
Result := True;
end else if Name = 'pre_mobius_invert' then begin
mobius_invert := 0;
Result := True;
end
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationPreMobius.GetNrVariables: integer;
begin
Result := 9
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationPreMobius.GetVariable(const Name: string; var value: double): boolean;
begin
Result := False;
if Name = 'pre_mobius_Re_A' then begin
Value := Re_A;
Result := True;
end else if Name = 'pre_mobius_Im_A' then begin
Value := Im_A;
Result := True;
end else if Name = 'pre_mobius_Re_B' then begin
Value := Re_B;
Result := True;
end else if Name = 'pre_mobius_Im_B' then begin
Value := Im_B;
Result := True;
end else if Name = 'pre_mobius_Re_C' then begin
Value := Re_C;
Result := True;
end else if Name = 'pre_mobius_Im_C' then begin
Value := Im_C;
Result := True;
end else if Name = 'pre_mobius_Re_D' then begin
Value := Re_D;
Result := True;
end else if Name = 'pre_mobius_Im_D' then begin
Value := Im_D;
Result := True;
end else if Name = 'pre_mobius_invert' then begin
Value := mobius_invert;
Result := True;
end
end;
///////////////////////////////////////////////////////////////////////////////
initialization
RegisterVariation(TVariationClassLoader.Create(TVariationPreMobius), false, false);
end.

View File

@ -29,8 +29,7 @@ interface
uses
BaseVariation, XFormMan;
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
{$define _ASM_}
{$endif}

View File

@ -28,8 +28,7 @@ interface
uses
BaseVariation, XFormMan;
{$ifdef Apo7X64}
{$else}
{$ifdef CPUX86}
{$define _ASM_}
{$endif}

View File

@ -40,7 +40,7 @@ procedure TVariationTanhSpiral.CalcFunction;
var
t, aux, sn, cn, snh, cnh: double;
begin
t := (random - 0.5) * 6.28318530717959;
t := (random - 0.5) * PI2;
SinCos(ta * t, sn, cn);
SinhCosh(t, snh, cnh);