--User changes

-Add a palette editor.
 -Add support for reading .ugr/.gradient/.gradients palette files.
 -Allow toggling on spinners whose minimum value is not zero.
 -Allow toggling display of image, affines and grid.
 -Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.

--Bug fixes
 -cpow2 was wrong.
 -Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
 -Use exec() on Apple and show() on all other OSes for dialog boxes.
 -Trying to render a sequence with no frames would crash.
 -Selecting multiple xforms and rotating them would produce the wrong rotation.
 -Better handling when parsing flames using different encoding, such as unicode and UTF-8.
 -Switching between SP/DP didn't reselect the selected flame in the Library tab.

--Code changes
 -Make all types concerning palettes be floats, including PaletteTableWidgetItem.
 -PaletteTableWidgetItem is no longer templated because all palettes are float.
 -Include the source colors for user created gradients.
 -Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
 -Split conditional out of accumulation loop on the CPU for better performance.
 -Vectorize summing when doing density filter for better performance.
 -Make all usage of palettes be of type float, double is pointless.
 -Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
 -Refactor some palette path searching code.
 -Make ReadFile() throw and catch an exception if the file operation fails.
 -A little extra safety in foci and foci3D with a call to Zeps().
 -Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
 -Fixing missing comma between paths in InitPaletteList().
 -Move Xml and PaletteList classes into cpp to shorten build times when working on them.
 -Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
 -Change more NULL to nullptr.
This commit is contained in:
Person 2017-02-26 00:02:21 -08:00
parent 8a75d5d227
commit 8a4127d5d7
102 changed files with 242668 additions and 3713 deletions

7
.gitignore vendored
View File

@ -18,8 +18,6 @@
*.ipch
*.bsc
*.exe
*.xml
!./Data/flam3-palettes.xml
*.ilk
*.wixobj
*.pch
@ -85,3 +83,8 @@ Builds/lib/libOpenCL.so
Builds/include/CL
Builds/include/GL
/Data/Variations Bench.xlsx
/Builds/QtCreator/EmberCL/EmberCL.pro.user.18
/Builds/QtCreator/Ember/Ember.pro.user.18
/Builds/QtCreator/Fractorium/Fractorium.pro.user.18
/Builds/MSVC/VS2013/flam3-palettes.xml
/Builds/MSVC/VS2015/flam3-palettes.xml

View File

@ -1,189 +1,249 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define ProductVersion="1.0.0.2" ?>
<?define ProductName="Fractorium $(var.ProductVersion) ($(var.GpuType))" ?>
<?define UpgradeCode="{4714cd15-bfba-44f6-8059-9e1466ebfa6e}"?>
<?define Manufacturer="Fractorium"?>
<!--
Original GUID,
<?define ProductCode="{703001af-6255-4671-9a69-571198b4c0dd}"?>
-->
<?define ProductVersion="1.0.0.2" ?>
<?define ProductName="Fractorium $(var.ProductVersion) ($(var.GpuType))" ?>
<?define UpgradeCode="{4714cd15-bfba-44f6-8059-9e1466ebfa6e}"?>
<?define Manufacturer="Fractorium"?>
<!--
Original GUID,
<?define ProductCode="{703001af-6255-4671-9a69-571198b4c0dd}"?>
-->
<!--
Change this for every release.
-->
<?define ProductCode="{08AE2B75-565F-4E0D-A1A0-C7A5ED1CA2C1}"?>
<Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
<Package
Keywords="Installer"
Platform="x64"
Description="$(var.Manufacturer)"
Comments="$(var.Manufacturer)"
Manufacturer="$(var.Manufacturer)"
InstallScope="perUser"
InstallerVersion="400"
InstallPrivileges="limited"
Compressed="yes"
Languages="1033"
SummaryCodepage="1252"
/>
<!--
Change this for every release.
-->
<?define ProductCode="{08AE2B75-565F-4E0D-A1A0-C7A5ED1CA2C1}"?>
<Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
<Package
Keywords="Installer"
Platform="x64"
Description="$(var.Manufacturer)"
Comments="$(var.Manufacturer)"
Manufacturer="$(var.Manufacturer)"
InstallScope="perUser"
InstallerVersion="400"
InstallPrivileges="limited"
Compressed="yes"
Languages="1033"
SummaryCodepage="1252"
/>
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Minimum="0.0.0"
IncludeMinimum="no"
OnlyDetect="no"
Maximum="$(var.ProductVersion)"
IncludeMaximum="no"
Property="PREVIOUSFOUND" />
</Upgrade>
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Minimum="0.0.0"
IncludeMinimum="no"
OnlyDetect="no"
Maximum="$(var.ProductVersion)"
IncludeMaximum="no"
Property="PREVIOUSFOUND" />
</Upgrade>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize"/>
</InstallExecuteSequence>
<MediaTemplate EmbedCab="yes" />
<Icon Id="AddRemoveProgramsIcon" SourceFile="$(var.SolutionDir)..\..\..\Source\Fractorium\Icons\Fractorium.ico"/>
<Property Id="ARPPRODUCTICON" Value="AddRemoveProgramsIcon" />
<Feature Id="MainApplication" Title="Main Application" Level="1">
<ComponentGroupRef Id="ProductComponents" />
<ComponentGroupRef Id="PlatformComponents" />
<ComponentRef Id="FractoriumStartMenuShortcut"/>
<ComponentRef Id="FractoriumDesktopShortcut"/>
</Feature>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize"/>
</InstallExecuteSequence>
<MediaTemplate EmbedCab="yes" />
<Icon Id="AddRemoveProgramsIcon" SourceFile="$(var.SolutionDir)..\..\..\Source\Fractorium\Icons\Fractorium.ico"/>
<Property Id="ARPPRODUCTICON" Value="AddRemoveProgramsIcon" />
<Feature Id="MainApplication" Title="Main Application" Level="1">
<ComponentGroupRef Id="ProductComponents" />
<ComponentGroupRef Id="PlatformComponents" />
<ComponentRef Id="FractoriumStartMenuShortcut"/>
<ComponentRef Id="FractoriumDesktopShortcut"/>
</Feature>
<WixVariable Id="WixUILicenseRtf" Value="$(var.SolutionDir)..\..\..\Data\gplv3.rtf" />
<WixVariable Id="WixUIBannerBmp" Value="$(var.SolutionDir)..\..\..\Source\Fractorium\Icons\banner.bmp" /><!--493 x 58 pixels -->
<WixVariable Id="WixUIDialogBmp" Value="$(var.SolutionDir)..\..\..\Source\Fractorium\Icons\dialog.bmp" /><!--493 × 312 pixels -->
<Property Id="MSIUSEREALADMINDETECTION" Value="1" />
<Property Id="MSIFASTINSTALL" Value="1" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<UIRef Id="WixUI_InstallDir" />
<UIRef Id="WixUI_ErrorProgressText" />
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir" >
<!-- Doing this requires admin access, so we don't do it.
<Directory Id="ProgramFiles64Folder" >
<Directory Id="INSTALLFOLDER" Name="Fractorium" >
<Directory Id="INSTALLFOLDERPLATFORMS" Name="platforms" />
</Directory>
</Directory>
-->
<WixVariable Id="WixUILicenseRtf" Value="$(var.SolutionDir)..\..\..\Data\gplv3.rtf" />
<WixVariable Id="WixUIBannerBmp" Value="$(var.SolutionDir)..\..\..\Source\Fractorium\Icons\banner.bmp" /><!--493 x 58 pixels -->
<WixVariable Id="WixUIDialogBmp" Value="$(var.SolutionDir)..\..\..\Source\Fractorium\Icons\dialog.bmp" /><!--493 × 312 pixels -->
<Property Id="MSIUSEREALADMINDETECTION" Value="1" />
<Property Id="MSIFASTINSTALL" Value="1" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<UIRef Id="WixUI_InstallDir" />
<UIRef Id="WixUI_ErrorProgressText" />
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir" >
<!-- Doing this requires admin access, so we don't do it.
<Directory Id="ProgramFiles64Folder" >
<Directory Id="INSTALLFOLDER" Name="Fractorium" >
<Directory Id="INSTALLFOLDERPLATFORMS" Name="platforms" />
</Directory>
</Directory>
-->
<!-- Doing this doesn't require admin access.
It reports a ton of errors, but oddly enough, an MSI is still created with the errors.
-->
<Directory Id="AppDataFolder" >
<Directory Id="INSTALLFOLDER" Name="Fractorium" >
<Directory Id="INSTALLFOLDERPLATFORMS" Name="platforms" />
</Directory>
</Directory>
<!-- Shortcut folders-->
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="ProgramMenuDirLevel1" Name="Fractorium" />
</Directory>
<Directory Id="DesktopFolder" Name="Desktop" />
</Directory>
</Fragment>
<!-- Doing this doesn't require admin access.
It reports a ton of errors, but oddly enough, an MSI is still created with the errors.
-->
<Directory Id="AppDataFolder" >
<Directory Id="INSTALLFOLDER" Name="Fractorium" >
<Directory Id="INSTALLFOLDERPLATFORMS" Name="platforms" />
</Directory>
</Directory>
<!-- Shortcut folders-->
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="ProgramMenuDirLevel1" Name="Fractorium" />
</Directory>
<Directory Id="DesktopFolder" Name="Desktop" />
</Directory>
</Fragment>
<Fragment>
<Component Id="FractoriumStartMenuShortcut" Directory="ProgramMenuDirLevel1" Guid="f1eaf3ba-9b61-48b6-8994-49ebc6b405aa">
<Shortcut Id="FractoriumStartMenuShortcut"
Directory="ProgramMenuDirLevel1"
Name="Fractorium"
Target="[INSTALLFOLDER]\Fractorium.exe"
WorkingDirectory="INSTALLFOLDER"
Icon="AddRemoveProgramsIcon"
/>
<Condition>1</Condition>
<RemoveFolder Id="FractoriumStartMenuShortcut" On="uninstall" />
<RegistryValue Root='HKCU' Key='Software\[Manufacturer]\[ProductName]' Type='string' Value='' KeyPath='yes' />
</Component>
<Component Id="FractoriumDesktopShortcut" Directory="DesktopFolder" Guid="b73ff21c-08ac-47ad-a510-b3ce90e43979">
<Shortcut Id="FractoriumDesktopShortcut"
Directory="DesktopFolder"
Name="Fractorium"
Target="[INSTALLFOLDER]\Fractorium.exe"
WorkingDirectory="INSTALLFOLDER"
Icon="AddRemoveProgramsIcon"
/>
<RemoveFolder Id="FractoriumDesktopShortcut" On="uninstall" />
<Condition>1</Condition>
<RegistryValue Root='HKCU' Key='Software\[Manufacturer]\[ProductName]' Type='string' Value='' KeyPath='yes' />
</Component>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="Fractorium.exe" Guid="ccc04ca4-c747-4330-8cfd-bdd943b185c0">
<File Id="Fractorium.exe" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\$(var.Configuration)\Fractorium.exe" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64" />
</Component>
<Component Id="EmberRender.exe" Guid="12d49219-9269-495a-b8e4-3d33cb32d280">
<File Id="EmberRender.exe" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\$(var.Configuration)\EmberRender.exe" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64" />
</Component>
<Component Id="EmberAnimate.exe" Guid="ae362704-93a3-48dc-a13b-7c4eabd87ee1">
<File Id="EmberAnimate.exe" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\$(var.Configuration)\EmberAnimate.exe" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64" />
</Component>
<Component Id="EmberGenome.exe" Guid="7a93f079-216a-4d1c-9b02-8ca93a6a8daa">
<File Id="EmberGenome.exe" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\$(var.Configuration)\EmberGenome.exe" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64" />
</Component>
<Component Id="Ember.dll" Guid="c0f80dee-7a16-4d6a-b7ed-d6cd162154eb">
<File Id="Ember.dll" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\$(var.Configuration)\Ember.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
<Component Id="EmberCL.dll" Guid="21c0e372-c605-4e0d-9ba8-94e38949833b">
<File Id="EmberCL.dll" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\$(var.Configuration)\EmberCL.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
<Component Id="libxml2.dll" Guid="bb3aa687-7a3d-4d16-a27c-28529b472754">
<File Id="libxml2.dll" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\Release\libxml2.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
<Component Id="tbb.dll" Guid="ffa1b2ec-32d5-41aa-9380-fb04d8139103">
<File Id="tbb.dll" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\Release\tbb.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
<Component Id="msvcp140.dll" Guid="8f1ffde7-c1bd-45fb-8bc8-26dde552eafd">
<File Id="msvcp140.dll" Source="$(env.VS140COMNTOOLS)..\..\VC\redist\x64\Microsoft.VC140.CRT\msvcp140.dll" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="vcruntime140.dll" Guid="50c9bc27-c547-4a03-9f6c-cd416f449dd8">
<File Id="vcruntime140.dll" Source="$(env.VS140COMNTOOLS)..\..\VC\redist\x64\Microsoft.VC140.CRT\vcruntime140.dll" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="vccorlib140.dll" Guid="affe33e7-1e64-4bb0-a062-2b56f77459b4">
<File Id="vccorlib140.dll" Source="$(env.VS140COMNTOOLS)..\..\VC\redist\x64\Microsoft.VC140.CRT\vccorlib140.dll" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="concrt140.dll" Guid="7fb716a1-1b4f-42fb-89c7-4d216ebd6e2e">
<File Id="concrt140.dll" Source="$(env.VS140COMNTOOLS)..\..\VC\redist\x64\Microsoft.VC140.CRT\concrt140.dll" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="flam3palettes.xml" Guid="d3adb0bb-14ef-4923-99d9-a5784b7ef04e">
<File Id="flam3palettes.xml" Source="$(var.SolutionDir)..\..\..\Data\flam3-palettes.xml" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="dark.qss" Guid="c120ace3-5fab-416f-b7f1-a8d9e3e0f061">
<File Id="dark.qss" Source="$(var.SolutionDir)..\..\..\Data\dark.qss" KeyPath="yes" Checksum="yes" ReadOnly="yes"/>
</Component>
<Component Id="VersionHistory.txt" Guid="8b031217-9e7d-4700-9ab8-2593a4e002b6">
<File Id="VersionHistory.txt" Source="$(var.SolutionDir)..\..\..\Data\Version History.txt" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="Qt5Core.dll" Guid="0198dd4b-9bbb-4ea2-86e3-6ea0f4f6ac51">
<File Id="Qt5Core.dll" Source="$(env.QTDIR)\bin\Qt5Core.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
<Component Id="Qt5Gui.dll" Guid="7f93dcc2-55db-4920-83d7-e06c23f7719a">
<File Id="Qt5Gui.dll" Source="$(env.QTDIR)\bin\Qt5Gui.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
<Component Id="Qt5Widgets.dll" Guid="006bb2f1-7a38-426f-ba2c-5196d1d6c24d">
<File Id="Qt5Widgets.dll" Source="$(env.QTDIR)\bin\Qt5Widgets.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
</ComponentGroup>
</Fragment>
<Fragment>
<ComponentGroup Id="PlatformComponents" Directory="INSTALLFOLDERPLATFORMS">
<Component Id="qwindows.dll" Guid="627b7f5a-8fa6-4c78-a6b7-81fcdd8fdd63">
<File Id="qwindows.dll" Source="$(env.QTDIR)\plugins\platforms\qwindows.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
</ComponentGroup>
</Fragment>
<Fragment>
<Component Id="FractoriumStartMenuShortcut" Directory="ProgramMenuDirLevel1" Guid="f1eaf3ba-9b61-48b6-8994-49ebc6b405aa">
<Shortcut Id="FractoriumStartMenuShortcut"
Directory="ProgramMenuDirLevel1"
Name="Fractorium"
Target="[INSTALLFOLDER]\Fractorium.exe"
WorkingDirectory="INSTALLFOLDER"
Icon="AddRemoveProgramsIcon"
/>
<Condition>1</Condition>
<RemoveFolder Id="FractoriumStartMenuShortcut" On="uninstall" />
<RegistryValue Root='HKCU' Key='Software\[Manufacturer]\[ProductName]' Type='string' Value='' KeyPath='yes' />
</Component>
<Component Id="FractoriumDesktopShortcut" Directory="DesktopFolder" Guid="b73ff21c-08ac-47ad-a510-b3ce90e43979">
<Shortcut Id="FractoriumDesktopShortcut"
Directory="DesktopFolder"
Name="Fractorium"
Target="[INSTALLFOLDER]\Fractorium.exe"
WorkingDirectory="INSTALLFOLDER"
Icon="AddRemoveProgramsIcon"
/>
<RemoveFolder Id="FractoriumDesktopShortcut" On="uninstall" />
<Condition>1</Condition>
<RegistryValue Root='HKCU' Key='Software\[Manufacturer]\[ProductName]' Type='string' Value='' KeyPath='yes' />
</Component>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="Fractorium.exe" Guid="ccc04ca4-c747-4330-8cfd-bdd943b185c0">
<File Id="Fractorium.exe" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\$(var.Configuration)\Fractorium.exe" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64" />
</Component>
<Component Id="EmberRender.exe" Guid="12d49219-9269-495a-b8e4-3d33cb32d280">
<File Id="EmberRender.exe" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\$(var.Configuration)\EmberRender.exe" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64" />
</Component>
<Component Id="EmberAnimate.exe" Guid="ae362704-93a3-48dc-a13b-7c4eabd87ee1">
<File Id="EmberAnimate.exe" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\$(var.Configuration)\EmberAnimate.exe" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64" />
</Component>
<Component Id="EmberGenome.exe" Guid="7a93f079-216a-4d1c-9b02-8ca93a6a8daa">
<File Id="EmberGenome.exe" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\$(var.Configuration)\EmberGenome.exe" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64" />
</Component>
<Component Id="Ember.dll" Guid="c0f80dee-7a16-4d6a-b7ed-d6cd162154eb">
<File Id="Ember.dll" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\$(var.Configuration)\Ember.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
<Component Id="EmberCL.dll" Guid="21c0e372-c605-4e0d-9ba8-94e38949833b">
<File Id="EmberCL.dll" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\$(var.Configuration)\EmberCL.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
<Component Id="libxml2.dll" Guid="bb3aa687-7a3d-4d16-a27c-28529b472754">
<File Id="libxml2.dll" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\Release\libxml2.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
<Component Id="tbb.dll" Guid="ffa1b2ec-32d5-41aa-9380-fb04d8139103">
<File Id="tbb.dll" Source="$(var.SolutionDir)..\..\..\Bin\$(var.Platform)\Release\tbb.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
<Component Id="msvcp140.dll" Guid="8f1ffde7-c1bd-45fb-8bc8-26dde552eafd">
<File Id="msvcp140.dll" Source="$(env.VS140COMNTOOLS)..\..\VC\redist\x64\Microsoft.VC140.CRT\msvcp140.dll" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="vcruntime140.dll" Guid="50c9bc27-c547-4a03-9f6c-cd416f449dd8">
<File Id="vcruntime140.dll" Source="$(env.VS140COMNTOOLS)..\..\VC\redist\x64\Microsoft.VC140.CRT\vcruntime140.dll" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="vccorlib140.dll" Guid="affe33e7-1e64-4bb0-a062-2b56f77459b4">
<File Id="vccorlib140.dll" Source="$(env.VS140COMNTOOLS)..\..\VC\redist\x64\Microsoft.VC140.CRT\vccorlib140.dll" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="concrt140.dll" Guid="7fb716a1-1b4f-42fb-89c7-4d216ebd6e2e">
<File Id="concrt140.dll" Source="$(env.VS140COMNTOOLS)..\..\VC\redist\x64\Microsoft.VC140.CRT\concrt140.dll" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="flam3palettes.xml" Guid="d3adb0bb-14ef-4923-99d9-a5784b7ef04e">
<File Id="flam3palettes.xml" Source="$(var.SolutionDir)..\..\..\Data\flam3-palettes.xml" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="userpalettes.xml" Guid="53e1e43e-b01e-4159-94fa-bdf6e8fd1d57">
<File Id="userpalettes.xml" Source="$(var.SolutionDir)..\..\..\Data\user-palettes.xml" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="boxtail_pack_02.gradient" Guid="f9bd8f21-6a61-4e4a-a7e6-bc50f2633dd6">
<File Id="boxtail_pack_02.gradient" Source="$(var.SolutionDir)..\..\..\Data\boxtail_pack_02.gradient" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="boxtail_pack_03_triangle.gradient" Guid="19d4957a-7ce7-4afd-b74b-5049265dffa2">
<File Id="boxtail_pack_03_triangle.gradient" Source="$(var.SolutionDir)..\..\..\Data\boxtail_pack_03_triangle.gradient" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="boxtail_pack_04_mineshack.gradient" Guid="2f144d87-97bd-4fe6-8000-f0a9e62f770f">
<File Id="boxtail_pack_04_mineshack.gradient" Source="$(var.SolutionDir)..\..\..\Data\boxtail_pack_04_mineshack.gradient" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="fardareismai_pack_01_variety_number_128.gradient" Guid="9ee0a298-b35b-4501-9beb-c0cdca41ca25">
<File Id="fardareismai_pack_01_variety_number_128.gradient" Source="$(var.SolutionDir)..\..\..\Data\fardareismai_pack_01_variety_number_128.gradient" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="fardareismai_pack_02_b_sides.gradient" Guid="69e0c7d9-283b-4161-a924-b015eb658e8d">
<File Id="fardareismai_pack_02_b_sides.gradient" Source="$(var.SolutionDir)..\..\..\Data\fardareismai_pack_02_b_sides.gradient" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="fardareismai_pack_03_old_and_new.gradient" Guid="1059241b-67e7-4a36-878d-675f3282c530">
<File Id="fardareismai_pack_03_old_and_new.gradient" Source="$(var.SolutionDir)..\..\..\Data\fardareismai_pack_03_old_and_new.gradient" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="fardareismai_pack_04_hoard.gradient" Guid="c611ee88-e0f4-493b-84f5-c65f899d43f3">
<File Id="fardareismai_pack_04_hoard.gradient" Source="$(var.SolutionDir)..\..\..\Data\fardareismai_pack_04_hoard.gradient" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="fractaldesire_pack_01.gradient" Guid="9f0885ab-920f-420d-a962-9bc515986701">
<File Id="fractaldesire_pack_01.gradient" Source="$(var.SolutionDir)..\..\..\Data\fractaldesire_pack_01.gradient" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="rce_ordinary_pack_01_colornation.gradient" Guid="8eb62cb8-279b-4518-9098-c0fec5830493">
<File Id="rce_ordinary_pack_01_colornation.gradient" Source="$(var.SolutionDir)..\..\..\Data\rce_ordinary_pack_01_colornation.gradient" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="tatasz_pack_01.gradient" Guid="967c9577-74d1-4bc0-aa52-2fb78507b572">
<File Id="tatasz_pack_01.gradient" Source="$(var.SolutionDir)..\..\..\Data\tatasz_pack_01.gradient" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="tatasz_pack_02_colder.gradient" Guid="304976a2-8ae7-47eb-bf1f-c6f3cbe380b8">
<File Id="tatasz_pack_02_colder.gradient" Source="$(var.SolutionDir)..\..\..\Data\tatasz_pack_02_colder.gradient" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="tatasz_pack_02_dark.gradient" Guid="05ed49cf-364c-4547-a107-2bd46afc6664">
<File Id="tatasz_pack_02_dark.gradient" Source="$(var.SolutionDir)..\..\..\Data\tatasz_pack_02_dark.gradient" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="tatasz_pack_02_warmer.gradient" Guid="62282580-0ae3-484e-98ba-38ec7bbf80e2">
<File Id="tatasz_pack_02_warmer.gradient" Source="$(var.SolutionDir)..\..\..\Data\tatasz_pack_02_warmer.gradient" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="tatasz_pack_03.gradient" Guid="7e5b5ef3-45be-4807-a88f-a8b773663e77">
<File Id="tatasz_pack_03.gradient" Source="$(var.SolutionDir)..\..\..\Data\tatasz_pack_03.gradient" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="dark.qss" Guid="c120ace3-5fab-416f-b7f1-a8d9e3e0f061">
<File Id="dark.qss" Source="$(var.SolutionDir)..\..\..\Data\dark.qss" KeyPath="yes" Checksum="yes" ReadOnly="yes"/>
</Component>
<Component Id="VersionHistory.txt" Guid="8b031217-9e7d-4700-9ab8-2593a4e002b6">
<File Id="VersionHistory.txt" Source="$(var.SolutionDir)..\..\..\Data\Version History.txt" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="Qt5Core.dll" Guid="0198dd4b-9bbb-4ea2-86e3-6ea0f4f6ac51">
<File Id="Qt5Core.dll" Source="$(env.QTDIR)\bin\Qt5Core.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
<Component Id="Qt5Gui.dll" Guid="7f93dcc2-55db-4920-83d7-e06c23f7719a">
<File Id="Qt5Gui.dll" Source="$(env.QTDIR)\bin\Qt5Gui.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
<Component Id="Qt5Widgets.dll" Guid="006bb2f1-7a38-426f-ba2c-5196d1d6c24d">
<File Id="Qt5Widgets.dll" Source="$(env.QTDIR)\bin\Qt5Widgets.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
</ComponentGroup>
</Fragment>
<Fragment>
<ComponentGroup Id="PlatformComponents" Directory="INSTALLFOLDERPLATFORMS">
<Component Id="qwindows.dll" Guid="627b7f5a-8fa6-4c78-a6b7-81fcdd8fdd63">
<File Id="qwindows.dll" Source="$(env.QTDIR)\plugins\platforms\qwindows.dll" KeyPath="yes" Checksum="yes" ProcessorArchitecture="x64"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>

View File

@ -69,6 +69,7 @@
<FloatingPointExceptions>false</FloatingPointExceptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -153,9 +154,12 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\Source\Ember\EmberToXml.cpp" />
<ClCompile Include="..\..\..\Source\Ember\PaletteList.cpp" />
<ClCompile Include="..\..\..\Source\Ember\Renderer.cpp" />
<ClCompile Include="..\..\..\Source\Ember\RendererBase.cpp" />
<ClCompile Include="..\..\..\Source\Ember\VariationList.cpp" />
<ClCompile Include="..\..\..\Source\Ember\XmlToEmber.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Ember.rc" />

View File

@ -151,6 +151,15 @@
<ClCompile Include="..\..\..\Source\Ember\VariationList.cpp">
<Filter>Header Files\Variations</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Ember\EmberToXml.cpp">
<Filter>Header Files\Xml</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Ember\XmlToEmber.cpp">
<Filter>Header Files\Xml</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Ember\PaletteList.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Ember.rc">

View File

@ -66,6 +66,7 @@
<MinimalRebuild>false</MinimalRebuild>
<StringPooling>true</StringPooling>
<FloatingPointExceptions>false</FloatingPointExceptions>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>

View File

@ -67,6 +67,7 @@
<MinimalRebuild>false</MinimalRebuild>
<StringPooling>true</StringPooling>
<FloatingPointExceptions>false</FloatingPointExceptions>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>

View File

@ -66,6 +66,7 @@
<MinimalRebuild>false</MinimalRebuild>
<StringPooling>true</StringPooling>
<FloatingPointExceptions>false</FloatingPointExceptions>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>

View File

@ -66,6 +66,7 @@
<MinimalRebuild>false</MinimalRebuild>
<StringPooling>true</StringPooling>
<FloatingPointExceptions>false</FloatingPointExceptions>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>

View File

@ -66,6 +66,7 @@
<MinimalRebuild>false</MinimalRebuild>
<StringPooling>true</StringPooling>
<FloatingPointExceptions>false</FloatingPointExceptions>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>

View File

@ -48,10 +48,16 @@
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)Obj\$(TargetName)\$(Platform)\$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)Obj\$(TargetName)\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>UNICODE;WIN32;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_MULTIMEDIA_LIB;QT_HELP_LIB;QT_OPENGL_LIB;QT_WIDGETS_LIB;QT_XML_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>.;$(QTDIR)\include;$(ProjectDir)..\..\..\Fractorium\GeneratedFiles;$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName;$(QTDIR)\..\qtmultimedia\include\QtMultimedia;$(QTDIR)\..\qtmultimedia\include;$(QTDIR)\..\qttools\include;$(QTDIR)\..\qttools\include\QtHelp;$(QTDIR)\include\QtConcurrent;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtOpenGL;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtXml;.\GeneratedFiles;$(ProjectDir)..\..\..\Source\Ember;$(ProjectDir)..\..\..\Source\EmberCL;$(ProjectDir)..\..\..\Source\EmberCommon;$(ProjectDir)..\..\..\..\glm;$(ProjectDir)..\..\..\..\tbb\include;$(ProjectDir)..\..\..\..\libjpeg;$(ProjectDir)..\..\..\..\libpng;$(ProjectDir)..\..\..\..\libxml2\include;$(AMDAPPSDKROOT)\include;$(CUDA_PATH)\include;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>.;.\PaletteEditor;$(QTDIR)\include;$(ProjectDir)..\..\..\Fractorium\GeneratedFiles;$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName;$(QTDIR)\..\qtmultimedia\include\QtMultimedia;$(QTDIR)\..\qtmultimedia\include;$(QTDIR)\..\qttools\include;$(QTDIR)\..\qttools\include\QtHelp;$(QTDIR)\include\QtConcurrent;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtOpenGL;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtXml;.\GeneratedFiles;$(ProjectDir)..\..\..\Source\Ember;$(ProjectDir)..\..\..\Source\EmberCL;$(ProjectDir)..\..\..\Source\EmberCommon;$(ProjectDir)..\..\..\Source\Fractorium;$(ProjectDir)..\..\..\..\glm;$(ProjectDir)..\..\..\..\tbb\include;$(ProjectDir)..\..\..\..\libjpeg;$(ProjectDir)..\..\..\..\libpng;$(ProjectDir)..\..\..\..\libxml2\include;$(AMDAPPSDKROOT)\include;$(CUDA_PATH)\include;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>Disabled</Optimization>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@ -67,6 +73,7 @@
<StringPooling>true</StringPooling>
<FloatingPointExceptions>false</FloatingPointExceptions>
<WarningLevel>Level3</WarningLevel>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -91,7 +98,7 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindowsd.dll" "$(OutDir)\platform
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>UNICODE;WIN32;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_MULTIMEDIA_LIB;QT_HELP_LIB;QT_OPENGL_LIB;QT_WIDGETS_LIB;QT_XML_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>.;$(QTDIR)\include;$(ProjectDir)..\..\..\Fractorium\GeneratedFiles;$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName;$(QTDIR)\..\qtmultimedia\include\QtMultimedia;$(QTDIR)\..\qtmultimedia\include;$(QTDIR)\..\qttools\include;$(QTDIR)\..\qttools\include\QtHelp;$(QTDIR)\include\QtConcurrent;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtOpenGL;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtXml;.\GeneratedFiles;$(ProjectDir)..\..\..\Source\Ember;$(ProjectDir)..\..\..\Source\EmberCL;$(ProjectDir)..\..\..\Source\EmberCommon;$(ProjectDir)..\..\..\..\glm;$(ProjectDir)..\..\..\..\tbb\include;$(ProjectDir)..\..\..\..\libjpeg;$(ProjectDir)..\..\..\..\libpng;$(ProjectDir)..\..\..\..\libxml2\include;$(AMDAPPSDKROOT)\include;$(CUDA_PATH)\include;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>.;.\PaletteEditor;$(QTDIR)\include;$(ProjectDir)..\..\..\Fractorium\GeneratedFiles;$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName;$(QTDIR)\..\qtmultimedia\include\QtMultimedia;$(QTDIR)\..\qtmultimedia\include;$(QTDIR)\..\qttools\include;$(QTDIR)\..\qttools\include\QtHelp;$(QTDIR)\include\QtConcurrent;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtOpenGL;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtXml;.\GeneratedFiles;$(ProjectDir)..\..\..\Source\Ember;$(ProjectDir)..\..\..\Source\EmberCL;$(ProjectDir)..\..\..\Source\EmberCommon;$(ProjectDir)..\..\..\Source\Fractorium;$(ProjectDir)..\..\..\..\glm;$(ProjectDir)..\..\..\..\tbb\include;$(ProjectDir)..\..\..\..\libjpeg;$(ProjectDir)..\..\..\..\libpng;$(ProjectDir)..\..\..\..\libxml2\include;$(AMDAPPSDKROOT)\include;$(CUDA_PATH)\include;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
@ -162,6 +169,11 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindows.dll" "$(OutDir)\platforms
<ClCompile Include="..\..\..\Source\Fractorium\main.cpp" />
<ClCompile Include="..\..\..\Source\Fractorium\DoubleSpinBox.cpp" />
<ClCompile Include="..\..\..\Source\Fractorium\OptionsDialog.cpp" />
<ClCompile Include="..\..\..\Source\Fractorium\PaletteEditor\ColorPanel.cpp" />
<ClCompile Include="..\..\..\Source\Fractorium\PaletteEditor\ColorPickerWidget.cpp" />
<ClCompile Include="..\..\..\Source\Fractorium\PaletteEditor\ColorTriangle.cpp" />
<ClCompile Include="..\..\..\Source\Fractorium\PaletteEditor\GradientColorsView.cpp" />
<ClCompile Include="..\..\..\Source\Fractorium\PaletteEditor\PaletteEditor.cpp" />
<ClCompile Include="..\..\..\Source\Fractorium\qcssparser.cpp" />
<ClCompile Include="..\..\..\Source\Fractorium\qcssscanner.cpp" />
<ClCompile Include="..\..\..\Source\Fractorium\QssDialog.cpp" />
@ -175,6 +187,15 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindows.dll" "$(OutDir)\platforms
<ClCompile Include="GeneratedFiles\Debug\moc_AboutDialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_ColorPanel.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_ColorPickerWidget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_ColorTriangle.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_csshighlighter.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
@ -199,12 +220,18 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindows.dll" "$(OutDir)\platforms
<ClCompile Include="GeneratedFiles\Debug\moc_GLWidget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_GradientColorsView.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_LibraryTreeWidget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_OptionsDialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_PaletteEditor.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_QssDialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
@ -235,6 +262,15 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindows.dll" "$(OutDir)\platforms
<ClCompile Include="GeneratedFiles\Release\moc_AboutDialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_ColorPanel.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_ColorPickerWidget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_ColorTriangle.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_csshighlighter.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
@ -259,12 +295,18 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindows.dll" "$(OutDir)\platforms
<ClCompile Include="GeneratedFiles\Release\moc_GLWidget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_GradientColorsView.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_LibraryTreeWidget.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_OptionsDialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_PaletteEditor.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_QssDialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
@ -291,30 +333,30 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindows.dll" "$(OutDir)\platforms
<CustomBuild Include="..\..\..\Source\Fractorium\VariationsDialog.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing VariationsDialog.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/VariationsDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/VariationsDialog.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing VariationsDialog.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/VariationsDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/VariationsDialog.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\QssDialog.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing QssDialog.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssDialog.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing QssDialog.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssDialog.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\csshighlighter.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing csshighlighter.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/csshighlighter.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/csshighlighter.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing csshighlighter.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/csshighlighter.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/csshighlighter.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
@ -322,53 +364,105 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindows.dll" "$(OutDir)\platforms
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing LibraryTreeWidget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/LibraryTreeWidget.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/LibraryTreeWidget.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing LibraryTreeWidget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/LibraryTreeWidget.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/LibraryTreeWidget.h"</Command>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\PaletteEditor\ColorPanel.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing ColorPanel.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/PaletteEditor/ColorPanel.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing ColorPanel.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/PaletteEditor/ColorPanel.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\PaletteEditor\ColorPickerWidget.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing ColorPickerWidget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/PaletteEditor/ColorPickerWidget.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing ColorPickerWidget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/PaletteEditor/ColorPickerWidget.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\PaletteEditor\ColorTriangle.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing ColorTriangle.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/PaletteEditor/ColorTriangle.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing ColorTriangle.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/PaletteEditor/ColorTriangle.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
</CustomBuild>
<ClInclude Include="..\..\..\Source\Fractorium\PaletteEditor\GradientArrow.h" />
<CustomBuild Include="..\..\..\Source\Fractorium\PaletteEditor\GradientColorsView.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing GradientColorsView.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/PaletteEditor/GradientColorsView.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing GradientColorsView.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/PaletteEditor/GradientColorsView.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\PaletteEditor\PaletteEditor.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing PaletteEditor.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/PaletteEditor/PaletteEditor.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing PaletteEditor.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/PaletteEditor/PaletteEditor.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
</CustomBuild>
<ClInclude Include="..\..\..\Source\Fractorium\qcssparser.h" />
<ClInclude Include="..\..\..\Source\Fractorium\qfunctions.h" />
<CustomBuild Include="..\..\..\Source\Fractorium\QssTextEdit.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing QssTextEdit.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssTextEdit.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssTextEdit.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing QssTextEdit.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssTextEdit.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssTextEdit.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
<ClInclude Include="GeneratedFiles\ui_paletteeditor.h" />
<ClInclude Include="GeneratedFiles\ui_QssDialog.h" />
<ClInclude Include="GeneratedFiles\ui_VariationsDialog.h" />
<CustomBuild Include="..\..\..\Source\Fractorium\OptionsDialog.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing OptionsDialog.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/OptionsDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/OptionsDialog.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing OptionsDialog.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/OptionsDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/OptionsDialog.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\AboutDialog.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing AboutDialog.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/AboutDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/AboutDialog.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing AboutDialog.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/AboutDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/AboutDialog.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\FinalRenderDialog.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing FinalRenderDialog.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/FinalRenderDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/FinalRenderDialog.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing FinalRenderDialog.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/FinalRenderDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/FinalRenderDialog.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
@ -391,20 +485,20 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindows.dll" "$(OutDir)\platforms
<CustomBuild Include="..\..\..\Source\Fractorium\FractoriumSettings.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing FractoriumSettings.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/FractoriumSettings.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/FractoriumSettings.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing FractoriumSettings.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/FractoriumSettings.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/FractoriumSettings.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\TwoButtonComboWidget.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing TwoButtonComboWidget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/TwoButtonComboWidget.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/TwoButtonComboWidget.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing TwoButtonComboWidget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/TwoButtonComboWidget.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/TwoButtonComboWidget.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
@ -412,20 +506,20 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindows.dll" "$(OutDir)\platforms
<CustomBuild Include="..\..\..\Source\Fractorium\CurvesGraphicsView.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing CurvesGraphicsView.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/CurvesGraphicsView.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/CurvesGraphicsView.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing CurvesGraphicsView.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/CurvesGraphicsView.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/CurvesGraphicsView.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\DoubleSpinBoxTableItemDelegate.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing DoubleSpinBoxTableItemDelegate.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/DoubleSpinBoxTableItemDelegate.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/DoubleSpinBoxTableItemDelegate.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing DoubleSpinBoxTableItemDelegate.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/DoubleSpinBoxTableItemDelegate.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/DoubleSpinBoxTableItemDelegate.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
@ -441,10 +535,10 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindows.dll" "$(OutDir)\platforms
<CustomBuild Include="..\..\..\Source\Fractorium\GLWidget.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing GLWidget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/GLWidget.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/GLWidget.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing GLWidget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/GLWidget.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/GLWidget.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
@ -452,30 +546,30 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindows.dll" "$(OutDir)\platforms
<CustomBuild Include="..\..\..\Source\Fractorium\DoubleSpinBox.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing DoubleSpinBox.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/DoubleSpinBox.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/DoubleSpinBox.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing DoubleSpinBox.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/DoubleSpinBox.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/DoubleSpinBox.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\SpinBox.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing SpinBox.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/SpinBox.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/SpinBox.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing SpinBox.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/SpinBox.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/SpinBox.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\StealthComboBox.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing StealthComboBox.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/StealthComboBox.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/StealthComboBox.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing StealthComboBox.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/StealthComboBox.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/StealthComboBox.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
@ -499,10 +593,10 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindows.dll" "$(OutDir)\platforms
<CustomBuild Include="..\..\..\Source\Fractorium\TableWidget.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing TableWidget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/TableWidget.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/TableWidget.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing TableWidget.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/TableWidget.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/TableWidget.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
@ -510,10 +604,10 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindows.dll" "$(OutDir)\platforms
<CustomBuild Include="..\..\..\Source\Fractorium\Fractorium.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing Fractorium.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/Fractorium.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/Fractorium.h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing Fractorium.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/Fractorium.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I.\PaletteEditor" "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\Source\Fractorium" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/Fractorium.h"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
@ -617,6 +711,16 @@ xcopy /F /Y /R /D "$(QTDIR)\plugins\platforms\qwindows.dll" "$(OutDir)\platforms
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\paletteeditor.ui">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Uic%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Uic%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Fractorium.rc" />

View File

@ -51,6 +51,9 @@
<Filter Include="Dialogs\Qss">
<UniqueIdentifier>{5ba9fccd-8922-4037-956f-d57177a43700}</UniqueIdentifier>
</Filter>
<Filter Include="Dialogs\PaletteEditor">
<UniqueIdentifier>{30bfa226-b712-471b-a4ff-cf01d10cf1f4}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\Source\Fractorium\main.cpp">
@ -266,6 +269,51 @@
<ClCompile Include="..\..\..\Source\Fractorium\LibraryTreeWidget.cpp">
<Filter>Widgets</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Fractorium\PaletteEditor\ColorPanel.cpp">
<Filter>Dialogs\PaletteEditor</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_ColorPanel.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_ColorPanel.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Fractorium\PaletteEditor\ColorPickerWidget.cpp">
<Filter>Dialogs\PaletteEditor</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_ColorPickerWidget.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_ColorPickerWidget.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Fractorium\PaletteEditor\ColorTriangle.cpp">
<Filter>Dialogs\PaletteEditor</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_ColorTriangle.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_ColorTriangle.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Fractorium\PaletteEditor\GradientColorsView.cpp">
<Filter>Dialogs\PaletteEditor</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_GradientColorsView.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_GradientColorsView.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Fractorium\PaletteEditor\PaletteEditor.cpp">
<Filter>Dialogs\PaletteEditor</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_PaletteEditor.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_PaletteEditor.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="GeneratedFiles\ui_Fractorium.h">
@ -322,6 +370,12 @@
<ClInclude Include="..\..\..\Source\Fractorium\qfunctions.h">
<Filter>Dialogs\Qss</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\Fractorium\PaletteEditor\GradientArrow.h">
<Filter>Dialogs\PaletteEditor</Filter>
</ClInclude>
<ClInclude Include="GeneratedFiles\ui_paletteeditor.h">
<Filter>Generated Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\..\Source\Fractorium\Fractorium.qrc">
@ -405,6 +459,24 @@
<CustomBuild Include="..\..\..\Source\Fractorium\LibraryTreeWidget.h">
<Filter>Widgets</Filter>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\PaletteEditor\ColorPanel.h">
<Filter>Dialogs\PaletteEditor</Filter>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\PaletteEditor\ColorPickerWidget.h">
<Filter>Dialogs\PaletteEditor</Filter>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\PaletteEditor\ColorTriangle.h">
<Filter>Dialogs\PaletteEditor</Filter>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\PaletteEditor\GradientColorsView.h">
<Filter>Dialogs\PaletteEditor</Filter>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\PaletteEditor\PaletteEditor.h">
<Filter>Dialogs\PaletteEditor</Filter>
</CustomBuild>
<CustomBuild Include="..\..\..\Source\Fractorium\paletteeditor.ui">
<Filter>Form Files</Filter>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<None Include="..\..\..\Source\Fractorium\Icons\Fractorium.ico" />

View File

@ -38,9 +38,12 @@ SOURCES += \
$$PRJ_SRC_DIR/DllMain.cpp \
$$PRJ_SRC_DIR/Ember.cpp \
$$PRJ_SRC_DIR/EmberPch.cpp \
$$PRJ_SRC_DIR/EmberToXml.cpp \
$$PRJ_SRC_DIR/PaletteList.cpp \
$$PRJ_SRC_DIR/RendererBase.cpp \
$$PRJ_SRC_DIR/Renderer.cpp \
$$PRJ_SRC_DIR/VariationList.cpp
$$PRJ_SRC_DIR/VariationList.cpp \
$$PRJ_SRC_DIR/XmlToEmber.cpp
include(deployment.pri)
qtcAddDeployment()

View File

@ -43,6 +43,7 @@ CONFIG(debug, debug|release) {
#For some reason, a Qt project needs to be told to look at itself.
INCLUDEPATH += $$PRJ_SRC_DIR
INCLUDEPATH += $$PRJ_SRC_DIR/PaletteEditor
# TODO: Figure out how to build the app bundle correctly.
# This will build a binary instead of an app bundle.
@ -53,7 +54,22 @@ target.path = $$BIN_INSTALL_DIR
INSTALLS += target
palettes.path = $$SHARE_INSTALL_DIR
palettes.files = $$ASSETS_DIR/flam3-palettes.xml
palettes.files = $$ASSETS_DIR/flam3-palettes.xml \
$$ASSETS_DIR/boxtail_pack_02.gradient \
$$ASSETS_DIR/boxtail_pack_03_triangle.gradient \
$$ASSETS_DIR/boxtail_pack_04_mineshack.gradient \
$$ASSETS_DIR/fardareismai_pack_01_variety_number_128.gradient \
$$ASSETS_DIR/fardareismai_pack_02_b_sides.gradient \
$$ASSETS_DIR/fardareismai_pack_03_old_and_new.gradient \
$$ASSETS_DIR/fardareismai_pack_04_hoard.gradient \
$$ASSETS_DIR/fractaldesire_pack_01.gradient \
$$ASSETS_DIR/rce_ordinary_pack_01_colornation.gradient \
$$ASSETS_DIR/tatasz_pack_01.gradient \
$$ASSETS_DIR/tatasz_pack_02_colder.gradient \
$$ASSETS_DIR/tatasz_pack_02_dark.gradient \
$$ASSETS_DIR/tatasz_pack_02_warmer.gradient \
$$ASSETS_DIR/tatasz_pack_03.gradient
#message(PALETTE INSTALL SOURCE: $$palettes.files)
INSTALLS += palettes
@ -114,7 +130,12 @@ SOURCES += \
$$PRJ_SRC_DIR/QssTextEdit.cpp \
$$PRJ_SRC_DIR/SpinBox.cpp \
$$PRJ_SRC_DIR/VariationsDialog.cpp \
$$PRJ_SRC_DIR/LibraryTreeWidget.cpp
$$PRJ_SRC_DIR/LibraryTreeWidget.cpp \
$$PRJ_SRC_DIR/PaletteEditor/ColorPanel.cpp \
$$PRJ_SRC_DIR/PaletteEditor/ColorPickerWidget.cpp \
$$PRJ_SRC_DIR/PaletteEditor/ColorTriangle.cpp \
$$PRJ_SRC_DIR/PaletteEditor/GradientColorsView.cpp \
$$PRJ_SRC_DIR/PaletteEditor/PaletteEditor.cpp
HEADERS += \
$$SRC_COMMON_DIR/EmberCommon.h \
@ -150,7 +171,13 @@ HEADERS += \
$$PRJ_SRC_DIR/TwoButtonComboWidget.h \
$$PRJ_SRC_DIR/VariationsDialog.h \
$$PRJ_SRC_DIR/VariationTreeWidgetItem.h \
$$PRJ_SRC_DIR/LibraryTreeWidget.h
$$PRJ_SRC_DIR/LibraryTreeWidget.h \
$$PRJ_SRC_DIR/PaletteEditor/ColorPanel.h \
$$PRJ_SRC_DIR/PaletteEditor/ColorPickerWidget.h \
$$PRJ_SRC_DIR/PaletteEditor/ColorTriangle.h \
$$PRJ_SRC_DIR/PaletteEditor/GradientArrow.h \
$$PRJ_SRC_DIR/PaletteEditor/GradientColorsView.h \
$$PRJ_SRC_DIR/PaletteEditor/PaletteEditor.h
FORMS += \
$$PRJ_SRC_DIR/AboutDialog.ui \
@ -158,7 +185,8 @@ FORMS += \
$$PRJ_SRC_DIR/Fractorium.ui \
$$PRJ_SRC_DIR/OptionsDialog.ui \
$$PRJ_SRC_DIR/QssDialog.ui \
$$PRJ_SRC_DIR/VariationsDialog.ui
$$PRJ_SRC_DIR/VariationsDialog.ui \
$$PRJ_SRC_DIR/PaletteEditor.ui
OTHER_FILES += \
$$PRJ_SRC_DIR/Fractorium.aps \

View File

@ -1,5 +1,6 @@
VERSION = 1.0.0.2
win32:CONFIG += skip_target_version_ext
CONFIG += c++14
#message(PWD: $$absolute_path($$PWD))
#1) Declare the root of all files in this project, everything else will be
@ -51,6 +52,7 @@ win32 {
INCLUDEPATH += /usr/include/glm
INCLUDEPATH += /usr/include/tbb
INCLUDEPATH += /usr/include/libxml2
#libjpeg and libpng aren't in separate folders, so nothing to add here for them.
}
@ -90,7 +92,7 @@ macx {
LIBS += -L/usr/local/lib# homebrew installs into /usr/local
}
unix {
unix:!macx {
LIBS += -lGL
LIBS += -lOpenCL
}
@ -150,6 +152,7 @@ win32 {
QMAKE_CXXFLAGS_DEBUG += /Od #Optimization disabled.
QMAKE_CXXFLAGS_DEBUG += /D "_DEBUG" #Debug mode.
QMAKE_CXXFLAGS_DEBUG += /RTC1 #Basic runtime checks: stack frames and uninitialized variables.
QMAKE_CXXFLAGS_DEBUG += /Ob2 #Inline function expansion: any suitable.
}
!win32 {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

5240
Data/tatasz_pack_01.gradient Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

5239
Data/tatasz_pack_03.gradient Normal file

File diff suppressed because it is too large Load Diff

68
Data/user-palettes.xml Normal file
View File

@ -0,0 +1,68 @@
<palettes>
<palette number="0" name="pal1" source_colors="0,0.847059,0.482353,0.109804 0.111111,0.878431,0.67451,0.282353 0.222222,0.329412,0.258824,0.866667 0.333333,0.843137,0.286275,0.0745098 0.444444,0.470588,0.909804,0.180392 0.555556,0.0588235,0.168627,0.529412 0.666667,0.439216,0.615686,0.780392 0.777778,0.890196,0.701961,0.101961 0.888889,0.486275,0.886275,0.568627 1,0.443137,0.384314,0.921569 " data="00d87c1d00d87e1f00d9802000d9812200d9832300da852500da862600da8828
00da8a2900db8c2b00db8d2c00db8f2e00dc913000dc933100dc943300dc9634
00dd983600dd993700dd9b3900de9d3a00de9f3c00dea03e00dea23f00dfa441
00dfa54200dfa74400dfa94500e0ab4700dfab4900daa74e00d5a45400d0a059
00cb9c5e00c6996300c1956900bc916e00b88d7300b38a7800ae867e00a98283
00a47e88009f7b8d009a7792009573980090709d008b6ca2008668a7008164ad
007c61b200785db7007359bc006e55c2006952c700644ecc005f4ad1005a47d7
005543dc005842d7005c42d0006143c9006543c2006a43bb006f43b4007344ad
007844a6007b44a1007f449a008445930089458c008d45850092457e00974676
009b466f00a0466800a4466100a9475a00ae475300b2474c00b7474500bb483e
00c0483700c5482f00c9482800ce492100d2491a00d7491300d44f1400d05415
00cd5a1600ca5f1700c6651800c36b1900c0701a00bc761b00b97b1c00b6811c
00b2861d00af8c1e00ac921f00a8972000a59d2100a2a222009ea823009bae24
0098b3250094b9260091be27008ec428008aca290087cf2a0084d52b0080da2c
007de02d0079e62e0076e4300072de33006fd736006bd0390067ca3c0063c33f
0060bc43005cb6460058af490055a94c0051a24f004d9b52004a955500468e58
0042875c003f815f003b7a620037736500336d680030666b002c5f6e00285971
0025527500214b78001d457b001a3e7e0016388100123184000f2b8700132f89
0016338c001a378e001d3b9000203f920024439500274797002b4c99002e509b
0031549e003558a000385ca2003c60a4003f64a7004368a900466cab004970ad
004d74b0005078b200547cb4005780b6005a84b9005e88bb00618cbd006590bf
006894c2006b98c4006f9cc600739ec300779ebd007b9fb7007fa0b10083a1ab
0087a1a5008ba29e008fa3980093a4920097a48c009ba586009fa68000a3a77a
00a7a87400aba86e00afa96800b3aa6200b7ab5c00bbab5500c0ac4f00c4ad49
00c8ae4300cbae3e00cfaf3800d3b03200d7b12c00dbb12600dfb22000e3b31a
00dfb51e00dcb62200d8b82700d5ba2b00d1bb2f00cdbd3300cabf3700c6c03b
00c2c24000bfc44400bbc54800b8c74c00b4c85000b0ca5500adcc5900a9cd5d
00a5cf6100a2d165009ed269009bd46e0097d6720093d7760090d97a008cdb7e
0088dc830085de870081e08b007ee18f007cdf93007bdb96007bd699007bd29c
007acd9f007ac9a30079c4a60079c0a90079bbac0078b7af0078b2b20078aeb6
0077a9b90077a5bc0076a0bf00769cc2007697c5007593c900758ecc00748acf
007485d2007481d500737cd8007378dc007273df00726fe200726ae5007166e8
"/>
<palette number="1" name="pal2" source_colors="0,0.545098,0.223529,0.298039 0.0666667,0.694118,0.337255,0.427451 0.133333,0.690196,0.392157,0.505882 0.2,0.686275,0.282353,0.34902 0.266667,0.694118,0.337255,0.419608 0.333333,0.243137,0.286275,0.301961 0.4,0.533333,0.32549,0.521569 0.466667,0.47451,0.392157,0.517647 0.533333,0.52549,0.298039,0.466667 0.6,0.521569,0.243137,0.305882 0.666667,0.521569,0.282353,0.392157 0.733333,0.619608,0.513726,0.556863 0.8,0.486275,0.458824,0.501961 0.866667,0.345098,0.317647,0.352941 0.933333,0.678431,0.360784,0.454902 1,0.807843,0.407843,0.490196 " data="008c3a4d008f3c4f00913d5100933f530095415500974357009a4459009c465b
009e485d00a0495f00a34b6000a54d6200a74e6400a9506600ac526800ae546a
00b0556c00b1566e00b1576f00b1587000b1597100b15a7200b15b7300b15b75
00b15c7600b05d7700b05e7800b05f7900b05f7b00b0607c00b0617d00b0627e
00b0637f00b0648000b0638000b0627e00b0607b00b05e7900b05d7700b05b74
00b0597200b0586f00af566d00af546b00af536800af516600af506400af4e61
00af4c5f00af4b5d00af495a00af485900af495a00af4a5c00af4b5d00b04c5e
00b04c5f00b04d6000b04e6100b04f6200b0506300b0516400b0516500b05266
00b1536700b1546800b1546900b1556a00b0566b00a9556900a35467009c5465
00955364008e5262008851600081515e007a505d00734f5b006d4e5900664e57
005f4d5600584c5400524b52004b4a5000444a4f003e494d00434a5000474a54
004b4b5700504b5a00544c5e00584d61005d4d6400614e6700654e6b006a4f6e
006e4f710072507500775178007b517b007f527e008452820088538500875485
008655850085568500845785008458850083598500825a8500815b8500805c84
007f5d84007e5e84007d5f84007d6084007c6184007b6284007a638400796484
007a6383007a6183007b6082007c5e81007d5d80007e5c7f007e5a7f007f597e
0080577d0081567c0081557c0082537b0083527a0084507900844f7900854e78
00864c7700864b7500864a7300864a700086496e0086486b0086476900864667
00864664008545620085445f0085435d0085425a008541580085415600854053
00853f5100853e4e00853e4f00853f5000854052008540530085415400854155
0085425700854358008543590085445b0085445c0085455d0085455e00854660
00854761008547620085486400864b6600884e680089516b008a556d008c5870
008d5c72008f5f75009063770092667900936a7c00956d7e0096718100987483
00997786009b7b88009c7e8b009e828d009d828d009b828d0099818c0097808b
00957f8a00937f8a00917e89008f7d88008d7c87008b7b8600897a8500877a85
008579840083788300817782007f7681007d7681007b747f0079727d0077707b
00756e7900736c7600716a74006f6872006d6670006a636d0068616b00665f69
00645d6700625b6500605962005e5760005c555e005a535c0059515a005e525c
0063525d0068535f006d54600072546200775564007c56650081566700865768
008b586a0090586b0095596d009a5a6e009f5a7000a45b7100a95b7300ad5c74
00af5d7500b15e7500b35e7600b55f7600b7607700b9607700bb617800bd6278
00bf627900c1637900c3647a00c5657a00c7657b00c8667b00ca677c00cc677d
"/>
</palettes>

View File

@ -203,6 +203,19 @@ void Affine2D<T>::Scale(T amount)
F(F() * amount);
}
/// <summary>
/// Scales all values A,B,D,E by the specified amount.
/// </summary>
/// <param name="amount">The amount to scale by</param>
template <typename T>
void Affine2D<T>::ScaleXY(T amount)
{
A(A() * amount);
B(B() * amount);
D(D() * amount);
E(E() * amount);
}
/// <summary>
/// Rotate this affine transform around its origin by the specified angle in degrees.
/// </summary>

View File

@ -76,6 +76,7 @@ public:
bool IsZero() const;
bool IsEmpty() const;
void Scale(T amount);
void ScaleXY(T amount);
Affine2D<T> ScaleCopy(T amount);
void Rotate(T rad);
void RotateTrans(T rad);

View File

@ -396,6 +396,11 @@ uint Timing::m_ProcessorCount;
EXPORTPREPOSTREGVAR(Gamma, T) \
EXPORTPREPOSTREGVAR(PRose3D, T) \
EXPORTPREPOSTREGVAR(LogDB, T) \
EXPORTPREPOSTREGVAR(CircleSplit, T) \
EXPORTPREPOSTREGVAR(Cylinder2, T) \
EXPORTPREPOSTREGVAR(TileLog, T) \
EXPORTPREPOSTREGVAR(TruchetFill, T) \
EXPORTPREPOSTREGVAR(Waves2Radial, T) \
template EMBER_API class PostSmartcropVariation<T>; /*Only implemented as post.*/ \
EXPORTPREPOSTREGVAR(DCBubble, T) \
EXPORTPREPOSTREGVAR(DCCarpet, T) \
@ -436,11 +441,10 @@ uint Timing::m_ProcessorCount;
template EMBER_API class XmlToEmber<T>; \
template EMBER_API class EmberToXml<T>;
EXPORT_SINGLE_TYPE_EMBER(float)
#define EXPORT_TWO_TYPE_EMBER(T, bucketT) \
template EMBER_API class SheepTools<T, bucketT>;
EXPORT_SINGLE_TYPE_EMBER(float)
EXPORT_TWO_TYPE_EMBER(float, float)
#ifdef DO_DOUBLE

View File

@ -659,23 +659,23 @@ public:
{
for (glm::length_t i = 0; i < 256; i++)
{
T t[3], s[4] = { 0, 0, 0, 0 };
float t[3], s[4] = { 0, 0, 0, 0 };
for (glm::length_t k = 0; k < size; k++)
{
Palette<T>::RgbToHsv(glm::value_ptr(embers[k].m_Palette[i]), t);
Palette<float>::RgbToHsv(glm::value_ptr(embers[k].m_Palette[i]), t);
for (size_t j = 0; j < 3; j++)
s[j] += coefs[k] * t[j];
s[j] += float(coefs[k]) * t[j];
s[3] += coefs[k] * embers[k].m_Palette[i][3];
s[3] += float(coefs[k]) * embers[k].m_Palette[i][3];
}
Palette<T>::HsvToRgb(s, glm::value_ptr(m_Palette[i]));
Palette<float>::HsvToRgb(s, glm::value_ptr(m_Palette[i]));
m_Palette[i][3] = s[3];
for (glm::length_t j = 0; j < 4; j++)
Clamp<T>(m_Palette[i][j], 0, 1);
Clamp<float>(m_Palette[i][j], 0, 1);
}
}
else if (embers[0].m_PaletteInterp == ePaletteInterp::INTERP_SWEEP)
@ -1100,8 +1100,8 @@ public:
/// <summary>
/// Placeholder to do nothing.
/// </summary>
/// <param name="point">Unused</param>
/// <param name="rand">Unused</param>
/// <param name="point">Ignored</param>
/// <param name="rand">Ignored</param>
void ProjectNone(Point<T>& point, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand)
{
}
@ -1110,7 +1110,7 @@ public:
/// Project when only z is set, and not pitch, yaw, projection or depth blur.
/// </summary>
/// <param name="point">The point to project</param>
/// <param name="rand">Unused</param>
/// <param name="rand">Ignored</param>
void ProjectZPerspective(Point<T>& point, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand)
{
T zr = Zeps(1 - m_CamPerspective * (point.m_Z - m_CamZPos));
@ -1123,7 +1123,7 @@ public:
/// Project when pitch, and optionally z and perspective are set, but not depth blur or yaw.
/// </summary>
/// <param name="point">The point to project</param>
/// <param name="rand">Unused</param>
/// <param name="rand">Ignored</param>
void ProjectPitch(Point<T>& point, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand)
{
T z = point.m_Z - m_CamZPos;
@ -1180,7 +1180,7 @@ public:
/// Project when yaw and optionally pitch, z, and perspective are set, but not depth blur.
/// </summary>
/// <param name="point">The point to project</param>
/// <param name="rand">Unused</param>
/// <param name="rand">Ignored</param>
void ProjectPitchYaw(Point<T>& point, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand)
{
T z = point.m_Z - m_CamZPos;
@ -1653,7 +1653,7 @@ public:
//The color palette to use. Can be specified inline as Xml color fields, or as a hex buffer. Can also be specified
//as an index into the palette file with an optional hue rotation applied. Inserting as a hex buffer is the preferred method.
//Xml field: "color" or "colors" or "palette" .
Palette<T> m_Palette;//Final palette that is actually used is a copy of this inside of render, which will be of type bucketT (float).
Palette<float> m_Palette;//Final palette that is actually used is a copy of this inside of render, which will be of type bucketT (float).
//Curves used to adjust the color during final accumulation.
Curves<T> m_Curves;

View File

@ -103,6 +103,8 @@ static inline size_t NowMs()
#define v2T glm::tvec2<T, glm::defaultp>
#define v3T glm::tvec3<T, glm::defaultp>
#define v4T glm::tvec4<T, glm::defaultp>
#define v4F glm::tvec4<float, glm::defaultp>
#define v4D glm::tvec4<double, glm::defaultp>
#define v4bT glm::tvec4<bucketT, glm::defaultp>
#define m2T glm::tmat2x2<T, glm::defaultp>
#define m3T glm::tmat3x3<T, glm::defaultp>
@ -112,6 +114,8 @@ static inline size_t NowMs()
#define v2T glm::detail::tvec2<T, glm::defaultp>
#define v3T glm::detail::tvec3<T, glm::defaultp>
#define v4T glm::detail::tvec4<T, glm::defaultp>
#define v4F glm::detail::tvec4<float, glm::defaultp>
#define v4D glm::detail::tvec4<double, glm::defaultp>
#define v4bT glm::detail::tvec4<bucketT, glm::defaultp>
#define m2T glm::detail::tmat2x2<T, glm::defaultp>
#define m3T glm::detail::tmat3x3<T, glm::defaultp>

880
Source/Ember/EmberToXml.cpp Normal file
View File

@ -0,0 +1,880 @@
#include "EmberPch.h"
#include "EmberToXml.h"
namespace EmberNs
{
/// <summary>
/// Save the ember to the specified file.
/// </summary>
/// <param name="filename">Full path and filename</param>
/// <param name="ember">The ember to save</param>
/// <param name="printEditDepth">How deep the edit depth goes</param>
/// <param name="doEdits">If true included edit tags, else don't.</param>
/// <param name="hexPalette">If true, embed a hexadecimal palette instead of Xml Color tags, else use Xml color tags.</param>
/// <param name="append">If true, append to the file if it already exists, else create a new file.</param>
/// <param name="start">Whether a new file is to be started</param>
/// <param name="finish">Whether an existing file is to be ended</param>
/// <returns>True if successful, else false</returns>
template <typename T>
bool EmberToXml<T>::Save(const string& filename, Ember<T>& ember, size_t printEditDepth, bool doEdits, bool hexPalette, bool append, bool start, bool finish)
{
vector<Ember<T>> vec;
vec.push_back(ember);
return Save(filename, vec, printEditDepth, doEdits, hexPalette, append, start, finish);
}
/// <summary>
/// Save a container of embers to the specified file.
/// </summary>
/// <param name="filename">Full path and filename</param>
/// <param name="embers">The container of embers to save</param>
/// <param name="printEditDepth">How deep the edit depth goes</param>
/// <param name="doEdits">If true included edit tags, else don't.</param>
/// <param name="hexPalette">If true, embed a hexadecimal palette instead of Xml Color tags, else use Xml color tags.</param>
/// <param name="append">If true, append to the file if it already exists, else create a new file.</param>
/// <param name="start">Whether a new file is to be started</param>
/// <param name="finish">Whether an existing file is to be ended</param>
/// <returns>True if successful, else false</returns>
template <typename T>
template <typename Alloc, template <typename, typename> class C>
bool EmberToXml<T>::Save(const string& filename, C<Ember<T>, Alloc>& embers, size_t printEditDepth, bool doEdits, bool hexPalette, bool append, bool start, bool finish)
{
bool b = false;
T t = 0;
string temp;
ofstream f;
try
{
if (append)
f.open(filename, std::ofstream::out | std::ofstream::app);//Appending allows us to write multiple embers to a single file.
else
f.open(filename);
if (f.is_open())
{
auto prev = embers.begin();
//Always ensure times make sense.
for (auto& ember : embers)
ember.m_Time = t++;
if ((append && start) || !append)
{
temp = "<flames>\n";
//temp = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<flames>\n";
f.write(temp.c_str(), temp.size());
}
for (auto& ember : embers)
{
string s = ToString(ember, "", printEditDepth, doEdits, hexPalette);
f.write(s.c_str(), s.size());
}
if ((append && finish) || !append)
{
temp = "</flames>\n";
f.write(temp.c_str(), temp.size());
}
f.close();
b = true;
}
else
{
cout << "Error: Writing flame " << filename << " failed.\n";
b = false;
}
}
catch (const std::exception& e)
{
cout << "Error: Writing flame " << filename << " failed: " << e.what() << "\n";
b = false;
}
catch (...)
{
cout << "Error: Writing flame " << filename << " failed.\n";
b = false;
}
return b;
}
/// <summary>
/// Return the Xml string representation of an ember.
/// </summary>
/// <param name="ember">The ember to create the Xml with</param>
/// <param name="extraAttributes">If true, add extra attributes, else don't</param>
/// <param name="printEditDepth">How deep the edit depth goes</param>
/// <param name="doEdits">If true included edit tags, else don't.</param>
/// <param name="hexPalette">If true, embed a hexadecimal palette instead of Xml Color tags, else use Xml color tags.</param>
/// <returns>The Xml string representation of the passed in ember</returns>
template <typename T>
string EmberToXml<T>::ToString(Ember<T>& ember, const string& extraAttributes, size_t printEditDepth, bool doEdits, bool hexPalette)
{
size_t i, j;
string s;
ostringstream os;
vector<Variation<T>*> variations;
os << "<flame version=\"EMBER-" << EmberVersion() << "\" time=\"" << ember.m_Time << "\"";
if (!ember.m_Name.empty())
os << " name=\"" << ember.m_Name << "\"";
os << " size=\"" << ember.m_FinalRasW << " " << ember.m_FinalRasH << "\"";
os << " center=\"" << ember.m_CenterX << " " << ember.m_CenterY << "\"";
os << " scale=\"" << ember.m_PixelsPerUnit << "\"";
if (ember.m_Zoom != 0)
os << " zoom=\"" << ember.m_Zoom << "\"";
os << " rotate=\"" << ember.m_Rotate << "\"";
os << " supersample=\"" << std::max<size_t>(1, ember.m_Supersample) << "\"";
os << " filter=\"" << ember.m_SpatialFilterRadius << "\"";
os << " filter_shape=\"" << ToLower(SpatialFilterCreator<T>::ToString(ember.m_SpatialFilterType)) << "\"";
os << " temporal_filter_type=\"" << ToLower(TemporalFilterCreator<T>::ToString(ember.m_TemporalFilterType)) << "\"";
if (ember.m_TemporalFilterType == eTemporalFilterType::EXP_TEMPORAL_FILTER)
os << " temporal_filter_exp=\"" << ember.m_TemporalFilterExp << "\"";
os << " temporal_filter_width=\"" << ember.m_TemporalFilterWidth << "\"";
os << " quality=\"" << ember.m_Quality << "\"";
os << " temporal_samples=\"" << ember.m_TemporalSamples << "\"";
os << " sub_batch_size=\"" << ember.m_SubBatchSize << "\"";
os << " fuse=\"" << ember.m_FuseCount << "\"";
os << " background=\"" << ember.m_Background.r << " " << ember.m_Background.g << " " << ember.m_Background.b << "\"";
os << " brightness=\"" << ember.m_Brightness << "\"";
os << " gamma=\"" << ember.m_Gamma << "\"";
os << " highlight_power=\"" << ember.m_HighlightPower << "\"";
os << " vibrancy=\"" << ember.m_Vibrancy << "\"";
os << " estimator_radius=\"" << ember.m_MaxRadDE << "\"";
os << " estimator_minimum=\"" << ember.m_MinRadDE << "\"";
os << " estimator_curve=\"" << ember.m_CurveDE << "\"";
os << " gamma_threshold=\"" << ember.m_GammaThresh << "\"";
os << " cam_zpos=\"" << ember.m_CamZPos << "\"";
os << " cam_persp=\"" << ember.m_CamPerspective << "\"";
os << " cam_yaw=\"" << ember.m_CamYaw << "\"";
os << " cam_pitch=\"" << ember.m_CamPitch << "\"";
os << " cam_dof=\"" << ember.m_CamDepthBlur << "\"";
if (ember.m_PaletteMode == ePaletteMode::PALETTE_STEP)
os << " palette_mode=\"step\"";
else if (ember.m_PaletteMode == ePaletteMode::PALETTE_LINEAR)
os << " palette_mode=\"linear\"";
if (ember.m_Interp == eInterp::EMBER_INTERP_LINEAR)
os << " interpolation=\"linear\"";
else if (ember.m_Interp == eInterp::EMBER_INTERP_SMOOTH)
os << " interpolation=\"smooth\"";
if (ember.m_AffineInterp == eAffineInterp::AFFINE_INTERP_LINEAR)
os << " interpolation_type=\"linear\"";
else if (ember.m_AffineInterp == eAffineInterp::AFFINE_INTERP_LOG)
os << " interpolation_type=\"log\"";
else if (ember.m_AffineInterp == eAffineInterp::AFFINE_INTERP_COMPAT)
os << " interpolation_type=\"old\"";
else if (ember.m_AffineInterp == eAffineInterp::AFFINE_INTERP_OLDER)
os << " interpolation_type=\"older\"";
if (ember.m_PaletteInterp == ePaletteInterp::INTERP_SWEEP)
os << " palette_interpolation=\"sweep\"";
if (!extraAttributes.empty())
os << " " << extraAttributes;
os << " plugins=\"";
ember.GetPresentVariations(variations, false);
if (!variations.empty())
for (auto var : variations) os << var->Name() << (var != variations.back() ? " " : "\"");
else
os << "\"";
os << " new_linear=\"1\"";
os << " curves=\"";
for (glm::length_t ci = 0; ci < 4; ci++)
{
for (glm::length_t cj = 0; cj < 4; cj++)
{
os << ember.m_Curves.m_Points[ci][cj].x << " ";
os << ember.m_Curves.m_Points[ci][cj].y << " ";
os << ember.m_Curves.m_Weights[ci][cj] << " ";
}
}
os << "\">\n";
for (i = 0; i < ember.m_EmberMotionElements.size(); ++i)
os << " " << ToString(ember.m_EmberMotionElements[i]);
//This is a grey area, what to do about symmetry to avoid duplicating the symmetry xforms when reading back?//TODO//BUG.
//if (ember.m_Symmetry)
// os << " <symmetry kind=\"" << ember.m_Symmetry << "\"/>\n";
for (i = 0; i < ember.XformCount(); i++)
os << ToString(*ember.GetXform(i), ember.XformCount(), false, false);//Not final, don't do motion.
if (ember.UseFinalXform())
os << ToString(*ember.NonConstFinalXform(), ember.XformCount(), true, false);//Final, don't do motion.
//Note that only embedded palettes are saved. The old style of specifying a palette index to look up in a default palette file
//is no longer supported, as it makes no sense when using multiple palette files. The only way it could work is if the index was
//always meant to refer to the default file, or if the filename was embedded as well. It's easier, more straightforward and
//less error prone to just embed the palette.
if (hexPalette)
{
os << " <palette count=\"256\" format=\"RGB\"";
if (!ember.m_Palette.m_SourceColors.empty())
{
os << " source_colors=\"";
for (auto& sc : ember.m_Palette.m_SourceColors)
{
os <<
Clamp(sc.first, 0.0f, 1.0f) << "," <<
Clamp(sc.second.r, 0.0f, 1.0f) << "," <<
Clamp(sc.second.g, 0.0f, 1.0f) << "," <<
Clamp(sc.second.b, 0.0f, 1.0f) << " ";
}
os << "\"";
}
os << ">\n";
for (i = 0; i < 32; i++)
{
os << " ";
for (j = 0; j < 8; j++)
{
size_t idx = 8 * i + j;
os << hex << setw(2) << setfill('0') << int(std::rint(ember.m_Palette[idx][0] * 255));
os << hex << setw(2) << setfill('0') << int(std::rint(ember.m_Palette[idx][1] * 255));
os << hex << setw(2) << setfill('0') << int(std::rint(ember.m_Palette[idx][2] * 255));
}
os << "\n";
}
os << " </palette>\n";
}
else
{
for (i = 0; i < 256; i++)
{
double r = ember.m_Palette[i][0] * 255;
double g = ember.m_Palette[i][1] * 255;
double b = ember.m_Palette[i][2] * 255;
double a = ember.m_Palette[i][3] * 255;
os << " ";
//The original used a precision of 6 which is totally unnecessary, use 2.
if (IsClose(a, 255.0))
os << "<color index=\"" << i << "\" rgb=\"" << std::fixed << std::setprecision(2) << r << " " << g << " " << b << "\"/>";
else
os << " <color index=\"" << i << "\" rgba=\"" << std::fixed << std::setprecision(2) << r << " " << g << " " << b << " " << a << "\"/>";
os << "\n";
}
}
if (doEdits && ember.m_Edits)
os << ToString(xmlDocGetRootElement(ember.m_Edits), 1, true, printEditDepth);
os << "</flame>\n";
return os.str();
}
/// <summary>
/// Create a new editdoc optionally based on parents passed in.
/// This is used when an ember is made out of some mutation or edit from one or two existing embers and
/// the user wants to capture the genetic lineage history information in the edit doc of the new ember.
/// </summary>
/// <param name="parent0">The first parent, optionally nullptr.</param>
/// <param name="parent1">The second parent, optionally nullptr.</param>
/// <param name="action">The action that was taken to create the new ember</param>
/// <param name="nick">The nickname of the author</param>
/// <param name="url">The Url of the author</param>
/// <param name="id">The id of the author</param>
/// <param name="comment">The comment to include</param>
/// <param name="sheepGen">The sheep generation used if > 0. Default: 0.</param>
/// <param name="sheepId">The sheep id used if > 0. Default: 0.</param>
/// <returns></returns>
template <typename T>
xmlDocPtr EmberToXml<T>::CreateNewEditdoc(Ember<T>* parent0, Ember<T>* parent1, const string& action, const string& nick, const string& url, const string& id, const string& comment, intmax_t sheepGen, intmax_t sheepId)
{
char timeString[128];
time_t myTime;
string s;
xmlDocPtr commentDoc = nullptr;
xmlDocPtr doc = xmlNewDoc(XC("1.0"));
xmlNodePtr rootNode = nullptr, node = nullptr, nodeCopy = nullptr;
xmlNodePtr rootComment = nullptr;
ostringstream os;
//Create the root node, called "edit".
rootNode = xmlNewNode(nullptr, XC("edit"));
xmlDocSetRootElement(doc, rootNode);
//Add the edit attributes.
//Date.
myTime = time(nullptr);
#ifdef _WIN32
tm localt;
localtime_s(&localt, &myTime);
strftime(timeString, 128, "%a %b %d %H:%M:%S %z %Y", &localt);//XXX use standard time format including timezone.
#else
tm* localt;
localt = localtime(&myTime);
strftime(timeString, 128, "%a %b %d %H:%M:%S %z %Y", localt);//XXX use standard time format including timezone.
#endif
xmlNewProp(rootNode, XC("date"), XC(timeString));
//Nick.
if (nick != "")
xmlNewProp(rootNode, XC("nick"), XC(nick.c_str()));
//Url.
if (url != "")
xmlNewProp(rootNode, XC("url"), XC(url.c_str()));
if (id != "")
xmlNewProp(rootNode, XC("id"), XC(id.c_str()));
//Action.
xmlNewProp(rootNode, XC("action"), XC(action.c_str()));
//Sheep info.
if (sheepGen > 0 && sheepId > 0)
{
//Create a child node of the root node called sheep.
node = xmlNewChild(rootNode, nullptr, XC("sheep"), nullptr);
//Create the sheep attributes.
os << sheepGen;
s = os.str();
xmlNewProp(node, XC("generation"), XC(s.c_str()));
os.str("");
os << sheepId;
s = os.str();
xmlNewProp(node, XC("id"), XC(s.c_str()));
os.str("");
}
//Check for the parents.
//If parent 0 not specified, this is a randomly generated genome.
if (parent0)
{
os << parent0->m_Index;
s = os.str();
if (parent0->m_Edits)
{
//Copy the node from the parent.
node = xmlDocGetRootElement(parent0->m_Edits);
nodeCopy = xmlCopyNode(node, 1);
AddFilenameWithoutAmpersand(nodeCopy, parent0->m_ParentFilename);
xmlNewProp(nodeCopy, XC("index"), XC(s.c_str()));
xmlAddChild(rootNode, nodeCopy);
}
else
{
//Insert a (parent has no edit) message.
nodeCopy = xmlNewChild(rootNode, nullptr, XC("edit"), nullptr);
AddFilenameWithoutAmpersand(nodeCopy, parent0->m_ParentFilename);
xmlNewProp(nodeCopy, XC("index"), XC(s.c_str()));
}
os.str("");
}
if (parent1)
{
os << parent1->m_Index;
s = os.str();
if (parent1->m_Edits)
{
//Copy the node from the parent.
node = xmlDocGetRootElement(parent1->m_Edits);
nodeCopy = xmlCopyNode(node, 1);
AddFilenameWithoutAmpersand(nodeCopy, parent1->m_ParentFilename);
xmlNewProp(nodeCopy, XC("index"), XC(s.c_str()));
xmlAddChild(rootNode, nodeCopy);
}
else
{
//Insert a (parent has no edit) message.
nodeCopy = xmlNewChild(rootNode, nullptr, XC("edit"), nullptr);
AddFilenameWithoutAmpersand(nodeCopy, parent1->m_ParentFilename);
xmlNewProp(nodeCopy, XC("index"), XC(s.c_str()));
}
os.str("");
}
//Comment string:
//This one's hard, since the comment string must be treated as
//a valid XML document. Create a new document using the comment
//string as the in-memory document, and then copy all children of
//the root node into the edit structure
//Parsing the comment string should be done once and then copied
//for each new edit doc, but that's for later.
if (comment != "")
{
os << "<comm>" << comment << "</comm>";
s = os.str();
commentDoc = xmlReadMemory(s.c_str(), int(s.length()), "comment.env", nullptr, XML_PARSE_NONET);
os.str("");
//Check for errors.
if (commentDoc)
{
//Loop through the children of the new document and copy them into the rootNode.
rootComment = xmlDocGetRootElement(commentDoc);
for (node = rootComment->children; node; node = node->next)
{
nodeCopy = xmlCopyNode(node, 1);
xmlAddChild(rootNode, nodeCopy);
}
//Free the created document.
xmlFreeDoc(commentDoc);
}
else
{
cout << "Failed to parse comment into Xml.\n";
}
}
//Return the Xml doc.
return doc;
}
/// <summary>
/// Return the Xml string representation of an xform.
/// </summary>
/// <param name="xform">The xform to create the Xml with</param>
/// <param name="xformCount">The number of non-final xforms in the ember to which this xform belongs. Used for xaos.</param>
/// <param name="isFinal">True if the xform is the final xform in the ember, else false.</param>
/// <param name="doMotion">If true, include motion elements in the Xml string, else omit.</param>
/// <returns>The Xml string representation of the passed in xform</returns>
template <typename T>
string EmberToXml<T>::ToString(Xform<T>& xform, size_t xformCount, bool isFinal, bool doMotion)
{
size_t i, j;
ostringstream os;
if (doMotion)
{
os << " <motion motion_frequency=\"" << xform.m_MotionFreq << "\" ";
if (xform.m_MotionFunc == eMotion::MOTION_SIN)
os << "motion_function=\"sin\" ";
else if (xform.m_MotionFunc == eMotion::MOTION_TRIANGLE)
os << "motion_function=\"triangle\" ";
else if (xform.m_MotionFunc == eMotion::MOTION_HILL)
os << "motion_function=\"hill\" ";
else if (xform.m_MotionFunc == eMotion::MOTION_SAW)
os << "motion_function=\"saw\" ";
if (xform.m_MotionOffset != 0)
os << "motion_offset=\"" << xform.m_MotionOffset << "\" ";
}
else
{
if (isFinal)
os << " <finalxform ";
else
os << " <xform weight=\"" << xform.m_Weight << "\" ";
}
if (!doMotion || xform.m_ColorX != EMPTYFIELD) os << "color=\"" << xform.m_ColorX << "\" ";
//if (!doMotion || xform.m_ColorY != EMPTYFIELD) os << "color=\"" << xform.m_ColorX << " " << xform.m_ColorY << "\" ";
if (!doMotion || xform.m_DirectColor != EMPTYFIELD) os << "var_color=\"" << xform.m_DirectColor << "\" ";
if (!doMotion || xform.m_ColorSpeed != EMPTYFIELD) os << "color_speed=\"" << xform.m_ColorSpeed << "\" ";
//os << "symmetry=\"" << fabs(xform.m_ColorSpeed - 1) * 2 << "\" ";//Legacy support.
if (!doMotion)
{
string s = xform.m_Name;
std::replace(s.begin(), s.end(), ' ', '_');
os << "name=\"" << s << "\" ";//Flam3 didn't do this, but Apo does.
if (!isFinal)
os << "animate=\"" << xform.m_Animate << "\" ";
}
//Variation writing order differs slightly from the original to make it a bit more readable.
//The original wrote out all of the variation names and weights. Then wrote out the parameters for
//the parametric variations. Here, write out the params immediately after each parametric variation
//so they are more closely grouped with the variation they apply to, rather than being all grouped at the end.
for (i = 0; i < xform.TotalVariationCount(); i++)
{
Variation<T>* var = xform.GetVariation(i);
ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var);
if (var->m_Weight != 0)
{
os << var->Name() << "=\"" << var->m_Weight << "\" ";
if (parVar)
{
auto params = parVar->Params();
for (j = 0; j < parVar->ParamCount(); j++)
{
if ((!doMotion || (doMotion && (params[j].ParamVal() != 0))) && !params[j].IsPrecalc())
os << params[j].Name() << "=\"" << params[j].ParamVal() << "\" ";
}
}
}
}
if (!doMotion || (doMotion && !xform.m_Affine.IsZero() && !xform.m_Affine.IsEmpty()))
{
os << "coefs=\"" << xform.m_Affine.A() << " " << xform.m_Affine.D() << " " << xform.m_Affine.B() << " "
<< xform.m_Affine.E() << " " << xform.m_Affine.C() << " " << xform.m_Affine.F() << "\"";
}
if ((!doMotion && !xform.m_Post.IsID()) || (doMotion && !xform.m_Post.IsZero() && !xform.m_Post.IsEmpty()))
{
os << " post=\"" << xform.m_Post.A() << " " << xform.m_Post.D() << " " << xform.m_Post.B() << " "
<< xform.m_Post.E() << " " << xform.m_Post.C() << " " << xform.m_Post.F() << "\"";
}
//Original only printed xaos values that were not 1. Here, print them all out if any are present.
if (!isFinal && !doMotion && xform.XaosPresent())//Applying motion to xaos not supported.
{
os << " chaos=\"";
for (i = 0; i < xformCount; i++)
os << xform.Xaos(i) << " ";
os << "\"";
}
if (!doMotion || xform.m_Opacity != EMPTYFIELD) os << " opacity=\"" << xform.m_Opacity << "\"";
if (!doMotion && !xform.m_Motion.empty())
{
os << ">\n";
for (i = 0; i < xform.m_Motion.size(); i++)
os << ToString(xform.m_Motion[i], 0, false, true);
if (isFinal)//Fixed to properly close final.//SMOULDER
os << " </finalxform>\n";
else
os << " </xform>\n";
}
else
os << "/>\n";
return os.str();
}
/// <summary>
/// Return an edit node Xml string.
/// </summary>
/// <param name="editNode">The edit node to get the string for</param>
/// <param name="tabs">How many tabs to use</param>
/// <param name="formatting">If true, include newlines and tabs, else don't.</param>
/// <param name="printEditDepth">How deep the edit depth goes</param>
/// <returns>The edit node Xml string</returns>
template <typename T>
string EmberToXml<T>::ToString(xmlNodePtr editNode, size_t tabs, bool formatting, size_t printEditDepth)
{
bool indentPrinted = false;
const char* tabString = " ", *attStr;
const char* editString = "edit";
const char* sheepString = "sheep";
size_t ti;//, editOrSheep = 0;
xmlAttrPtr attPtr = nullptr, curAtt = nullptr;
xmlNodePtr childPtr = nullptr, curChild = nullptr;
ostringstream os;
if (printEditDepth > 0 && tabs > printEditDepth)
return "";
//If this node is an XML_ELEMENT_NODE, print it and its attributes.
if (editNode->type == XML_ELEMENT_NODE)
{
//Print the node at the tab specified.
if (formatting)
for (ti = 0; ti < tabs; ti++)
os << tabString;
os << "<" << editNode->name;
//This can either be an edit node or a sheep node.
//If it's an edit node, add one to the tab.
if (!Compare(editNode->name, editString))
{
//editOrSheep = 1;
tabs++;
}
else if (!Compare(editNode->name, sheepString)) {}
//editOrSheep = 2;
else {}
//editOrSheep = 0;
//Print the attributes.
attPtr = editNode->properties;
for (curAtt = attPtr; curAtt; curAtt = curAtt->next)
{
attStr = CX(xmlGetProp(editNode, curAtt->name));
os << " " << curAtt->name << "=\"" << attStr << "\"";
xmlFree(reinterpret_cast<void*>(const_cast<char*>(attStr)));
}
//Does this node have children?
if (!editNode->children || (printEditDepth > 0 && tabs > printEditDepth))
{
//Close the tag and subtract the tab.
os << "/>";
if (formatting)
os << "\n";
tabs--;
}
else
{
//Close the tag.
os << ">";
if (formatting)
os << "\n";
//Loop through the children and print them.
childPtr = editNode->children;
indentPrinted = false;
for (curChild = childPtr; curChild; curChild = curChild->next)
{
//If child is an element, indent first and then print it.
if (curChild->type == XML_ELEMENT_NODE &&
(!Compare(curChild->name, editString) || !Compare(curChild->name, sheepString)))
{
if (indentPrinted)
{
indentPrinted = false;
os << "\n";
}
os << ToString(curChild, tabs, true, printEditDepth);
}
else
{
//Child is a text node, don't want to indent more than once.
if (xmlIsBlankNode(curChild))
continue;
if (!indentPrinted && formatting)
{
for (ti = 0; ti < tabs; ti++)
os << tabString;
indentPrinted = true;
}
//Print nodes without formatting.
os << ToString(curChild, tabs, false, printEditDepth);
}
}
if (indentPrinted && formatting)
os << "\n";
tabs--;//Tab out.
if (formatting)
for (ti = 0; ti < tabs; ti++)
os << tabString;
os << "</" << editNode->name << ">";//Close the tag.
if (formatting)
os << "\n";
}
}
else if (editNode->type == XML_TEXT_NODE)
{
string s(reinterpret_cast<char*>(xmlNodeGetContent(editNode)));
os << Trim(s);
}
return os.str();
}
/// <summary>
/// Convert a EmberMotion element to an xml string
/// </summary>
/// <param name="motion">The EmberMotion object to convert to XML</param>
/// <returns>The string representation of the passed in EmberMotion object</returns>
template <typename T>
string EmberToXml<T>::ToString(const EmberMotion<T>& motion)
{
ostringstream os;
os << "<flame_motion motion_frequency=\"" << motion.m_MotionFreq << "\" ";
if (motion.m_MotionOffset > 0)
os << "motion_offset=\"" << motion.m_MotionOffset << "\" ";
os << "motion_func=";
switch (motion.m_MotionFunc)
{
case eMotion::MOTION_SIN:
os << "\"sin\"";
break;
case eMotion::MOTION_HILL:
os << "\"hill\"";
break;
case eMotion::MOTION_TRIANGLE:
os << "\"triangle\"";
break;
case eMotion::MOTION_SAW:
default:
os << "\"saw\"";
break;
}
T r = 0.0;
T g = 0.0;
T b = 0.0;
T cx = 0.0;
T cy = 0.0;
for (size_t i = 0; i < motion.m_MotionParams.size(); ++i)
{
switch (motion.m_MotionParams[i].first)
{
case eEmberMotionParam::FLAME_MOTION_ZOOM:
os << " zoom=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_ZPOS:
os << " cam_zpos=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_PERSPECTIVE:
os << " cam_persp=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_YAW:
os << " cam_yaw=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_PITCH:
os << " cam_pitch=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_DEPTH_BLUR:
os << " cam_dof=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_CENTER_X:
cx = motion.m_MotionParams[i].second;
break;
case eEmberMotionParam::FLAME_MOTION_CENTER_Y:
cy = motion.m_MotionParams[i].second;
break;
case eEmberMotionParam::FLAME_MOTION_ROTATE:
os << " rotate=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_BRIGHTNESS:
os << " brightness=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_GAMMA:
os << " gamma=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_GAMMA_THRESH:
os << " gamma_threshold=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_HIGHLIGHT_POWER:
os << " highlight_power=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_BACKGROUND_R:
r = motion.m_MotionParams[i].second;
break;
case eEmberMotionParam::FLAME_MOTION_BACKGROUND_G:
g = motion.m_MotionParams[i].second;
break;
case eEmberMotionParam::FLAME_MOTION_BACKGROUND_B:
b = motion.m_MotionParams[i].second;
break;
case eEmberMotionParam::FLAME_MOTION_VIBRANCY:
os << " vibrancy=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_NONE:
default:
break;
}
}
if (r != 0.0 || g != 0.0 || b != 0.0)
os << " background=\"" << r << " " << g << " " << b << "\"";
if (cx != 0.0 || cy != 0.0)
os << " center=\"" << cx << " " << cy << "\"";
os << "/>\n";
return os.str();
}
/// <summary>
/// Replace the character '&' in a filename with "&amp;" and set the value in
/// the passed in node to this new string.
/// If no '&' is found, the passed in string is used as-is when populating the value of the node.
/// This is done because Xml parsing can't handle ampersands.
/// </summary>
/// <param name="node">The XML node to write the new value to</param>
/// <param name="filename">The filename string to examine for ampersands.</param>
template <typename T>
void EmberToXml<T>::AddFilenameWithoutAmpersand(xmlNodePtr node, string& filename)
{
if (filename.find_first_of('&') != std::string::npos)
{
string filenameWithoutAmpersands = filename;
FindAndReplace<string>(filenameWithoutAmpersands, "&", "&amp;");
xmlNewProp(node, XC("filename"), XC(filenameWithoutAmpersands.c_str()));
}
else
{
xmlNewProp(node, XC("filename"), XC(filename.c_str()));
}
}
#define EXPORT_EMBER_TO_XML(T) \
template EMBER_API class EmberToXml<T>; \
template EMBER_API bool EmberToXml<T>::Save(const string&, vector<Ember<T>>& embers, size_t, bool, bool, bool, bool, bool); \
template EMBER_API bool EmberToXml<T>::Save(const string&, list<Ember<T>>& embers, size_t, bool, bool, bool, bool, bool);
EXPORT_EMBER_TO_XML(float)
#ifdef DO_DOUBLE
EXPORT_EMBER_TO_XML(double)
#endif
}

View File

@ -27,835 +27,16 @@ public:
~EmberToXml() = default;
EmberToXml(const EmberToXml<T>& e) = delete;
/// <summary>
/// Save the ember to the specified file.
/// </summary>
/// <param name="filename">Full path and filename</param>
/// <param name="ember">The ember to save</param>
/// <param name="printEditDepth">How deep the edit depth goes</param>
/// <param name="doEdits">If true included edit tags, else don't.</param>
/// <param name="hexPalette">If true, embed a hexadecimal palette instead of Xml Color tags, else use Xml color tags.</param>
/// <param name="append">If true, append to the file if it already exists, else create a new file.</param>
/// <param name="start">Whether a new file is to be started</param>
/// <param name="finish">Whether an existing file is to be ended</param>
/// <returns>True if successful, else false</returns>
bool Save(const string& filename, Ember<T>& ember, size_t printEditDepth, bool doEdits, bool hexPalette, bool append = false, bool start = false, bool finish = false)
{
vector<Ember<T>> vec;
vec.push_back(ember);
return Save(filename, vec, printEditDepth, doEdits, hexPalette, append, start, finish);
}
/// <summary>
/// Save a container of embers to the specified file.
/// </summary>
/// <param name="filename">Full path and filename</param>
/// <param name="embers">The container of embers to save</param>
/// <param name="printEditDepth">How deep the edit depth goes</param>
/// <param name="doEdits">If true included edit tags, else don't.</param>
/// <param name="hexPalette">If true, embed a hexadecimal palette instead of Xml Color tags, else use Xml color tags.</param>
/// <param name="append">If true, append to the file if it already exists, else create a new file.</param>
/// <param name="start">Whether a new file is to be started</param>
/// <param name="finish">Whether an existing file is to be ended</param>
/// <returns>True if successful, else false</returns>
bool Save(const string& filename, Ember<T>& ember, size_t printEditDepth, bool doEdits, bool hexPalette, bool append = false, bool start = false, bool finish = false);
template <typename Alloc, template <typename, typename> class C>
bool Save(const string& filename, C<Ember<T>, Alloc>& embers, size_t printEditDepth, bool doEdits, bool hexPalette, bool append = false, bool start = false, bool finish = false)
{
bool b = false;
bool hasTimes = false;
T t = 0;
string temp;
ofstream f;
try
{
if (append)
f.open(filename, std::ofstream::out | std::ofstream::app);//Appending allows us to write multiple embers to a single file.
else
f.open(filename);
if (f.is_open())
{
auto prev = embers.begin();
//Always ensure times make sense.
for (auto& ember : embers)
ember.m_Time = t++;
if ((append && start) || !append)
{
temp = "<flames>\n";
//temp = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<flames>\n";
f.write(temp.c_str(), temp.size());
}
for (auto& ember : embers)
{
string s = ToString(ember, "", printEditDepth, doEdits, hexPalette);
f.write(s.c_str(), s.size());
}
if ((append && finish) || !append)
{
temp = "</flames>\n";
f.write(temp.c_str(), temp.size());
}
f.close();
b = true;
}
else
{
cout << "Error: Writing flame " << filename << " failed.\n";
b = false;
}
}
catch (const std::exception& e)
{
cout << "Error: Writing flame " << filename << " failed: " << e.what() << "\n";
b = false;
}
catch (...)
{
cout << "Error: Writing flame " << filename << " failed.\n";
b = false;
}
return b;
}
/// <summary>
/// Return the Xml string representation of an ember.
/// </summary>
/// <param name="ember">The ember to create the Xml with</param>
/// <param name="extraAttributes">If true, add extra attributes, else don't</param>
/// <param name="printEditDepth">How deep the edit depth goes</param>
/// <param name="doEdits">If true included edit tags, else don't.</param>
/// <param name="hexPalette">If true, embed a hexadecimal palette instead of Xml Color tags, else use Xml color tags.</param>
/// <returns>The Xml string representation of the passed in ember</returns>
string ToString(Ember<T>& ember, const string& extraAttributes, size_t printEditDepth, bool doEdits, bool hexPalette = true)
{
size_t i, j;
string s;
ostringstream os;
vector<Variation<T>*> variations;
os << "<flame version=\"EMBER-" << EmberVersion() << "\" time=\"" << ember.m_Time << "\"";
if (!ember.m_Name.empty())
os << " name=\"" << ember.m_Name << "\"";
os << " size=\"" << ember.m_FinalRasW << " " << ember.m_FinalRasH << "\"";
os << " center=\"" << ember.m_CenterX << " " << ember.m_CenterY << "\"";
os << " scale=\"" << ember.m_PixelsPerUnit << "\"";
if (ember.m_Zoom != 0)
os << " zoom=\"" << ember.m_Zoom << "\"";
os << " rotate=\"" << ember.m_Rotate << "\"";
os << " supersample=\"" << std::max<size_t>(1, ember.m_Supersample) << "\"";
os << " filter=\"" << ember.m_SpatialFilterRadius << "\"";
os << " filter_shape=\"" << ToLower(SpatialFilterCreator<T>::ToString(ember.m_SpatialFilterType)) << "\"";
os << " temporal_filter_type=\"" << ToLower(TemporalFilterCreator<T>::ToString(ember.m_TemporalFilterType)) << "\"";
if (ember.m_TemporalFilterType == eTemporalFilterType::EXP_TEMPORAL_FILTER)
os << " temporal_filter_exp=\"" << ember.m_TemporalFilterExp << "\"";
os << " temporal_filter_width=\"" << ember.m_TemporalFilterWidth << "\"";
os << " quality=\"" << ember.m_Quality << "\"";
os << " temporal_samples=\"" << ember.m_TemporalSamples << "\"";
os << " sub_batch_size=\"" << ember.m_SubBatchSize << "\"";
os << " fuse=\"" << ember.m_FuseCount << "\"";
os << " background=\"" << ember.m_Background.r << " " << ember.m_Background.g << " " << ember.m_Background.b << "\"";
os << " brightness=\"" << ember.m_Brightness << "\"";
os << " gamma=\"" << ember.m_Gamma << "\"";
os << " highlight_power=\"" << ember.m_HighlightPower << "\"";
os << " vibrancy=\"" << ember.m_Vibrancy << "\"";
os << " estimator_radius=\"" << ember.m_MaxRadDE << "\"";
os << " estimator_minimum=\"" << ember.m_MinRadDE << "\"";
os << " estimator_curve=\"" << ember.m_CurveDE << "\"";
os << " gamma_threshold=\"" << ember.m_GammaThresh << "\"";
os << " cam_zpos=\"" << ember.m_CamZPos << "\"";
os << " cam_persp=\"" << ember.m_CamPerspective << "\"";
os << " cam_yaw=\"" << ember.m_CamYaw << "\"";
os << " cam_pitch=\"" << ember.m_CamPitch << "\"";
os << " cam_dof=\"" << ember.m_CamDepthBlur << "\"";
if (ember.m_PaletteMode == ePaletteMode::PALETTE_STEP)
os << " palette_mode=\"step\"";
else if (ember.m_PaletteMode == ePaletteMode::PALETTE_LINEAR)
os << " palette_mode=\"linear\"";
if (ember.m_Interp == eInterp::EMBER_INTERP_LINEAR)
os << " interpolation=\"linear\"";
else if (ember.m_Interp == eInterp::EMBER_INTERP_SMOOTH)
os << " interpolation=\"smooth\"";
if (ember.m_AffineInterp == eAffineInterp::AFFINE_INTERP_LINEAR)
os << " interpolation_type=\"linear\"";
else if (ember.m_AffineInterp == eAffineInterp::AFFINE_INTERP_LOG)
os << " interpolation_type=\"log\"";
else if (ember.m_AffineInterp == eAffineInterp::AFFINE_INTERP_COMPAT)
os << " interpolation_type=\"old\"";
else if (ember.m_AffineInterp == eAffineInterp::AFFINE_INTERP_OLDER)
os << " interpolation_type=\"older\"";
if (ember.m_PaletteInterp == ePaletteInterp::INTERP_SWEEP)
os << " palette_interpolation=\"sweep\"";
if (!extraAttributes.empty())
os << " " << extraAttributes;
os << " plugins=\"";
ember.GetPresentVariations(variations, false);
if (!variations.empty())
for (auto var : variations) os << var->Name() << (var != variations.back() ? " " : "\"");
else
os << "\"";
os << " new_linear=\"1\"";
os << " curves=\"";
for (glm::length_t ci = 0; ci < 4; ci++)
{
for (glm::length_t cj = 0; cj < 4; cj++)
{
os << ember.m_Curves.m_Points[ci][cj].x << " ";
os << ember.m_Curves.m_Points[ci][cj].y << " ";
os << ember.m_Curves.m_Weights[ci][cj] << " ";
}
}
os << "\">\n";
for (i = 0; i < ember.m_EmberMotionElements.size(); ++i)
os << " " << ToString(ember.m_EmberMotionElements[i]);
//This is a grey area, what to do about symmetry to avoid duplicating the symmetry xforms when reading back?//TODO//BUG.
//if (ember.m_Symmetry)
// os << " <symmetry kind=\"" << ember.m_Symmetry << "\"/>\n";
for (i = 0; i < ember.XformCount(); i++)
os << ToString(*ember.GetXform(i), ember.XformCount(), false, false);//Not final, don't do motion.
if (ember.UseFinalXform())
os << ToString(*ember.NonConstFinalXform(), ember.XformCount(), true, false);//Final, don't do motion.
//Note that only embedded palettes are saved. The old style of specifying a palette index to look up in a default palette file
//is no longer supported, as it makes no sense when using multiple palette files. The only way it could work is if the index was
//always meant to refer to the default file, or if the filename was embedded as well. It's easier, more straightforward and
//less error prone to just embed the palette.
if (hexPalette)
{
os << " <palette count=\"256\" format=\"RGB\">\n";
for (i = 0; i < 32; i++)
{
os << " ";
for (j = 0; j < 8; j++)
{
size_t idx = 8 * i + j;
os << hex << setw(2) << setfill('0') << int(std::rint(ember.m_Palette[idx][0] * 255));
os << hex << setw(2) << setfill('0') << int(std::rint(ember.m_Palette[idx][1] * 255));
os << hex << setw(2) << setfill('0') << int(std::rint(ember.m_Palette[idx][2] * 255));
}
os << "\n";
}
os << " </palette>\n";
}
else
{
for (i = 0; i < 256; i++)
{
double r = ember.m_Palette[i][0] * 255;
double g = ember.m_Palette[i][1] * 255;
double b = ember.m_Palette[i][2] * 255;
double a = ember.m_Palette[i][3] * 255;
os << " ";
//The original used a precision of 6 which is totally unnecessary, use 2.
if (IsClose(a, 255.0))
os << "<color index=\"" << i << "\" rgb=\"" << std::fixed << std::setprecision(2) << r << " " << g << " " << b << "\"/>";
else
os << " <color index=\"" << i << "\" rgba=\"" << std::fixed << std::setprecision(2) << r << " " << g << " " << b << " " << a << "\"/>";
os << "\n";
}
}
if (doEdits && ember.m_Edits)
os << ToString(xmlDocGetRootElement(ember.m_Edits), 1, true, printEditDepth);
os << "</flame>\n";
return os.str();
}
/// <summary>
/// Create a new editdoc optionally based on parents passed in.
/// This is used when an ember is made out of some mutation or edit from one or two existing embers and
/// the user wants to capture the genetic lineage history information in the edit doc of the new ember.
/// </summary>
/// <param name="parent0">The first parent, optionally nullptr.</param>
/// <param name="parent1">The second parent, optionally nullptr.</param>
/// <param name="action">The action that was taken to create the new ember</param>
/// <param name="nick">The nickname of the author</param>
/// <param name="url">The Url of the author</param>
/// <param name="id">The id of the author</param>
/// <param name="comment">The comment to include</param>
/// <param name="sheepGen">The sheep generation used if > 0. Default: 0.</param>
/// <param name="sheepId">The sheep id used if > 0. Default: 0.</param>
/// <returns></returns>
xmlDocPtr CreateNewEditdoc(Ember<T>* parent0, Ember<T>* parent1, const string& action, const string& nick, const string& url, const string& id, const string& comment, intmax_t sheepGen = 0, intmax_t sheepId = 0)
{
char timeString[128];
time_t myTime;
string s;
xmlDocPtr commentDoc = nullptr;
xmlDocPtr doc = xmlNewDoc(XC("1.0"));
xmlNodePtr rootNode = nullptr, node = nullptr, nodeCopy = nullptr;
xmlNodePtr rootComment = nullptr;
ostringstream os;
//Create the root node, called "edit".
rootNode = xmlNewNode(nullptr, XC("edit"));
xmlDocSetRootElement(doc, rootNode);
//Add the edit attributes.
//Date.
myTime = time(nullptr);
#ifdef _WIN32
tm localt;
localtime_s(&localt, &myTime);
strftime(timeString, 128, "%a %b %d %H:%M:%S %z %Y", &localt);//XXX use standard time format including timezone.
#else
tm* localt;
localt = localtime(&myTime);
strftime(timeString, 128, "%a %b %d %H:%M:%S %z %Y", localt);//XXX use standard time format including timezone.
#endif
xmlNewProp(rootNode, XC("date"), XC(timeString));
//Nick.
if (nick != "")
xmlNewProp(rootNode, XC("nick"), XC(nick.c_str()));
//Url.
if (url != "")
xmlNewProp(rootNode, XC("url"), XC(url.c_str()));
if (id != "")
xmlNewProp(rootNode, XC("id"), XC(id.c_str()));
//Action.
xmlNewProp(rootNode, XC("action"), XC(action.c_str()));
//Sheep info.
if (sheepGen > 0 && sheepId > 0)
{
//Create a child node of the root node called sheep.
node = xmlNewChild(rootNode, nullptr, XC("sheep"), nullptr);
//Create the sheep attributes.
os << sheepGen;
s = os.str();
xmlNewProp(node, XC("generation"), XC(s.c_str()));
os.str("");
os << sheepId;
s = os.str();
xmlNewProp(node, XC("id"), XC(s.c_str()));
os.str("");
}
//Check for the parents.
//If parent 0 not specified, this is a randomly generated genome.
if (parent0)
{
os << parent0->m_Index;
s = os.str();
if (parent0->m_Edits)
{
//Copy the node from the parent.
node = xmlDocGetRootElement(parent0->m_Edits);
nodeCopy = xmlCopyNode(node, 1);
AddFilenameWithoutAmpersand(nodeCopy, parent0->m_ParentFilename);
xmlNewProp(nodeCopy, XC("index"), XC(s.c_str()));
xmlAddChild(rootNode, nodeCopy);
}
else
{
//Insert a (parent has no edit) message.
nodeCopy = xmlNewChild(rootNode, nullptr, XC("edit"), nullptr);
AddFilenameWithoutAmpersand(nodeCopy, parent0->m_ParentFilename);
xmlNewProp(nodeCopy, XC("index"), XC(s.c_str()));
}
os.str("");
}
if (parent1)
{
os << parent1->m_Index;
s = os.str();
if (parent1->m_Edits)
{
//Copy the node from the parent.
node = xmlDocGetRootElement(parent1->m_Edits);
nodeCopy = xmlCopyNode(node, 1);
AddFilenameWithoutAmpersand(nodeCopy, parent1->m_ParentFilename);
xmlNewProp(nodeCopy, XC("index"), XC(s.c_str()));
xmlAddChild(rootNode, nodeCopy);
}
else
{
//Insert a (parent has no edit) message.
nodeCopy = xmlNewChild(rootNode, nullptr, XC("edit"), nullptr);
AddFilenameWithoutAmpersand(nodeCopy, parent1->m_ParentFilename);
xmlNewProp(nodeCopy, XC("index"), XC(s.c_str()));
}
os.str("");
}
//Comment string:
//This one's hard, since the comment string must be treated as
//a valid XML document. Create a new document using the comment
//string as the in-memory document, and then copy all children of
//the root node into the edit structure
//Parsing the comment string should be done once and then copied
//for each new edit doc, but that's for later.
if (comment != "")
{
os << "<comm>" << comment << "</comm>";
s = os.str();
commentDoc = xmlReadMemory(s.c_str(), int(s.length()), "comment.env", nullptr, XML_PARSE_NONET);
os.str("");
//Check for errors.
if (commentDoc)
{
//Loop through the children of the new document and copy them into the rootNode.
rootComment = xmlDocGetRootElement(commentDoc);
for (node = rootComment->children; node; node = node->next)
{
nodeCopy = xmlCopyNode(node, 1);
xmlAddChild(rootNode, nodeCopy);
}
//Free the created document.
xmlFreeDoc(commentDoc);
}
else
{
cout << "Failed to parse comment into Xml.\n";
}
}
//Return the Xml doc.
return doc;
}
bool Save(const string& filename, C<Ember<T>, Alloc>& embers, size_t printEditDepth, bool doEdits, bool hexPalette, bool append = false, bool start = false, bool finish = false);
string ToString(Ember<T>& ember, const string& extraAttributes, size_t printEditDepth, bool doEdits, bool hexPalette = true);
xmlDocPtr CreateNewEditdoc(Ember<T>* parent0, Ember<T>* parent1, const string& action, const string& nick, const string& url, const string& id, const string& comment, intmax_t sheepGen = 0, intmax_t sheepId = 0);
private:
/// <summary>
/// Return the Xml string representation of an xform.
/// </summary>
/// <param name="xform">The xform to create the Xml with</param>
/// <param name="xformCount">The number of non-final xforms in the ember to which this xform belongs. Used for xaos.</param>
/// <param name="isFinal">True if the xform is the final xform in the ember, else false.</param>
/// <param name="doMotion">If true, include motion elements in the Xml string, else omit.</param>
/// <returns>The Xml string representation of the passed in xform</returns>
string ToString(Xform<T>& xform, size_t xformCount, bool isFinal, bool doMotion)
{
size_t i, j;
ostringstream os;
if (doMotion)
{
os << " <motion motion_frequency=\"" << xform.m_MotionFreq << "\" ";
if (xform.m_MotionFunc == eMotion::MOTION_SIN)
os << "motion_function=\"sin\" ";
else if (xform.m_MotionFunc == eMotion::MOTION_TRIANGLE)
os << "motion_function=\"triangle\" ";
else if (xform.m_MotionFunc == eMotion::MOTION_HILL)
os << "motion_function=\"hill\" ";
else if (xform.m_MotionFunc == eMotion::MOTION_SAW)
os << "motion_function=\"saw\" ";
if (xform.m_MotionOffset != 0)
os << "motion_offset=\"" << xform.m_MotionOffset << "\" ";
}
else
{
if (isFinal)
os << " <finalxform ";
else
os << " <xform weight=\"" << xform.m_Weight << "\" ";
}
if (!doMotion || xform.m_ColorX != EMPTYFIELD) os << "color=\"" << xform.m_ColorX << "\" ";
//if (!doMotion || xform.m_ColorY != EMPTYFIELD) os << "color=\"" << xform.m_ColorX << " " << xform.m_ColorY << "\" ";
if (!doMotion || xform.m_DirectColor != EMPTYFIELD) os << "var_color=\"" << xform.m_DirectColor << "\" ";
if (!doMotion || xform.m_ColorSpeed != EMPTYFIELD) os << "color_speed=\"" << xform.m_ColorSpeed << "\" ";
//os << "symmetry=\"" << fabs(xform.m_ColorSpeed - 1) * 2 << "\" ";//Legacy support.
if (!doMotion)
{
string s = xform.m_Name;
std::replace(s.begin(), s.end(), ' ', '_');
os << "name=\"" << s << "\" ";//Flam3 didn't do this, but Apo does.
if (!isFinal)
os << "animate=\"" << xform.m_Animate << "\" ";
}
//Variation writing order differs slightly from the original to make it a bit more readable.
//The original wrote out all of the variation names and weights. Then wrote out the parameters for
//the parametric variations. Here, write out the params immediately after each parametric variation
//so they are more closely grouped with the variation they apply to, rather than being all grouped at the end.
for (i = 0; i < xform.TotalVariationCount(); i++)
{
Variation<T>* var = xform.GetVariation(i);
ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var);
if (var->m_Weight != 0)
{
os << var->Name() << "=\"" << var->m_Weight << "\" ";
if (parVar)
{
auto params = parVar->Params();
for (j = 0; j < parVar->ParamCount(); j++)
{
if ((!doMotion || (doMotion && (params[j].ParamVal() != 0))) && !params[j].IsPrecalc())
os << params[j].Name() << "=\"" << params[j].ParamVal() << "\" ";
}
}
}
}
if (!doMotion || (doMotion && !xform.m_Affine.IsZero() && !xform.m_Affine.IsEmpty()))
{
os << "coefs=\"" << xform.m_Affine.A() << " " << xform.m_Affine.D() << " " << xform.m_Affine.B() << " "
<< xform.m_Affine.E() << " " << xform.m_Affine.C() << " " << xform.m_Affine.F() << "\"";
}
if ((!doMotion && !xform.m_Post.IsID()) || (doMotion && !xform.m_Post.IsZero() && !xform.m_Post.IsEmpty()))
{
os << " post=\"" << xform.m_Post.A() << " " << xform.m_Post.D() << " " << xform.m_Post.B() << " "
<< xform.m_Post.E() << " " << xform.m_Post.C() << " " << xform.m_Post.F() << "\"";
}
//Original only printed xaos values that were not 1. Here, print them all out if any are present.
if (!isFinal && !doMotion && xform.XaosPresent())//Applying motion to xaos not supported.
{
os << " chaos=\"";
for (i = 0; i < xformCount; i++)
os << xform.Xaos(i) << " ";
os << "\"";
}
if (!doMotion || xform.m_Opacity != EMPTYFIELD) os << " opacity=\"" << xform.m_Opacity << "\"";
if (!doMotion && !xform.m_Motion.empty())
{
os << ">\n";
for (i = 0; i < xform.m_Motion.size(); i++)
os << ToString(xform.m_Motion[i], 0, false, true);
if (isFinal)//Fixed to properly close final.//SMOULDER
os << " </finalxform>\n";
else
os << " </xform>\n";
}
else
os << "/>\n";
return os.str();
}
/// <summary>
/// Return an edit node Xml string.
/// </summary>
/// <param name="editNode">The edit node to get the string for</param>
/// <param name="tabs">How many tabs to use</param>
/// <param name="formatting">If true, include newlines and tabs, else don't.</param>
/// <param name="printEditDepth">How deep the edit depth goes</param>
/// <returns>The edit node Xml string</returns>
string ToString(xmlNodePtr editNode, size_t tabs, bool formatting, size_t printEditDepth)
{
bool indentPrinted = false;
const char* tabString = " ", *attStr;
const char* editString = "edit";
const char* sheepString = "sheep";
size_t ti;//, editOrSheep = 0;
xmlAttrPtr attPtr = nullptr, curAtt = nullptr;
xmlNodePtr childPtr = nullptr, curChild = nullptr;
ostringstream os;
if (printEditDepth > 0 && tabs > printEditDepth)
return "";
//If this node is an XML_ELEMENT_NODE, print it and its attributes.
if (editNode->type == XML_ELEMENT_NODE)
{
//Print the node at the tab specified.
if (formatting)
for (ti = 0; ti < tabs; ti++)
os << tabString;
os << "<" << editNode->name;
//This can either be an edit node or a sheep node.
//If it's an edit node, add one to the tab.
if (!Compare(editNode->name, editString))
{
//editOrSheep = 1;
tabs++;
}
else if (!Compare(editNode->name, sheepString)) { }
//editOrSheep = 2;
else { }
//editOrSheep = 0;
//Print the attributes.
attPtr = editNode->properties;
for (curAtt = attPtr; curAtt; curAtt = curAtt->next)
{
attStr = CX(xmlGetProp(editNode, curAtt->name));
os << " " << curAtt->name << "=\"" << attStr << "\"";
xmlFree(reinterpret_cast<void*>(const_cast<char*>(attStr)));
}
//Does this node have children?
if (!editNode->children || (printEditDepth > 0 && tabs > printEditDepth))
{
//Close the tag and subtract the tab.
os << "/>";
if (formatting)
os << "\n";
tabs--;
}
else
{
//Close the tag.
os << ">";
if (formatting)
os << "\n";
//Loop through the children and print them.
childPtr = editNode->children;
indentPrinted = false;
for (curChild = childPtr; curChild; curChild = curChild->next)
{
//If child is an element, indent first and then print it.
if (curChild->type == XML_ELEMENT_NODE &&
(!Compare(curChild->name, editString) || !Compare(curChild->name, sheepString)))
{
if (indentPrinted)
{
indentPrinted = false;
os << "\n";
}
os << ToString(curChild, tabs, true, printEditDepth);
}
else
{
//Child is a text node, don't want to indent more than once.
if (xmlIsBlankNode(curChild))
continue;
if (!indentPrinted && formatting)
{
for (ti = 0; ti < tabs; ti++)
os << tabString;
indentPrinted = true;
}
//Print nodes without formatting.
os << ToString(curChild, tabs, false, printEditDepth);
}
}
if (indentPrinted && formatting)
os << "\n";
tabs--;//Tab out.
if (formatting)
for (ti = 0; ti < tabs; ti++)
os << tabString;
os << "</" << editNode->name << ">";//Close the tag.
if (formatting)
os << "\n";
}
}
else if (editNode->type == XML_TEXT_NODE)
{
string s(reinterpret_cast<char*>(xmlNodeGetContent(editNode)));
os << Trim(s);
}
return os.str();
}
/// <summary>
/// Convert a FlameMotion element to an xml string
/// </summary>
/// <param name="motion">The FlameMotion object to convert to XML</param>
string ToString(const EmberMotion<T>& motion)
{
ostringstream os;
os << "<flame_motion motion_frequency=\"" << motion.m_MotionFreq << "\" ";
if (motion.m_MotionOffset > 0)
os << "motion_offset=\"" << motion.m_MotionOffset << "\" ";
os << "motion_func=";
switch (motion.m_MotionFunc)
{
case eMotion::MOTION_SIN:
os << "\"sin\"";
break;
case eMotion::MOTION_HILL:
os << "\"hill\"";
break;
case eMotion::MOTION_TRIANGLE:
os << "\"triangle\"";
break;
case eMotion::MOTION_SAW:
default:
os << "\"saw\"";
break;
}
T r = 0.0;
T g = 0.0;
T b = 0.0;
T cx = 0.0;
T cy = 0.0;
for (size_t i = 0; i < motion.m_MotionParams.size(); ++i)
{
switch (motion.m_MotionParams[i].first)
{
case eEmberMotionParam::FLAME_MOTION_ZOOM:
os << " zoom=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_ZPOS:
os << " cam_zpos=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_PERSPECTIVE:
os << " cam_persp=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_YAW:
os << " cam_yaw=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_PITCH:
os << " cam_pitch=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_DEPTH_BLUR:
os << " cam_dof=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_CENTER_X:
cx = motion.m_MotionParams[i].second;
break;
case eEmberMotionParam::FLAME_MOTION_CENTER_Y:
cy = motion.m_MotionParams[i].second;
break;
case eEmberMotionParam::FLAME_MOTION_ROTATE:
os << " rotate=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_BRIGHTNESS:
os << " brightness=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_GAMMA:
os << " gamma=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_GAMMA_THRESH:
os << " gamma_threshold=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_HIGHLIGHT_POWER:
os << " highlight_power=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_BACKGROUND_R:
r = motion.m_MotionParams[i].second;
break;
case eEmberMotionParam::FLAME_MOTION_BACKGROUND_G:
g = motion.m_MotionParams[i].second;
break;
case eEmberMotionParam::FLAME_MOTION_BACKGROUND_B:
b = motion.m_MotionParams[i].second;
break;
case eEmberMotionParam::FLAME_MOTION_VIBRANCY:
os << " vibrancy=\"" << motion.m_MotionParams[i].second << "\"";
break;
case eEmberMotionParam::FLAME_MOTION_NONE:
default:
break;
}
}
if (r != 0.0 || g != 0.0 || b != 0.0)
os << " background=\"" << r << " " << g << " " << b << "\"";
if (cx != 0.0 || cy != 0.0)
os << " center=\"" << cx << " " << cy << "\"";
os << "/>\n";
return os.str();
}
void AddFilenameWithoutAmpersand(xmlNodePtr node, string& filename)
{
if (filename.find_first_of('&') != std::string::npos)
{
string filenameWithoutAmpersands = filename;
FindAndReplace<string>(filenameWithoutAmpersands, "&", "&amp;");
xmlNewProp(node, XC("filename"), XC(filenameWithoutAmpersands.c_str()));
}
else
{
xmlNewProp(node, XC("filename"), XC(filename.c_str()));
}
}
string ToString(Xform<T>& xform, size_t xformCount, bool isFinal, bool doMotion);
string ToString(xmlNodePtr editNode, size_t tabs, bool formatting, size_t printEditDepth);
string ToString(const EmberMotion<T>& motion);
void AddFilenameWithoutAmpersand(xmlNodePtr node, string& filename);
};
}

View File

@ -13,6 +13,9 @@ namespace EmberNs
/// The palette stores a set of 256 colors which are what get accumulated to the histogram
/// for each iteration. The colors come from either the main palette Xml file or directly
/// from the ember parameter file. Either way, they come in as 0-255 and get normalized to 0-1.
/// The palette may have also come from a palette editor where the user specifies key colors, then
/// those are interpolated to make a smooth palette. In that case, the m_SourceColors map will
/// be populated.
/// In the future, 2D palette support might be added in which case this class will have to be modified.
/// Template argument expected to be float or double.
/// </summary>
@ -90,13 +93,27 @@ public:
for (size_t i = 0; i < size; i++)
{
m_Entries[i].a = T(palette15[i * 4 + 0]);
m_Entries[i].r = T(palette15[i * 4 + 1]);
m_Entries[i].g = T(palette15[i * 4 + 2]);
m_Entries[i].b = T(palette15[i * 4 + 3]);
m_Entries[i].r = T(palette15[i * 4 + 1]) / T(255);
m_Entries[i].g = T(palette15[i * 4 + 2]) / T(255);
m_Entries[i].b = T(palette15[i * 4 + 3]) / T(255);
}
}
}
/// <summary>
/// Constructor which takes the vector of colors as well as the source colors which were
/// used to create it in a palette editor. The burden is on the user to not let the two get out of sync.
/// </summary>
/// <param name="name">The name of the palette</param>
/// <param name="entries">A vector of color entries</param>
/// <param name="sourceColors">A map of colors which was used to create entries in a palette editor</param>
Palette(const string& name, vector<v4T>& entries, map<T, v4T>& sourceColors)
{
m_Name = name;
m_Entries = entries;
m_SourceColors = sourceColors;
}
/// <summary>
/// Default copy constructor.
/// </summary>
@ -145,6 +162,11 @@ public:
m_Name = palette.m_Name;
m_Filename = palette.m_Filename;
CopyCont(m_Entries, palette.m_Entries);
m_SourceColors.clear();
for (auto& kv : palette.m_SourceColors)
m_SourceColors[T(kv.first)] = v4T(kv.second);
return *this;
}
@ -183,6 +205,13 @@ public:
/// <returns>The size of the color entries vector</returns>
size_t Size() { return m_Entries.size(); }
/// <summary>
/// The size of the source color entries vector which was used to create the palette.
/// Note this will only be non-zero if this palette was created in the palette editor.
/// </summary>
/// <returns>The size of the source colors map</returns>
size_t SourceColorSize() { return m_SourceColors.size(); }
/// <summary>
/// Set all colors to either black or white, including the alpha channel.
/// </summary>
@ -585,5 +614,6 @@ public:
string m_Name = "-";//Name of this palette.
shared_ptr<string> m_Filename;//Name of the parent file this palette came from, can be empty.
vector<v4T> m_Entries;
map<T, v4T> m_SourceColors;
};
}

View File

@ -0,0 +1,779 @@
#include "EmberPch.h"
#include "PaletteList.h"
namespace EmberNs
{
/// <summary>
/// Empty constructor which initializes the palette map with the default palette file.
/// </summary>
template <typename T>
PaletteList<T>::PaletteList()
{
//Add(string(m_DefaultFilename));
}
/// <summary>
/// Destructor which saves any modifiable palettes to file, just in case they were modified.
/// </summary>
template <typename T>
PaletteList<T>::~PaletteList()
{
for (auto& palFile : s_Palettes)
{
if (IsModifiable(palFile.first))
Save(palFile.first);
}
}
/// <summary>
/// Create a new palette file with the given name and vector of palettes, and save it.
/// </summary>
/// <param name="filename">The full path to the file to add</param>
/// <param name="palettes">The list of palettes which comprise the file</param>
/// <returns>True if the file did not exist, was successfully added and saved, else false.</returns>
template <typename T>
bool PaletteList<T>::AddPaletteFile(const string& filename, const vector<Palette<T>>& palettes)
{
if (!GetPaletteListByFullPath(filename))
{
auto item = s_Palettes.insert(make_pair(filename, palettes));
Save(filename);
return true;
}
return false;
}
/// <summary>
/// Create an new empty palette file with the given name with a single modifiable palette in it.
/// </summary>
/// <param name="filename">The full path to the file to add</param>
/// <param name="palettes">The list of palettes which comprise the file</param>
/// <returns>True if the file did not exist, was successfully added and saved, else false.</returns>
template <typename T>
bool PaletteList<T>::AddEmptyPaletteFile(const string& filename)
{
if (!GetPaletteListByFullPath(filename))
{
auto item = s_Palettes.insert(make_pair(filename, vector<Palette<T>>()));
Palette<T> p;
p.m_Index = 0;
p.m_Name = "empty-default";
p.m_Filename = make_shared<string>(filename);
p.m_SourceColors = map<T, v4T>
{
{ T(0), v4T(T(0), T(0), T(0), T(1)) },
{ T(1), v4T(T(0), T(0), T(0), T(1)) }
};
item.first->second.push_back(p);
Save(filename);
return true;
}
return false;
}
/// <summary>
/// Add a new palette to an existing palette file and save the file.
/// </summary>
/// <param name="filename">The full path to the existing palette file to add</param>
/// <param name="palette">The new palette to add to the file</param>
/// <returns>True if the palette file existed, the palette was added, and the file was successfully saved, else false.</returns>
template <typename T>
bool PaletteList<T>::AddPaletteToFile(const string& filename, const Palette<T>& palette)
{
if (auto p = GetPaletteListByFullPathOrFilename(filename))
{
p->push_back(palette);
p->back().m_Index = int(p->size()) - 1;
Save(filename);
return true;
}
return false;
}
/// <summary>
/// Replace an existing palette in a palette file with a new one and save the file.
/// The match is done based on palette name, so if there are duplicate names in
/// the file, only the first one will be replaced.
/// </summary>
/// <param name="filename">The full path to the existing palette file to replace a palette in</param>
/// <param name="palette">The new palette to use to replace an existing one in the file</param>
/// <returns>True if the palette file existed, the palette was replaced, and the file was successfully saved, else false.</returns>
template <typename T>
bool PaletteList<T>::Replace(const string& filename, const Palette<T>& palette)
{
if (auto p = GetPaletteListByFullPathOrFilename(filename))
{
for (auto& pal : *p)
{
if (pal.m_Name == palette.m_Name)
{
auto index = pal.m_Index;
pal = palette;
pal.m_Index = index;
Save(filename);
return true;
}
}
}
return false;
}
/// <summary>
/// Replace an existing palette in a palette file with a new one and save the file.
/// The match is done based on the passed in index.
/// </summary>
/// <param name="filename">The full path to the existing palette file to replace a palette in</param>
/// <param name="palette">The new palette to use to replace an existing one in the file</param>
/// <param name="index">The 0-based index of the palette to replace</param>
/// <returns>True if the palette file existed, the palette was replaced, and the file was successfully saved, else false.</returns>
template <typename T>
bool PaletteList<T>::Replace(const string& filename, const Palette<T>& palette, int index)
{
if (auto p = GetPaletteListByFullPathOrFilename(filename))
{
if (index < p->size())
{
(*p)[index] = palette;
(*p)[index].m_Index = index;
Save(filename);
return true;
}
}
return false;
}
/// <summary>
/// Delete an existing palette from a palette file.
/// The match is done based on the passed in index.
/// </summary>
/// <param name="filename">The full path to the existing palette file to delete a palette from</param>
/// <param name="index">The 0-based index of the palette to delete</param>
/// <returns>True if the palette file existed, the palette was deleted, and the file was successfully saved, else false.</returns>
template <typename T>
bool PaletteList<T>::Delete(const string& filename, int index)
{
int i = 0;
if (auto p = GetPaletteListByFullPathOrFilename(filename))
{
if (index < p->size())
{
p->erase(p->begin() + index);
for (auto& pal : *p)
pal.m_Index = i++;
Save(filename);
return true;
}
}
return false;
}
/// <summary>
/// Read an Xml palette file into memory.
/// This must be called before any palette file usage.
/// </summary>
/// <param name="filename">The full path to the file to read</param>
/// <param name="force">If true, override the initialization state and force a read, else observe the initialization state.</param>
/// <returns>Whether anything was read</returns>
template <typename T>
bool PaletteList<T>::Add(const string& filename, bool force)
{
bool added = true;
bool contains = GetPaletteListByFullPathOrFilename(filename) != nullptr;
auto filenameonly = GetFilename(filename);
if (contains && !force)//Don't allow any palettes with the same name, even if they reside in different paths.
return false;
auto palettes = s_Palettes.insert(make_pair(filename, vector<Palette<T>>()));
if (force || palettes.second)
{
string buf;
const char* loc = __FUNCTION__;
if (ReadFile(filename.c_str(), buf))
{
auto lower = ToLower(filename);
auto pfilename = shared_ptr<string>(new string(filename));
if (EndsWith(lower, ".xml"))
{
xmlDocPtr doc = xmlReadMemory(static_cast<const char*>(buf.data()), int(buf.size()), filename.c_str(), nullptr, XML_PARSE_NONET);
if (doc)
{
auto rootNode = xmlDocGetRootElement(doc);
palettes.first->second.clear();
palettes.first->second.reserve(buf.size() / 2048);//Roughly what it takes per palette.
ParsePalettes(rootNode, pfilename, palettes.first->second);
xmlFreeDoc(doc);
if (palettes.first->second.empty())
{
added = false;//Reading failed, likely not a valid palette file.
s_Palettes.erase(filename);
AddToReport(string(loc) + " : Couldn't parse xml doc");
}
}
else
{
added = false;
s_Palettes.erase(filename);
AddToReport(string(loc) + " : Couldn't load xml doc");
}
}
else if (EndsWith(lower, ".ugr") || EndsWith(lower, ".gradient") || EndsWith(lower, ".gradients"))
{
if (!ParsePalettes(buf, pfilename, palettes.first->second))
{
added = false;
s_Palettes.erase(filename);
AddToReport(string(loc) + " : Couldn't read palette file " + filename);
}
}
}
else
{
added = false;
s_Palettes.erase(filename);
AddToReport(string(loc) + " : Couldn't read palette file " + filename);
}
}
return added;
}
/// <summary>
/// Get the palette at a random index in a random file in the map.
/// </summary>
/// <returns>A pointer to a random palette in a random file if successful, else nullptr.</returns>
template <typename T>
Palette<T>* PaletteList<T>::GetRandomPalette()
{
auto p = s_Palettes.begin();
size_t i = 0, paletteFileIndex = QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand() % Size();
//Move p forward i elements.
while (i < paletteFileIndex && p != s_Palettes.end())
{
++i;
++p;
}
if (i < Size())
{
size_t paletteIndex = QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand() % p->second.size();
if (paletteIndex < p->second.size())
return &p->second[paletteIndex];
}
return nullptr;
}
/// <summary>
/// Get the palette at a specified index in the specified file in the map.
/// </summary>
/// <param name="filename">The filename of the palette to retrieve</param>
/// <param name="i">The index of the palette to read. A value of -1 indicates a random palette.</param>
/// <returns>A pointer to the requested palette if the index was in range, else nullptr.</returns>
template <typename T>
Palette<T>* PaletteList<T>::GetPaletteByFilename(const string& filename, size_t i)
{
if (auto palettes = GetPaletteListByFilename(filename))
if (i < palettes->size())
return &(*palettes)[i];
return nullptr;
}
/// <summary>
/// Get the palette at a specified index in the specified file in the map.
/// </summary>
/// <param name="filename">The full path and filename of the palette to retrieve</param>
/// <param name="i">The index of the palette to read. A value of -1 indicates a random palette.</param>
/// <returns>A pointer to the requested palette if the index was in range, else nullptr.</returns>
template <typename T>
Palette<T>* PaletteList<T>::GetPaletteByFullPath(const string& filename, size_t i)
{
if (auto palettes = GetPaletteListByFullPath(filename))
if (i < palettes->size())
return &(*palettes)[i];
return nullptr;
}
/// <summary>
/// Get a pointer to a palette with a specified name in the specified full path and filename in the map.
/// </summary>
/// <param name="filename">The filename of the palette to retrieve</param>
/// <param name="name">The name of the palette to retrieve</param>
/// <returns>A pointer to the requested palette if found, else nullptr.</returns>
template <typename T>
Palette<T>* PaletteList<T>::GetPaletteByName(const string& filename, const string& name)
{
if (auto palettes = GetPaletteListByFullPathOrFilename(filename))
for (auto& palette : *palettes)
if (palette.m_Name == name)
return &palette;
return nullptr;
}
/// <summary>
/// Get the palette file with the specified filename in the map.
/// </summary>
/// <param name="filename">The filename of the palette to retrieve</param>
/// <returns>A pointer to the requested palette if found, else nullptr.</returns>
template <typename T>
vector<Palette<T>>* PaletteList<T>::GetPaletteListByFilename(const string& filename)
{
auto filenameonly = GetFilename(filename);
for (auto& palettes : s_Palettes)
if (GetFilename(palettes.first) == filenameonly)
return &palettes.second;
return nullptr;
}
/// <summary>
/// Get the palette file with the specified full path and filename in the map.
/// </summary>
/// <param name="filename">The full path and filename of the palette to retrieve</param>
/// <returns>A pointer to the requested palette if found, else nullptr.</returns>
template <typename T>
vector<Palette<T>>* PaletteList<T>::GetPaletteListByFullPath(const string& filename)
{
auto palettes = s_Palettes.find(filename);
if (palettes != s_Palettes.end() && !palettes->second.empty())
return &palettes->second;
return nullptr;
}
/// <summary>
/// Get the palette file with the specified full path and filename in the map.
/// If that does not work, try getting it with the filename alone.
/// </summary>
/// <param name="filename">The full path and filename or just the filename of the palette to retrieve</param>
/// <returns>A pointer to the requested palette if found, else nullptr.</returns>
template <typename T>
vector<Palette<T>>* PaletteList<T>::GetPaletteListByFullPathOrFilename(const string& filename)
{
auto p = GetPaletteListByFullPath(filename);
if (!p)
p = GetPaletteListByFilename(filename);
return p;
}
/// <summary>
/// Get full path and filename of the pallete with the specified filename
/// </summary>
/// <param name="filename">The filename only of the palette to retrieve</param>
/// <returns>A pointer to the requested palette if found, else nullptr.</returns>
template <typename T>
string PaletteList<T>::GetFullPathFromFilename(const string& filename)
{
auto filenameonly = GetFilename(filename);
for (auto& palettes : s_Palettes)
if (GetFilename(palettes.first) == filenameonly)
return palettes.first;
return "";
}
/// <summary>
/// Get a copy of the palette at a specified index in the specified file in the map
/// with its hue adjusted by the specified amount.
/// </summary>
/// <param name="filename">The filename of the palette to retrieve</param>
/// <param name="i">The index of the palette to read.</param>
/// <param name="hue">The hue adjustment to apply</param>
/// <param name="palette">The palette to store the output</param>
/// <returns>True if successful, else false.</returns>
template <typename T>
bool PaletteList<T>::GetHueAdjustedPalette(const string& filename, size_t i, T hue, Palette<T>& palette)
{
if (auto unadjustedPal = GetPaletteByFullPath(filename, i))
{
unadjustedPal->MakeHueAdjustedPalette(palette, hue);
return true;
}
return false;
}
/// <summary>
/// Clear the palette list and reset the initialization state.
/// </summary>
template <typename T>
void PaletteList<T>::Clear()
{
s_Palettes.clear();
}
/// <summary>
/// Get the size of the palettes map.
/// This will be the number of files read.
/// </summary>
/// <returns>The size of the palettes map</returns>
template <typename T>
size_t PaletteList<T>::Size() { return s_Palettes.size(); }
/// <summary>
/// Get the size of specified palette vector in the palettes map.
/// </summary>
/// <param name="index">The index of the palette in the map to retrieve</param>
/// <returns>The size of the palette vector at the specified index in the palettes map</returns>
template <typename T>
size_t PaletteList<T>::Size(size_t index)
{
size_t i = 0;
auto p = s_Palettes.begin();
while (i < index && p != s_Palettes.end())
{
++i;
++p;
}
return p->second.size();
}
/// <summary>
/// Get the size of specified palette vector in the palettes map.
/// </summary>
/// <param name="s">The filename of the palette in the map to retrieve</param>
/// <returns>The size of the palette vector at the specified index in the palettes map</returns>
template <typename T>
size_t PaletteList<T>::Size(const string& s)
{
return s_Palettes[s].size();
}
/// <summary>
/// Get the name of specified palette in the palettes map.
/// </summary>
/// <param name="index">The index of the palette in the map to retrieve</param>
/// <returns>The name of the palette vector at the specified index in the palettes map</returns>
template <typename T>
const string& PaletteList<T>::Name(size_t index)
{
size_t i = 0;
auto p = s_Palettes.begin();
while (i < index && p != s_Palettes.end())
{
++i;
++p;
}
return p->first;
}
/// <summary>
/// Determines whether at least one palette in the passed in palette file is modifiable,
/// meaning whether the source colors have at least one element in them.
/// </summary>
/// <param name="filename">The full path to the existing palette file to search for a modifiable palette in</param>
/// <returns>True if at least one palette in the file was modifiable, else false.</returns>
template <typename T>
bool PaletteList<T>::IsModifiable(const string& filename)
{
if (auto palFile = GetPaletteListByFullPathOrFilename(filename))
{
for (auto& pal : *palFile)
if (!pal.m_SourceColors.empty())
return true;
}
return false;
}
/// <summary>
/// Get a const ref to the underlying static palette structure.
/// </summary>
/// <returns>s_Palettes</returns>
template <typename T>
const map<string, vector<Palette<T>>>& PaletteList<T>::Palettes() const
{
return s_Palettes;
}
/// <summary>
/// Saves an existing file to disk.
/// </summary>
/// <param name="filename">The full path to the existing palette file to save</param>
/// <returns>True if successful, else false.</returns>
template <typename T>
bool PaletteList<T>::Save(const string& filename)
{
auto fullpath = GetFullPathFromFilename(filename);
try
{
size_t index = 0;
ostringstream os;
if (auto palFile = GetPaletteListByFullPathOrFilename(filename))
{
ofstream f(fullpath);
os << "<palettes>\n";
if (f.is_open())
{
for (auto& pal : *palFile)
{
os << "<palette number=\"" << index++ << "\" name=\"" << pal.m_Name << "\"";
if (!pal.m_SourceColors.empty())
{
os << " source_colors=\"";
for (auto& sc : pal.m_SourceColors)//Need to clamp these each from 0 to 1. Use our custom clamp funcs.//TODO
os << sc.first << "," << sc.second.r << "," << sc.second.g << "," << sc.second.b << " ";
os << "\"";
}
os << " data=\"";
for (int i = 0; i < 32; i++)
{
for (int j = 0; j < 8; j++)
{
size_t idx = 8 * i + j;
os << "00";
os << hex << setw(2) << setfill('0') << int(std::rint(pal[idx][0] * 255));
os << hex << setw(2) << setfill('0') << int(std::rint(pal[idx][1] * 255));
os << hex << setw(2) << setfill('0') << int(std::rint(pal[idx][2] * 255));
}
os << "\n";
}
os << "\"/>\n";
}
}
os << "</palettes>";
string s = os.str();
f.write(s.c_str(), s.size());
return true;
}
}
catch (const std::exception& e)
{
cout << "Error: Writing palette file " << fullpath << " failed: " << e.what() << "\n";
return false;
}
catch (...)
{
cout << "Error: Writing palette file " << fullpath << " failed.\n";
return false;
}
return false;
}
/// <summary>
/// Parses an Xml node for all palettes present and stores them in the passed in palette vector.
/// Note that although the Xml color values are expected to be 0-255, they are converted and
/// stored as normalized colors, with values from 0-1.
/// </summary>
/// <param name="node">The parent note of all palettes in the Xml file.</param>
/// <param name="filename">The name of the Xml file.</param>
/// <param name="palettes">The vector to store the parsed palettes associated with this file in.</param>
template <typename T>
void PaletteList<T>::ParsePalettes(xmlNode* node, const shared_ptr<string>& filename, vector<Palette<T>>& palettes)
{
char* val;
xmlAttrPtr attr;
int index = 0;
while (node)
{
if (node->type == XML_ELEMENT_NODE && !Compare(node->name, "palette"))
{
attr = node->properties;
Palette<T> palette;
while (attr)
{
val = reinterpret_cast<char*>(xmlGetProp(node, attr->name));
if (!Compare(attr->name, "data"))
{
string s1, s;
size_t tmp, colorCount = 0;
stringstream ss, temp(val); ss >> std::hex;
s.reserve(2048);
while (temp >> s1)
s += s1;
auto length = s.size();
for (size_t strIndex = 0; strIndex < length;)
{
strIndex += 2;//Skip past the 00 at the beginning of each RGB.
for (glm::length_t i = 0; i < 3 && colorCount < palette.Size(); i++)
{
const char tmpStr[3] = { s[strIndex++], s[strIndex++], 0 };//Read out and convert the string two characters at a time.
ss.clear();//Reset and fill the string stream.
ss.str(tmpStr);
ss >> tmp;//Do the conversion.
palette.m_Entries[colorCount][i] = T(tmp) / T(255);//Hex palette is [0..255], convert to [0..1].
}
colorCount++;
}
}
else if (!Compare(attr->name, "source_colors"))
{
string s(val);
auto vec1 = Split(s, ' ');
for (auto& v : vec1)
{
auto vec2 = Split(v, ',');
if (vec2.size() == 4)
{
float d1 = Clamp(std::stof(vec2[0]), 0.0f, 1.0f);
palette.m_SourceColors[d1] = v4F(Clamp(std::stof(vec2[1]), 0.0f, 1.0f),
Clamp(std::stof(vec2[2]), 0.0f, 1.0f),
Clamp(std::stof(vec2[3]), 0.0f, 1.0f), 1.0f);
}
}
}
else if (!Compare(attr->name, "name"))
{
palette.m_Name = string(val);
}
xmlFree(val);
attr = attr->next;
}
palette.m_Index = index++;
palette.m_Filename = filename;
palettes.push_back(palette);
}
else
{
ParsePalettes(node->children, filename, palettes);
}
node = node->next;
}
}
/// <summary>
/// Parses a gradient file for all palettes present and stores them in the passed in palette vector.
/// Note that although the Xml color values are expected to be 0-255, they are converted and
/// stored as normalized colors, with values from 0-1.
/// This format is from Ultra Fractal and Apophysis.
/// </summary>
/// <param name="buf">The data to parse.</param>
/// <param name="filename">The name of the gradient file.</param>
/// <param name="palettes">The vector to store the parsed palettes associated with this file in.</param>
/// <returns>True if at least one palette is read, else false.</returns>
template <typename T>
bool PaletteList<T>::ParsePalettes(const string& buf, const shared_ptr<string>& filename, vector<Palette<T>>& palettes)
{
int paletteIndex = 0;
size_t index = 0;
string line;
string name;
bool reading = false;
bool found = false;
istringstream iss(buf);
vector<string> splitVec;
const char leftBrace = '{';
const char rightBrace = '}';
const string titleStr = "title=";
const string indexStr = "index=";
const string colorStr = "color=";
const string titleDelStr = " =\"";
const string colorDelStr = " =";
Palette<T> palette;
Color<T> col;
palettes.clear();
while (std::getline(iss, line))
{
if (!reading && Contains(line, leftBrace))
{
reading = true;
}
else if (Contains(line, rightBrace))
{
if (found)
palettes.push_back(palette);
reading = false;
found = false;
}
if (reading)
{
if (Find(line, titleStr))
{
splitVec = Split(line, titleDelStr, true);
if (splitVec.size() > 2)
name = splitVec[1];
}
else if (Find(line, indexStr) && Find(line, colorStr))
{
if (!found)
{
index = 0;
found = true;
palette.Clear();
palette.m_Index = paletteIndex++;
palette.m_Name = name;
palette.m_Filename = filename;
}
splitVec = Split(line, colorDelStr, true);
if (splitVec.size() > 3 && index < 256)
{
int val = std::stoi(splitVec[3]);
col.r = (val & 0xFF) / T(255);//Hex palette is [0..255], convert to [0..1].
col.g = ((val >> 8) & 0xFF) / T(255);
col.b = ((val >> 16) & 0xFF) / T(255);
palette[index] = col;
}
index++;
}
}
}
return !palettes.empty();
}
template EMBER_API class PaletteList<float>;
#ifdef DO_DOUBLE
template EMBER_API class PaletteList<double>;
#endif
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "Palette.h"
#include "Point.h"
/// <summary>
/// PaletteList class.
@ -12,7 +13,11 @@ namespace EmberNs
/// Holds a list of palettes read from an Xml file. Since the default list from flam3-palettes.xml is fairly large at 700 palettes,
/// the list member is kept as a static. This class derives from EmberReport in order to report any errors that occurred while reading the Xml.
/// Note that although the Xml color values are expected to be 0-255, they are converted and stored as normalized colors, with values from 0-1.
/// Template argument expected to be float or double.
/// This can hold read only palettes, as well as user created and modifiable ones.
/// The key in the map is the fully qualified path and filename to each palette file.
/// Despite the keys being full paths, the same filename cannot be inserted twice, even if they reside
/// in different folders. Functions are provided to retrieve palette files via filename only, or full path.
/// Template argument should always be float (which makes the templating of this class pointless).
/// </summary>
template <typename T>
class EMBER_API PaletteList : public EmberReport
@ -20,294 +25,37 @@ class EMBER_API PaletteList : public EmberReport
public:
static const char* m_DefaultFilename;
/// <summary>
/// Empty constructor which initializes the palette map with the default palette file.
/// </summary>
PaletteList()
{
Add(string(m_DefaultFilename));
}
~PaletteList() = default;
PaletteList();
PaletteList(const PaletteList<T>& paletteList) = delete;
/// <summary>
/// Read an Xml palette file into memory.
/// This must be called before any palette file usage.
/// </summary>
/// <param name="filename">The full path to the file to read</param>
/// <param name="force">If true, override the initialization state and force a read, else observe the initialization state.</param>
/// <returns>Whether anything was read</returns>
bool Add(const string& filename, bool force = false)
{
bool added = true;
auto palettes = s_Palettes.insert(make_pair(filename, vector<Palette<T>>()));
if (force || palettes.second)
{
string buf;
const char* loc = __FUNCTION__;
if (ReadFile(filename.c_str(), buf))
{
xmlDocPtr doc = xmlReadMemory(static_cast<const char*>(buf.data()), int(buf.size()), filename.c_str(), nullptr, XML_PARSE_NONET);
if (doc)
{
auto rootNode = xmlDocGetRootElement(doc);
auto pfilename = shared_ptr<string>(new string(filename));
palettes.first->second.clear();
palettes.first->second.reserve(buf.size() / 2048);//Roughly what it takes per palette.
ParsePalettes(rootNode, pfilename, palettes.first->second);
xmlFreeDoc(doc);
if (palettes.first->second.empty())
{
added = false;//Reading failed, likely not a valid palette file.
s_Palettes.erase(filename);
AddToReport(string(loc) + " : Couldn't parse xml doc");
}
}
else
{
added = false;
s_Palettes.erase(filename);
AddToReport(string(loc) + " : Couldn't load xml doc");
}
}
else
{
added = false;
s_Palettes.erase(filename);
AddToReport(string(loc) + " : Couldn't read palette file " + filename);
}
}
return added;
}
/// <summary>
/// Get the palette at a random index in a random file in the map.
/// </summary>
Palette<T>* GetRandomPalette()
{
auto p = s_Palettes.begin();
size_t i = 0, paletteFileIndex = QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand() % Size();
//Move p forward i elements.
while (i < paletteFileIndex && p != s_Palettes.end())
{
++i;
++p;
}
if (i < Size())
{
size_t paletteIndex = QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand() % p->second.size();
if (paletteIndex < p->second.size())
return &p->second[paletteIndex];
}
return nullptr;
}
/// <summary>
/// Get the palette at a specified index in the specified file in the map.
/// </summary>
/// <param name="filename">The filename of the palette to retrieve</param>
/// <param name="i">The index of the palette to read. A value of -1 indicates a random palette.</param>
/// <returns>A pointer to the requested palette if the index was in range, else nullptr.</returns>
Palette<T>* GetPalette(const string& filename, size_t i)
{
auto& palettes = s_Palettes[filename];
if (!palettes.empty() && i < palettes.size())
return &palettes[i];
return nullptr;
}
/// <summary>
/// Get a pointer to a palette with a specified name in the specified file in the map.
/// </summary>
/// <param name="filename">The filename of the palette to retrieve</param>
/// <param name="name">The name of the palette to retrieve</param>
/// <returns>A pointer to the palette if found, else nullptr</returns>
Palette<T>* GetPaletteByName(const string& filename, const string& name)
{
for (auto& palettes : s_Palettes)
if (palettes.first == filename)
for (auto& palette : palettes.second)
if (palette.m_Name == name)
return &palette;
return nullptr;
}
/// <summary>
/// Get a copy of the palette at a specified index in the specified file in the map
/// with its hue adjusted by the specified amount.
/// </summary>
/// <param name="filename">The filename of the palette to retrieve</param>
/// <param name="i">The index of the palette to read.</param>
/// <param name="hue">The hue adjustment to apply</param>
/// <param name="palette">The palette to store the output</param>
/// <returns>True if successful, else false.</returns>
bool GetHueAdjustedPalette(const string& filename, size_t i, T hue, Palette<T>& palette)
{
bool b = false;
if (Palette<T>* unadjustedPal = GetPalette(filename, i))
{
unadjustedPal->MakeHueAdjustedPalette(palette, hue);
b = true;
}
return b;
}
/// <summary>
/// Clear the palette list and reset the initialization state.
/// </summary>
void Clear()
{
s_Palettes.clear();
}
/// <summary>
/// Get the size of the palettes map.
/// This will be the number of files read.
/// </summary>
/// <returns>The size of the palettes map</returns>
size_t Size() { return s_Palettes.size(); }
/// <summary>
/// Get the size of specified palette vector in the palettes map.
/// </summary>
/// <param name="index">The index of the palette in the map to retrieve</param>
/// <returns>The size of the palette vector at the specified index in the palettes map</returns>
size_t Size(size_t index)
{
size_t i = 0;
auto p = s_Palettes.begin();
while (i < index && p != s_Palettes.end())
{
++i;
++p;
}
return p->second.size();
}
/// <summary>
/// Get the size of specified palette vector in the palettes map.
/// </summary>
/// <param name="s">The filename of the palette in the map to retrieve</param>
/// <returns>The size of the palette vector at the specified index in the palettes map</returns>
size_t Size(const string& s)
{
return s_Palettes[s].size();
}
/// <summary>
/// Get the name of specified palette in the palettes map.
/// </summary>
/// <param name="index">The index of the palette in the map to retrieve</param>
/// <returns>The name of the palette vector at the specified index in the palettes map</returns>
const string& Name(size_t index)
{
size_t i = 0;
auto p = s_Palettes.begin();
while (i < index && p != s_Palettes.end())
{
++i;
++p;
}
return p->first;
}
~PaletteList();
bool AddPaletteFile(const string& filename, const vector<Palette<T>>& palettes);
bool AddEmptyPaletteFile(const string& filename);
bool AddPaletteToFile(const string& filename, const Palette<T>& palette);
bool Replace(const string& filename, const Palette<T>& palette);
bool Replace(const string& filename, const Palette<T>& palette, int index);
bool Delete(const string& filename, int index);
bool Add(const string& filename, bool force = false);
Palette<T>* GetRandomPalette();
Palette<T>* GetPaletteByFilename(const string& filename, size_t i);
Palette<T>* GetPaletteByFullPath(const string& filename, size_t i);
Palette<T>* GetPaletteByName(const string& filename, const string& name);
vector<Palette<T>>* GetPaletteListByFilename(const string& filename);
vector<Palette<T>>* GetPaletteListByFullPath(const string& filename);
vector<Palette<T>>* GetPaletteListByFullPathOrFilename(const string& filename);
string GetFullPathFromFilename(const string& filename);
bool GetHueAdjustedPalette(const string& filename, size_t i, T hue, Palette<T>& palette);
void Clear();
size_t Size();
size_t Size(size_t index);
size_t Size(const string& s);
const string& Name(size_t index);
bool IsModifiable(const string& filename);
const map<string, vector<Palette<T>>>& Palettes() const;
private:
/// <summary>
/// Parses an Xml node for all palettes present and stores them in the passed in palette vector.
/// Note that although the Xml color values are expected to be 0-255, they are converted and
/// stored as normalized colors, with values from 0-1.
/// </summary>
/// <param name="node">The parent note of all palettes in the Xml file.</param>
/// <param name="filename">The name of the Xml file.</param>
/// <param name="palettes">The vector to store the paresed palettes associated with this file in.</param>
void ParsePalettes(xmlNode* node, const shared_ptr<string>& filename, vector<Palette<T>>& palettes)
{
char* val;
const char* loc = __FUNCTION__;
xmlAttrPtr attr;
while (node)
{
if (node->type == XML_ELEMENT_NODE && !Compare(node->name, "palette"))
{
attr = node->properties;
Palette<T> palette;
while (attr)
{
val = reinterpret_cast<char*>(xmlGetProp(node, attr->name));
if (!Compare(attr->name, "data"))
{
string s1, s;
size_t tmp, colorCount = 0, colorIndex = 0;
stringstream ss, temp(val); ss >> std::hex;
s.reserve(2048);
while (temp >> s1)
s += s1;
auto length = s.size();
for (size_t strIndex = 0; strIndex < length;)
{
strIndex += 2;//Skip past the 00 at the beginning of each RGB.
for (glm::length_t i = 0; i < 3 && colorCount < palette.Size(); i++)
{
const char tmpStr[3] = { s[strIndex++], s[strIndex++], 0 };//Read out and convert the string two characters at a time.
ss.clear();//Reset and fill the string stream.
ss.str(tmpStr);
ss >> tmp;//Do the conversion.
palette.m_Entries[colorCount][i] = T(tmp) / T(255);//Hex palette is [0..255], convert to [0..1].
}
colorCount++;
}
}
else if (!Compare(attr->name, "number"))
{
palette.m_Index = atoi(val);
}
else if (!Compare(attr->name, "name"))
{
palette.m_Name = string(val);
}
xmlFree(val);
attr = attr->next;
}
palette.m_Filename = filename;
palettes.push_back(palette);
}
else
{
ParsePalettes(node->children, filename, palettes);
}
node = node->next;
}
}
bool Save(const string& filename);
void ParsePalettes(xmlNode* node, const shared_ptr<string>& filename, vector<Palette<T>>& palettes);
bool ParsePalettes(const string& buf, const shared_ptr<string>& filename, vector<Palette<T>>& palettes);
static map<string, vector<Palette<T>>> s_Palettes;//The map of filenames to vectors that store the palettes.
};

View File

@ -60,25 +60,6 @@ bool Renderer<T, bucketT>::AssignIterator()
template <typename T, typename bucketT>
void Renderer<T, bucketT>::ComputeBounds()
{
//size_t maxDEFilterWidth = 0;
//Use type T to account for negative numbers which will occur with a larger supersample and smaller filter width.
//The final value will be of type size_t.
//m_GutterWidth = size_t(ClampGte<T>((T(m_SpatialFilter->FinalFilterWidth()) - T(Supersample())) / 2, 0));
//
////Check the size of the density estimation filter.
////If the radius of the density estimation filter is greater than the
////gutter width, have to pad with more. Otherwise, use the same value.
//for (auto& ember : *m_EmbersP)
// maxDEFilterWidth = std::max<size_t>(size_t(ceil(ember.m_MaxRadDE) * m_Ember.m_Supersample), maxDEFilterWidth);
//
////Need an extra ss = (int)floor(m_Supersample / 2.0) of pixels so that a local iteration count for DE can be determined.//SMOULDER
//if (maxDEFilterWidth > 0)
// maxDEFilterWidth += size_t(Floor<T>(m_Ember.m_Supersample / T(2)));
//To have a fully present set of pixels for the spatial filter, must
//add the DE filter width to the spatial filter width.//SMOULDER
//m_DensityFilterOffset = maxDEFilterWidth;
//m_GutterWidth += m_DensityFilterOffset;
//
//Original did a lot of work to compute a gutter that changes size based on various parameters, which seems to be of no benefit.
//It also prevents the renderer from only performing filtering or final accum based on a filter parameter change, since that
//change may have changed the gutter.
@ -720,7 +701,7 @@ EmberImageComments Renderer<T, bucketT>::ImageComments(const EmberStats& stats,
template <typename T, typename bucketT>
void Renderer<T, bucketT>::MakeDmap(T colorScalar)
{
m_Ember.m_Palette.template MakeDmap<bucketT>(m_Dmap, colorScalar);
m_Ember.m_Palette.template MakeDmap<bucketT>(m_Dmap, bucketT(colorScalar));
}
/// <summary>
@ -863,48 +844,33 @@ eRenderStatus Renderer<T, bucketT>::LogScaleDensityFilter(bool forceOutput)
size_t endRow = m_SuperRasH;
size_t endCol = m_SuperRasW;
//Timing t(4);
//if (forceOutput)//Assume interactive render, so speed up at the expense of slight quality.
//{
// parallel_for(startRow, endRow, [&](size_t j)
// {
// if (!m_Abort)
// {
// size_t row = j * m_SuperRasW;
// size_t rowEnd = row + endCol;
// VectorizedLogScale(row, rowEnd);
// }
// });
//}
//else
//Original didn't parallelize this, doing so gives a 50-75% speedup.
//The value can be directly assigned, which is quicker than summing.
parallel_for(startRow, endRow, size_t(1), [&](size_t j)
{
//Original didn't parallelize this, doing so gives a 50-75% speedup.
//The value can be directly assigned, which is quicker than summing.
parallel_for(startRow, endRow, [&](size_t j)
size_t row = j * m_SuperRasW;
size_t rowEnd = row + endCol;
if (!m_Abort)
{
size_t row = j * m_SuperRasW;
size_t rowEnd = row + endCol;
if (!m_Abort)
for (size_t i = row; i < rowEnd; i++)
{
for (size_t i = row; i < rowEnd; i++)
//Check for visibility first before doing anything else to avoid all possible unnecessary calculations.
if (m_HistBuckets[i].a != 0)
{
//Check for visibility first before doing anything else to avoid all possible unnecessary calculations.
if (m_HistBuckets[i].a != 0)
{
bucketT logScale = (m_K1 * std::log(1 + m_HistBuckets[i].a * m_K2)) / m_HistBuckets[i].a;
//Original did a temporary assignment, then *= logScale, then passed the result to bump_no_overflow().
//Combine here into one operation for a slight speedup.
//Vectorized version:
bucketT* __restrict hist = glm::value_ptr(m_HistBuckets[i]);//Vectorizer can't tell these point to different locations.
bucketT* __restrict acc = glm::value_ptr(m_AccumulatorBuckets[i]);
bucketT logScale = (m_K1 * std::log(1 + m_HistBuckets[i].a * m_K2)) / m_HistBuckets[i].a;
//Original did a temporary assignment, then *= logScale, then passed the result to bump_no_overflow().
//Combine here into one operation for a slight speedup.
//Vectorized version:
bucketT* __restrict hist = glm::value_ptr(m_HistBuckets[i]);//Vectorizer can't tell these point to different locations.
bucketT* __restrict acc = glm::value_ptr(m_AccumulatorBuckets[i]);
for (size_t v = 0; v < 4; v++)
acc[v] = hist[v] * logScale;
}
for (size_t v = 0; v < 4; v++)
acc[v] = hist[v] * logScale;
}
}
});
}
}
});
//t.Toc(__FUNCTION__);
return m_Abort ? eRenderStatus::RENDER_ABORT : eRenderStatus::RENDER_OK;
}
@ -930,7 +896,7 @@ eRenderStatus Renderer<T, bucketT>::GaussianDensityFilter()
intmax_t endCol = m_SuperRasW - (Supersample() - 1);
size_t chunkSize = size_t(ceil(double(endRow - startRow) / double(threads)));
//parallel_for scales very well, dividing the work almost perfectly among all processors.
parallel_for(size_t(0), threads, [&] (size_t threadIndex)
parallel_for(size_t(0), threads, size_t(1), [&] (size_t threadIndex)
{
size_t pixelNumber = 0;
int localStartRow = int(std::min<size_t>(startRow + (threadIndex * chunkSize), endRow - 1));
@ -1115,7 +1081,7 @@ eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(byte* pixels, size_t
//The original does it this way as well and it's roughly 11 times faster to do it this way than inline below with each pixel.
if (EarlyClip())
{
parallel_for(size_t(0), m_SuperRasH, [&] (size_t j)
parallel_for(size_t(0), m_SuperRasH, size_t(1), [&] (size_t j)
{
auto rowStart = m_AccumulatorBuckets.data() + (j * m_SuperRasW);//Pull out of inner loop for optimization.
auto rowEnd = rowStart + m_SuperRasW;
@ -1138,7 +1104,7 @@ eRenderStatus Renderer<T, bucketT>::AccumulatorToFinalImage(byte* pixels, size_t
//otherwise artifacts that resemble page tearing will occur in an interactive run. It's
//critical to never exit this loop prematurely.
//for (size_t j = 0; j < FinalRasH(); j++)//Keep around for debugging.
parallel_for(size_t(0), FinalRasH(), [&](size_t j)
parallel_for(size_t(0), FinalRasH(), size_t(1), [&](size_t j)
{
Color<bucketT> newBucket;
size_t pixelsRowStart = (m_YAxisUp ? ((FinalRasH() - j) - 1) : j) * FinalRowSize();//Pull out of inner loop for optimization.
@ -1300,13 +1266,13 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample
m_ThreadEmbers.insert(m_ThreadEmbers.begin(), m_ThreadsToUse, m_Ember);
}
parallel_for(size_t(0), m_ThreadsToUse, [&] (size_t threadIndex)
parallel_for(size_t(0), m_ThreadsToUse, size_t(1), [&] (size_t threadIndex)
{
#if defined(_WIN32)
SetThreadPriority(GetCurrentThread(), int(m_Priority));
#elif defined(__APPLE__)
sched_param sp = {0};
sp.sched_priority = m_Priority;
sp.sched_priority = int(m_Priority);
pthread_setschedparam(pthread_self(), SCHED_RR, &sp);
#else
pthread_setschedprio(pthread_self(), int(m_Priority));
@ -1441,31 +1407,31 @@ template <typename T, typename bucketT> DensityFilterBase* Renderer<T, bucketT>:
/// Non-virtual ember wrappers, getters only.
/// </summary>
template <typename T, typename bucketT> bool Renderer<T, bucketT>::XaosPresent() const { return m_Ember.XaosPresent(); }
template <typename T, typename bucketT> size_t Renderer<T, bucketT>::Supersample() const { return m_Ember.m_Supersample; }
template <typename T, typename bucketT> size_t Renderer<T, bucketT>::PaletteIndex() const { return m_Ember.PaletteIndex(); }
template <typename T, typename bucketT> T Renderer<T, bucketT>::Time() const { return m_Ember.m_Time; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::Quality() const { return m_Ember.m_Quality; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::SpatialFilterRadius() const { return m_Ember.m_SpatialFilterRadius; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::PixelsPerUnit() const { return m_Ember.m_PixelsPerUnit; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::Zoom() const { return m_Ember.m_Zoom; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::CenterX() const { return m_Ember.m_CenterX; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::CenterY() const { return m_Ember.m_CenterY; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::Rotate() const { return m_Ember.m_Rotate; }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::Brightness() const { return bucketT(m_Ember.m_Brightness); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::Gamma() const { return bucketT(m_Ember.m_Gamma); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::Vibrancy() const { return bucketT(m_Ember.m_Vibrancy); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::GammaThresh() const { return bucketT(m_Ember.m_GammaThresh); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::HighlightPower() const { return bucketT(m_Ember.m_HighlightPower); }
template <typename T, typename bucketT> Color<T> Renderer<T, bucketT>::Background() const { return m_Ember.m_Background; }
template <typename T, typename bucketT> const Xform<T>* Renderer<T, bucketT>::Xforms() const { return m_Ember.Xforms(); }
template <typename T, typename bucketT> Xform<T>* Renderer<T, bucketT>::NonConstXforms() { return m_Ember.NonConstXforms(); }
template <typename T, typename bucketT> size_t Renderer<T, bucketT>::XformCount() const { return m_Ember.XformCount(); }
template <typename T, typename bucketT> const Xform<T>* Renderer<T, bucketT>::FinalXform() const { return m_Ember.FinalXform(); }
template <typename T, typename bucketT> Xform<T>* Renderer<T, bucketT>::NonConstFinalXform() { return m_Ember.NonConstFinalXform(); }
template <typename T, typename bucketT> bool Renderer<T, bucketT>::UseFinalXform() const { return m_Ember.UseFinalXform(); }
template <typename T, typename bucketT> const Palette<T>* Renderer<T, bucketT>::GetPalette() const { return &m_Ember.m_Palette; }
template <typename T, typename bucketT> ePaletteMode Renderer<T, bucketT>::PaletteMode() const { return m_Ember.m_PaletteMode; }
template <typename T, typename bucketT> bool Renderer<T, bucketT>::XaosPresent() const { return m_Ember.XaosPresent(); }
template <typename T, typename bucketT> size_t Renderer<T, bucketT>::Supersample() const { return m_Ember.m_Supersample; }
template <typename T, typename bucketT> size_t Renderer<T, bucketT>::PaletteIndex() const { return m_Ember.PaletteIndex(); }
template <typename T, typename bucketT> T Renderer<T, bucketT>::Time() const { return m_Ember.m_Time; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::Quality() const { return m_Ember.m_Quality; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::SpatialFilterRadius() const { return m_Ember.m_SpatialFilterRadius; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::PixelsPerUnit() const { return m_Ember.m_PixelsPerUnit; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::Zoom() const { return m_Ember.m_Zoom; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::CenterX() const { return m_Ember.m_CenterX; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::CenterY() const { return m_Ember.m_CenterY; }
template <typename T, typename bucketT> T Renderer<T, bucketT>::Rotate() const { return m_Ember.m_Rotate; }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::Brightness() const { return bucketT(m_Ember.m_Brightness); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::Gamma() const { return bucketT(m_Ember.m_Gamma); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::Vibrancy() const { return bucketT(m_Ember.m_Vibrancy); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::GammaThresh() const { return bucketT(m_Ember.m_GammaThresh); }
template <typename T, typename bucketT> bucketT Renderer<T, bucketT>::HighlightPower() const { return bucketT(m_Ember.m_HighlightPower); }
template <typename T, typename bucketT> Color<T> Renderer<T, bucketT>::Background() const { return m_Ember.m_Background; }
template <typename T, typename bucketT> const Xform<T>* Renderer<T, bucketT>::Xforms() const { return m_Ember.Xforms(); }
template <typename T, typename bucketT> Xform<T>* Renderer<T, bucketT>::NonConstXforms() { return m_Ember.NonConstXforms(); }
template <typename T, typename bucketT> size_t Renderer<T, bucketT>::XformCount() const { return m_Ember.XformCount(); }
template <typename T, typename bucketT> const Xform<T>* Renderer<T, bucketT>::FinalXform() const { return m_Ember.FinalXform(); }
template <typename T, typename bucketT> Xform<T>* Renderer<T, bucketT>::NonConstFinalXform() { return m_Ember.NonConstFinalXform(); }
template <typename T, typename bucketT> bool Renderer<T, bucketT>::UseFinalXform() const { return m_Ember.UseFinalXform(); }
template <typename T, typename bucketT> const Palette<float>* Renderer<T, bucketT>::GetPalette() const { return &m_Ember.m_Palette; }
template <typename T, typename bucketT> ePaletteMode Renderer<T, bucketT>::PaletteMode() const { return m_Ember.m_PaletteMode; }
/// <summary>
/// Virtual ember wrappers overridden from RendererBase, getters only.
@ -1528,53 +1494,52 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
{
size_t histIndex, intColorIndex, histSize = m_HistBuckets.size();
bucketT colorIndex, colorIndexFrac;
auto dmap = palette->m_Entries.data();
//It's critical to understand what's going on here as it's one of the most important parts of the algorithm.
//A color value gets retrieved from the palette and
//its RGB values are added to the existing RGB values in the histogram bucket.
//Alpha is always 1 in the palettes, so that serves as the hit count.
//This differs from the original since redundantly adding both an alpha component and a hit count is omitted.
//This will eventually leave us with large values for pixels with many hits, which will be log scaled down later.
//Original used a function called bump_no_overflow(). Just do a straight add because the type will always be float or double.
//Doing so gives a 25% speed increase.
//Splitting these conditionals into separate loops makes no speed difference.
for (size_t i = 0; i < sampleCount && !m_Abort; i++)
//Linear is a linear scale for when the color index is not a whole number, which is most of the time.
//It uses a portion of the value of the index, and the remainder of the next index.
//Example: index = 25.7
//Fraction = 0.7
//Color = (dmap[25] * 0.3) + (dmap[26] * 0.7)
//Use overloaded addition and multiplication operators in vec4 to perform the accumulation.
if (PaletteMode() == ePaletteMode::PALETTE_LINEAR)
{
Point<T> p(samples[i]);//Slightly faster to cache this.
if (Rotate() != 0)
//It's critical to understand what's going on here as it's one of the most important parts of the algorithm.
//A color value gets retrieved from the palette and
//its RGB values are added to the existing RGB values in the histogram bucket.
//Alpha is always 1 in the palettes, so that serves as the hit count.
//This differs from the original since redundantly adding both an alpha component and a hit count is omitted.
//This will eventually leave us with large values for pixels with many hits, which will be log scaled down later.
//Original used a function called bump_no_overflow(). Just do a straight add because the type will always be float or double.
//Doing so gives a 25% speed increase.
//Splitting these conditionals into separate loops makes no speed difference.
for (size_t i = 0; i < sampleCount && !m_Abort; i++)
{
T p00 = p.m_X - CenterX();
T p11 = p.m_Y - m_Ember.m_RotCenterY;
p.m_X = (p00 * m_RotMat.A()) + (p11 * m_RotMat.B()) + CenterX();
p.m_Y = (p00 * m_RotMat.D()) + (p11 * m_RotMat.E()) + m_Ember.m_RotCenterY;
}
Point<T> p(samples[i]);//Slightly faster to cache this.
//Checking this first before converting gives better performance than converting and checking a single value, which the original did.
//Second, an interesting optimization observation is that when keeping the bounds vars within m_CarToRas and calling its InBounds() member function,
//rather than here as members, about a 7% speedup is achieved. This is possibly due to the fact that data from m_CarToRas is accessed
//right after the call to Convert(), so some caching efficiencies get realized.
if (m_CarToRas.InBounds(p))
{
if (p.m_VizAdjusted != 0)
if (Rotate() != 0)
{
m_CarToRas.Convert(p, histIndex);
T p00 = p.m_X - CenterX();
T p11 = p.m_Y - m_Ember.m_RotCenterY;
p.m_X = (p00 * m_RotMat.A()) + (p11 * m_RotMat.B()) + CenterX();
p.m_Y = (p00 * m_RotMat.D()) + (p11 * m_RotMat.E()) + m_Ember.m_RotCenterY;
}
//There is a very slim chance that a point will be right on the border and will technically be in bounds, passing the InBounds() test,
//but ends up being mapped to a histogram bucket that is out of bounds due to roundoff error. Perform one final check before proceeding.
//This will result in a few points at the very edges getting discarded, but prevents a crash and doesn't seem to make a speed difference.
if (histIndex < histSize)
//Checking this first before converting gives better performance than converting and checking a single value, which the original did.
//Second, an interesting optimization observation is that when keeping the bounds vars within m_CarToRas and calling its InBounds() member function,
//rather than here as members, about a 7% speedup is achieved. This is possibly due to the fact that data from m_CarToRas is accessed
//right after the call to Convert(), so some caching efficiencies get realized.
if (m_CarToRas.InBounds(p))
{
if (p.m_VizAdjusted != 0)
{
//Linear is a linear scale for when the color index is not a whole number, which is most of the time.
//It uses a portion of the value of the index, and the remainder of the next index.
//Example: index = 25.7
//Fraction = 0.7
//Color = (dmap[25] * 0.3) + (dmap[26] * 0.7)
//Use overloaded addition and multiplication operators in vec4 to perform the accumulation.
if (PaletteMode() == ePaletteMode::PALETTE_LINEAR)
m_CarToRas.Convert(p, histIndex);
//There is a very slim chance that a point will be right on the border and will technically be in bounds, passing the InBounds() test,
//but ends up being mapped to a histogram bucket that is out of bounds due to roundoff error. Perform one final check before proceeding.
//This will result in a few points at the very edges getting discarded, but prevents a crash and doesn't seem to make a speed difference.
if (histIndex < histSize)
{
colorIndex = bucketT(p.m_ColorX) * COLORMAP_LENGTH;
colorIndex = bucketT(p.m_ColorX) * COLORMAP_LENGTH_MINUS_1;
intColorIndex = size_t(colorIndex);
if (intColorIndex < 0)
@ -1614,9 +1579,33 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
hist[3] += ((pal[3] * cifm1) + (pal2[3] * colorIndexFrac)) * va;
}
}
else if (PaletteMode() == ePaletteMode::PALETTE_STEP)
}
}
}
}
else if (PaletteMode() == ePaletteMode::PALETTE_STEP)//Duplicate of above, but for step mode.
{
for (size_t i = 0; i < sampleCount && !m_Abort; i++)
{
Point<T> p(samples[i]);//Slightly faster to cache this.
if (Rotate() != 0)
{
T p00 = p.m_X - CenterX();
T p11 = p.m_Y - m_Ember.m_RotCenterY;
p.m_X = (p00 * m_RotMat.A()) + (p11 * m_RotMat.B()) + CenterX();
p.m_Y = (p00 * m_RotMat.D()) + (p11 * m_RotMat.E()) + m_Ember.m_RotCenterY;
}
if (m_CarToRas.InBounds(p))
{
if (p.m_VizAdjusted != 0)
{
m_CarToRas.Convert(p, histIndex);
if (histIndex < histSize)
{
intColorIndex = Clamp<size_t>(size_t(p.m_ColorX * COLORMAP_LENGTH), 0, COLORMAP_LENGTH_MINUS_1);
intColorIndex = Clamp<size_t>(size_t(p.m_ColorX * COLORMAP_LENGTH_MINUS_1), 0, COLORMAP_LENGTH_MINUS_1);
bucketT* __restrict hist = glm::value_ptr(m_HistBuckets[histIndex]);//Vectorizer can't tell these point to different locations.
const bucketT* __restrict pal = glm::value_ptr(palette->m_Entries[intColorIndex]);
@ -1654,7 +1643,13 @@ template <typename T, typename bucketT>
void Renderer<T, bucketT>::AddToAccum(const tvec4<bucketT, glm::defaultp>& bucket, intmax_t i, intmax_t ii, intmax_t j, intmax_t jj)
{
if (j + jj >= 0 && j + jj < intmax_t(m_SuperRasH) && i + ii >= 0 && i + ii < intmax_t(m_SuperRasW))
m_AccumulatorBuckets[(i + ii) + ((j + jj) * m_SuperRasW)] += bucket;
{
auto* __restrict accum = m_AccumulatorBuckets.data() + ((i + ii) + ((j + jj) * m_SuperRasW));//For vectorizer, results in a 33% speedup.
accum->r += bucket.r;
accum->g += bucket.g;
accum->b += bucket.b;
accum->a += bucket.a;
}
}
/// <summary>

View File

@ -107,33 +107,33 @@ public:
virtual DensityFilterBase* GetDensityFilter() override;
//Non-virtual ember wrappers, getters only.
inline bool XaosPresent() const;
inline size_t Supersample() const;
inline size_t PaletteIndex() const;
inline T Time() const;
inline T Quality() const;
inline T SpatialFilterRadius() const;
inline T PixelsPerUnit() const;
inline T Zoom() const;
inline T CenterX() const;
inline T CenterY() const;
inline T Rotate() const;
inline T Hue() const;
inline bucketT Brightness() const;
inline bucketT Contrast() const;
inline bucketT Gamma() const;
inline bucketT Vibrancy() const;
inline bucketT GammaThresh() const;
inline bucketT HighlightPower() const;
inline Color<T> Background() const;
inline const Xform<T>* Xforms() const;
inline Xform<T>* NonConstXforms();
inline size_t XformCount() const;
inline const Xform<T>* FinalXform() const;
inline Xform<T>* NonConstFinalXform();
inline bool UseFinalXform() const;
inline const Palette<T>* GetPalette() const;
inline ePaletteMode PaletteMode() const;
inline bool XaosPresent() const;
inline size_t Supersample() const;
inline size_t PaletteIndex() const;
inline T Time() const;
inline T Quality() const;
inline T SpatialFilterRadius() const;
inline T PixelsPerUnit() const;
inline T Zoom() const;
inline T CenterX() const;
inline T CenterY() const;
inline T Rotate() const;
inline T Hue() const;
inline bucketT Brightness() const;
inline bucketT Contrast() const;
inline bucketT Gamma() const;
inline bucketT Vibrancy() const;
inline bucketT GammaThresh() const;
inline bucketT HighlightPower() const;
inline Color<T> Background() const;
inline const Xform<T>* Xforms() const;
inline Xform<T>* NonConstXforms();
inline size_t XformCount() const;
inline const Xform<T>* FinalXform() const;
inline Xform<T>* NonConstFinalXform();
inline bool UseFinalXform() const;
inline const Palette<float>* GetPalette() const;
inline ePaletteMode PaletteMode() const;
//Virtual ember wrappers overridden from RendererBase, getters only.
virtual size_t TemporalSamples() const override;

View File

@ -597,7 +597,6 @@ public:
int var, samed, multid, samepost;
glm::length_t i, j, k, n;
size_t varCount = m_VariationList->Size();
Palette<T> palette;
static size_t xformDistrib[] =
{
2, 2, 2, 2,
@ -863,8 +862,8 @@ public:
for (i = 0; i < m_Renderer->FinalDimensions(); i++)
{
m_Hist[(p[0] * res / 256) +
(p[1] * res / 256) * res +
(p[2] * res / 256) * res * res]++;//A specific histogram index representing the sum of R,G,B values.
(p[1] * res / 256) * res +
(p[2] * res / 256) * res * res]++;//A specific histogram index representing the sum of R,G,B values.
p += m_Renderer->PixelSize();//Advance the pointer by 1 pixel.
}
@ -1366,7 +1365,7 @@ private:
unique_ptr<XaosIterator<T>> m_XaosIterator = make_unique<XaosIterator<T>>();
unique_ptr<Renderer<T, bucketT>> m_Renderer;
QTIsaac<ISAAC_SIZE, ISAAC_INT> m_Rand;
PaletteList<T> m_PaletteList;
PaletteList<float> m_PaletteList;
shared_ptr<VariationList<T>> m_VariationList;
};
}

View File

@ -53,6 +53,18 @@ static inline bool Contains(c& container, const T& val)
return std::find_if(container.begin(), container.end(), [&](const T & t) -> bool { return t == val; }) != container.end();
}
/// <summary>
/// Thin specialization for string because the compiler can't figure out the container template type
/// when passing string to the function above.
/// </summary>
/// <param name="str1">The string to call find() on</param>
/// <param name="str2">The string to search for</param>
/// <returns>True if str2 was present at least once, else false.</returns>
static bool Find(const string& str1, const string& str2)
{
return str1.find(str2) != string::npos;
}
/// <summary>
/// Thin wrapper around computing the total size of a vector.
/// </summary>
@ -284,16 +296,21 @@ static bool ReadFile(const char* filename, string& buf, bool nullTerminate = tru
{
try
{
ifstream ifs(filename, ios::binary | ios::ate);
auto pos = ifs.tellg();
buf.resize(pos + streampos(nullTerminate ? 1 : 0));
ifs.seekg(0, ios::beg);
ifs.read(&buf[0], pos);
ifstream ifs;
ifs.exceptions(ifstream::failbit);
ifs.open(filename, ios::binary | ios::ate);
if (nullTerminate)//Optionally NULL terminate if they want to treat it as a string.
buf[buf.size() - 1] = 0;
if (auto pos = ifs.tellg())//Ensure it exists and wasn't empty.
{
buf.resize(pos + streampos(nullTerminate ? 1 : 0));
ifs.seekg(0, ios::beg);
ifs.read(&buf[0], pos);
return true;
if (nullTerminate)//Optionally NULL terminate if they want to treat it as a string.
buf[buf.size() - 1] = 0;
return true;
}
}
catch (const std::exception& e)
{
@ -812,6 +829,18 @@ static inline T NormalizeDeg180(T angle)
return a;
}
/// <summary>
/// Determine whether the passed in string ends with the passed in suffix, case sensitive.
/// </summary>
/// <param name="str">The string to test</param>
/// <param name="suffix">The string to test for</param>
/// <returns>True if str ends with suffix, else false.</returns>
static bool EndsWith(const std::string& str, const std::string& suffix)
{
return str.size() >= suffix.size() &&
str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
}
/// <summary>
/// Return a lower case copy of a string.
/// </summary>
@ -867,21 +896,61 @@ static string Trim(const string& str, char ch = ' ')
}
/// <summary>
/// Return a copy of a file path string with the path portion removed.
/// Split a string into tokens and place them in a vector.
/// </summary>
/// <param name="str">The string to split</param>
/// <param name="del">The delimiter to split the string on. Note that only one character has to match, so this is a good way to use multiple delimiters</param>
/// <param name="removeEmpty">True to omit empty strings, else false to keep them.</param>
/// <returns>The vector containing the split tokens</returns>
static vector<std::string> Split(const string& str, const string& del, bool removeEmpty = false)
{
int current = 0;
int next = -1;
vector<string> vec;
do
{
current = next + 1;
next = int(str.find_first_of(del, current));
string ent(Trim(str.substr(current, next - current)));
if (!removeEmpty || ent.length() > 0)
vec.push_back(ent);
}
while (next != int(string::npos));
return vec;
}
/// <summary>
/// Return a copy of a file path string with the file portion removed.
/// </summary>
/// <param name="filename">The string to retrieve the path from</param>
/// <returns>The path portion of the string</returns>
static string GetPath(const string& filename)
{
const size_t lastSlash = filename.find_last_of("\\/");
if (std::string::npos != lastSlash)
return filename.substr(0, lastSlash + 1);
else
return filename;
}
/// <summary>
/// Return a copy of a file path string with the path portion removed.
/// </summary>
/// <param name="filename">The string to retrieve the filename from</param>
/// <returns>The filename portion of the string</returns>
static string GetFilename(const string& filename)
{
string s;
const size_t lastSlash = filename.find_last_of("\\/");
if (std::string::npos != lastSlash)
s = filename.substr(0, lastSlash + 1);
return filename.substr(lastSlash + 1, filename.size() - lastSlash);
else
s = "";
return s;
return filename;
}
/// <summary>

View File

@ -44,329 +44,334 @@ enum class eVariationAssignType : et
/// </summary>
enum class eVariationId : et
{
VAR_ARCH ,
VAR_AUGER ,
VAR_BARYCENTROID ,
VAR_BCIRCLE ,
VAR_BCOLLIDE ,
VAR_BENT ,
VAR_BENT2 ,
VAR_BIPOLAR ,
VAR_BISPLIT ,
VAR_BLADE ,
VAR_BLADE3D ,
VAR_BLOB ,
VAR_BLOB2 ,
VAR_BLOB3D ,
VAR_BLOCKY ,
VAR_BLUR ,
VAR_BLUR_CIRCLE ,
VAR_BLUR_HEART ,
VAR_BLUR_LINEAR ,
VAR_BLUR_PIXELIZE ,
VAR_BLUR_SQUARE ,
VAR_BLUR_ZOOM ,
VAR_BLUR3D ,
VAR_BMOD ,
VAR_BOARDERS ,
VAR_BOARDERS2 ,
VAR_BSWIRL ,
VAR_BTRANSFORM ,
VAR_BUBBLE ,
VAR_BUBBLE2 ,
VAR_BUBBLET3D ,
VAR_BUTTERFLY ,
VAR_BWRAPS ,
VAR_CARDIOID ,
VAR_CELL ,
VAR_CHECKS ,
VAR_CIRCLEBLUR ,
VAR_CIRCLECROP ,
VAR_CIRCLELINEAR ,
VAR_CIRCLERAND ,
VAR_CIRCLETRANS1 ,
VAR_CIRCLIZE ,
VAR_CIRCLIZE2 ,
VAR_CIRCUS ,
VAR_COLLIDEOSCOPE ,
VAR_CONIC ,
VAR_COS ,
VAR_COS_WRAP ,
VAR_COSH ,
VAR_COSHQ ,
VAR_COSINE ,
VAR_COSQ ,
VAR_COT ,
VAR_COTH ,
VAR_COTHQ ,
VAR_COTQ ,
VAR_CPOW ,
VAR_CPOW2 ,
VAR_CRACKLE ,
VAR_CRESCENTS ,
VAR_CROB ,
VAR_CROP ,
VAR_CROPN ,
VAR_CROSS ,
VAR_CSC ,
VAR_CSCH ,
VAR_CSCHQ ,
VAR_CSCQ ,
VAR_CUBIC3D ,
VAR_ARCH,
VAR_AUGER ,
VAR_BARYCENTROID,
VAR_BCIRCLE ,
VAR_BCOLLIDE ,
VAR_BENT ,
VAR_BENT2 ,
VAR_BIPOLAR ,
VAR_BISPLIT ,
VAR_BLADE ,
VAR_BLADE3D ,
VAR_BLOB ,
VAR_BLOB2 ,
VAR_BLOB3D ,
VAR_BLOCKY ,
VAR_BLUR ,
VAR_BLUR_CIRCLE ,
VAR_BLUR_HEART,
VAR_BLUR_LINEAR ,
VAR_BLUR_PIXELIZE,
VAR_BLUR_SQUARE ,
VAR_BLUR_ZOOM ,
VAR_BLUR3D ,
VAR_BMOD ,
VAR_BOARDERS ,
VAR_BOARDERS2 ,
VAR_BSWIRL ,
VAR_BTRANSFORM ,
VAR_BUBBLE ,
VAR_BUBBLE2 ,
VAR_BUBBLET3D ,
VAR_BUTTERFLY ,
VAR_BWRAPS ,
VAR_CARDIOID ,
VAR_CELL ,
VAR_CHECKS ,
VAR_CIRCLEBLUR ,
VAR_CIRCLECROP,
VAR_CIRCLELINEAR,
VAR_CIRCLERAND,
VAR_CIRCLESPLIT,
VAR_CIRCLETRANS1,
VAR_CIRCLIZE ,
VAR_CIRCLIZE2 ,
VAR_CIRCUS,
VAR_COLLIDEOSCOPE,
VAR_CONIC ,
VAR_COS ,
VAR_COS_WRAP ,
VAR_COSH ,
VAR_COSHQ,
VAR_COSINE ,
VAR_COSQ,
VAR_COT ,
VAR_COTH ,
VAR_COTHQ ,
VAR_COTQ ,
VAR_CPOW ,
VAR_CPOW2 ,
VAR_CRACKLE ,
VAR_CRESCENTS ,
VAR_CROB ,
VAR_CROP ,
VAR_CROPN ,
VAR_CROSS ,
VAR_CSC ,
VAR_CSCH ,
VAR_CSCHQ ,
VAR_CSCQ ,
VAR_CUBIC3D ,
VAR_CUBIC_LATTICE3D,
VAR_CURL ,
VAR_CURL3D ,
VAR_CURL_SP ,
VAR_CURVATURE ,
VAR_CURVE ,
VAR_CYLINDER ,
VAR_DELTA_A ,
VAR_DEPTH ,
VAR_DIAMOND ,
VAR_DISC ,
VAR_DISC2 ,
VAR_DISC3D ,
VAR_ECLIPSE ,
VAR_ECOLLIDE ,
VAR_EDISC ,
VAR_EJULIA ,
VAR_ELLIPTIC ,
VAR_EMOD ,
VAR_EMOTION ,
VAR_ENNEPERS ,
VAR_EPISPIRAL ,
VAR_EPUSH ,
VAR_ERF ,
VAR_EROTATE ,
VAR_ESCALE ,
VAR_ESCHER ,
VAR_ESTIQ ,
VAR_ESWIRL ,
VAR_EX ,
VAR_EXP ,
VAR_EXPO ,
VAR_EXPONENTIAL ,
VAR_EXTRUDE ,
VAR_EYEFISH ,
VAR_FALLOFF ,
VAR_FALLOFF2 ,
VAR_FALLOFF3 ,
VAR_FAN ,
VAR_FAN2 ,
VAR_FARBLUR ,
VAR_FDISC ,
VAR_FIBONACCI ,
VAR_FIBONACCI2 ,
VAR_FISHEYE ,
VAR_FLATTEN ,
VAR_FLIP_CIRCLE ,
VAR_FLIP_Y ,
VAR_FLOWER ,
VAR_FLUX ,
VAR_FOCI ,
VAR_FOCI3D ,
VAR_FOURTH ,
VAR_FUNNEL ,
VAR_GAMMA ,
VAR_GAUSSIAN_BLUR ,
VAR_GDOFFS ,
VAR_GLYNNIA ,
VAR_GLYNNSIM1 ,
VAR_GLYNNSIM2 ,
VAR_GLYNNSIM3 ,
VAR_GRIDOUT ,
VAR_HANDKERCHIEF ,
VAR_HEART ,
VAR_HEAT ,
VAR_HEMISPHERE ,
VAR_HEXAPLAY3D ,
VAR_HEXCROP ,
VAR_HEXES ,
VAR_HEXNIX3D ,
VAR_HO ,
VAR_HOLE ,
VAR_HORSESHOE ,
VAR_HYPERBOLIC ,
VAR_HYPERTILE ,
VAR_HYPERTILE1 ,
VAR_HYPERTILE2 ,
VAR_HYPERTILE3D ,
VAR_HYPERTILE3D1 ,
VAR_HYPERTILE3D2 ,
VAR_IDISC ,
VAR_INTERFERENCE2 ,
VAR_JAC_CN ,
VAR_JAC_DN ,
VAR_JAC_SN ,
VAR_JULIA ,
VAR_JULIA3D ,
VAR_JULIA3DQ ,
VAR_JULIA3DZ ,
VAR_JULIAC ,
VAR_JULIAN ,
VAR_JULIAN2 ,
VAR_JULIAN3DX ,
VAR_JULIANAB ,
VAR_JULIAQ ,
VAR_JULIASCOPE ,
VAR_KALEIDOSCOPE ,
VAR_LAZY_TRAVIS ,
VAR_LAZYSUSAN ,
VAR_LINE ,
VAR_LINEAR ,
VAR_LINEAR_T ,
VAR_LINEAR_T3D ,
VAR_CURL ,
VAR_CURL3D ,
VAR_CURL_SP,
VAR_CURVATURE,
VAR_CURVE ,
VAR_CYLINDER ,
VAR_CYLINDER2,
VAR_DELTA_A ,
VAR_DEPTH,
VAR_DIAMOND ,
VAR_DISC ,
VAR_DISC2 ,
VAR_DISC3D ,
VAR_ECLIPSE ,
VAR_ECOLLIDE ,
VAR_EDISC ,
VAR_EJULIA ,
VAR_ELLIPTIC ,
VAR_EMOD ,
VAR_EMOTION ,
VAR_ENNEPERS ,
VAR_EPISPIRAL ,
VAR_EPUSH ,
VAR_ERF ,
VAR_EROTATE ,
VAR_ESCALE ,
VAR_ESCHER ,
VAR_ESTIQ,
VAR_ESWIRL ,
VAR_EX ,
VAR_EXP ,
VAR_EXPO ,
VAR_EXPONENTIAL ,
VAR_EXTRUDE ,
VAR_EYEFISH ,
VAR_FALLOFF ,
VAR_FALLOFF2 ,
VAR_FALLOFF3 ,
VAR_FAN ,
VAR_FAN2 ,
VAR_FARBLUR,
VAR_FDISC ,
VAR_FIBONACCI ,
VAR_FIBONACCI2 ,
VAR_FISHEYE ,
VAR_FLATTEN ,
VAR_FLIP_CIRCLE ,
VAR_FLIP_Y ,
VAR_FLOWER ,
VAR_FLUX ,
VAR_FOCI ,
VAR_FOCI3D ,
VAR_FOURTH,
VAR_FUNNEL ,
VAR_GAMMA ,
VAR_GAUSSIAN_BLUR,
VAR_GDOFFS,
VAR_GLYNNIA ,
VAR_GLYNNSIM1 ,
VAR_GLYNNSIM2 ,
VAR_GLYNNSIM3 ,
VAR_GRIDOUT ,
VAR_HANDKERCHIEF,
VAR_HEART ,
VAR_HEAT,
VAR_HEMISPHERE ,
VAR_HEXAPLAY3D ,
VAR_HEXCROP ,
VAR_HEXES ,
VAR_HEXNIX3D ,
VAR_HO ,
VAR_HOLE ,
VAR_HORSESHOE ,
VAR_HYPERBOLIC ,
VAR_HYPERTILE ,
VAR_HYPERTILE1 ,
VAR_HYPERTILE2 ,
VAR_HYPERTILE3D ,
VAR_HYPERTILE3D1,
VAR_HYPERTILE3D2,
VAR_IDISC ,
VAR_INTERFERENCE2,
VAR_JAC_CN ,
VAR_JAC_DN ,
VAR_JAC_SN ,
VAR_JULIA ,
VAR_JULIA3D ,
VAR_JULIA3DQ ,
VAR_JULIA3DZ ,
VAR_JULIAC,
VAR_JULIAN ,
VAR_JULIAN2 ,
VAR_JULIAN3DX,
VAR_JULIANAB,
VAR_JULIAQ ,
VAR_JULIASCOPE ,
VAR_KALEIDOSCOPE,
VAR_LAZY_TRAVIS ,
VAR_LAZYSUSAN ,
VAR_LINE ,
VAR_LINEAR ,
VAR_LINEAR_T ,
VAR_LINEAR_T3D ,
//VAR_LINEAR_XZ ,
//VAR_LINEAR_YZ ,
VAR_LINEAR3D ,
VAR_LISSAJOUS ,
VAR_LOG ,
VAR_LOG_DB ,
VAR_LOQ ,
VAR_LOONIE ,
VAR_LOONIE2 ,
VAR_LOONIE3 ,
VAR_LOONIE3D ,
VAR_MASK ,
VAR_MCARPET ,
VAR_MIRROR_X ,
VAR_MIRROR_Y ,
VAR_MIRROR_Z ,
VAR_MOBIQ ,
VAR_MOBIUS ,
VAR_MOBIUS_STRIP ,
VAR_MOBIUSN ,
VAR_MODULUS ,
VAR_MURL ,
VAR_MURL2 ,
VAR_NBLUR ,
VAR_NGON ,
VAR_NOISE ,
VAR_NPOLAR ,
VAR_OCTAGON ,
VAR_OCTAPOL ,
VAR_ORTHO ,
VAR_OSCILLOSCOPE ,
VAR_OVOID ,
VAR_OVOID3D ,
VAR_PARABOLA ,
VAR_PDJ ,
VAR_PERSPECTIVE ,
VAR_PETAL ,
VAR_PHOENIX_JULIA ,
VAR_PIE ,
VAR_PIE3D ,
VAR_POINCARE ,
VAR_POINCARE3D ,
VAR_POLAR ,
VAR_POLAR2 ,
VAR_POLYNOMIAL ,
VAR_POPCORN ,
VAR_POPCORN2 ,
VAR_POPCORN23D ,
VAR_POW_BLOCK ,
VAR_POWER ,
VAR_PRESSURE_WAVE ,
VAR_PROSE3D ,
VAR_PSPHERE ,
VAR_Q_ODE ,
VAR_RADIAL_BLUR ,
VAR_RATIONAL3 ,
VAR_RAYS ,
VAR_RBLUR ,
VAR_RECTANGLES ,
VAR_RINGS ,
VAR_RINGS2 ,
VAR_RIPPLE ,
VAR_RIPPLED ,
VAR_ROTATE_X ,
VAR_ROTATE_Y ,
VAR_ROTATE_Z ,
VAR_ROUNDSPHER ,
VAR_ROUNDSPHER3D ,
VAR_SCRY ,
VAR_SCRY3D ,
VAR_SEC ,
VAR_SECANT2 ,
VAR_SECH ,
VAR_SECHQ ,
VAR_SECQ ,
VAR_SEPARATION ,
VAR_SHRED_RAD ,
VAR_SHRED_LIN ,
VAR_SIGMOID ,
VAR_SIN ,
VAR_SINEBLUR ,
VAR_SINH ,
VAR_SINHQ ,
VAR_SINQ ,
VAR_SINTRANGE ,
VAR_SINUS_GRID ,
VAR_SINUSOIDAL ,
VAR_SINUSOIDAL3D ,
VAR_LINEAR3D ,
VAR_LISSAJOUS ,
VAR_LOG ,
VAR_LOG_DB ,
VAR_LOQ ,
VAR_LOONIE ,
VAR_LOONIE2 ,
VAR_LOONIE3 ,
VAR_LOONIE3D ,
VAR_MASK ,
VAR_MCARPET ,
VAR_MIRROR_X,
VAR_MIRROR_Y,
VAR_MIRROR_Z,
VAR_MOBIQ,
VAR_MOBIUS ,
VAR_MOBIUS_STRIP,
VAR_MOBIUSN ,
VAR_MODULUS ,
VAR_MURL ,
VAR_MURL2 ,
VAR_NBLUR ,
VAR_NGON ,
VAR_NOISE ,
VAR_NPOLAR ,
VAR_OCTAGON ,
VAR_OCTAPOL ,
VAR_ORTHO ,
VAR_OSCILLOSCOPE,
VAR_OVOID ,
VAR_OVOID3D ,
VAR_PARABOLA ,
VAR_PDJ ,
VAR_PERSPECTIVE ,
VAR_PETAL ,
VAR_PHOENIX_JULIA,
VAR_PIE ,
VAR_PIE3D ,
VAR_POINCARE ,
VAR_POINCARE3D ,
VAR_POLAR ,
VAR_POLAR2 ,
VAR_POLYNOMIAL ,
VAR_POPCORN ,
VAR_POPCORN2 ,
VAR_POPCORN23D ,
VAR_POW_BLOCK ,
VAR_POWER ,
VAR_PRESSURE_WAVE,
VAR_PROSE3D ,
VAR_PSPHERE ,
VAR_Q_ODE,
VAR_RADIAL_BLUR ,
VAR_RATIONAL3 ,
VAR_RAYS ,
VAR_RBLUR,
VAR_RECTANGLES ,
VAR_RINGS ,
VAR_RINGS2 ,
VAR_RIPPLE ,
VAR_RIPPLED ,
VAR_ROTATE_X,
VAR_ROTATE_Y,
VAR_ROTATE_Z,
VAR_ROUNDSPHER ,
VAR_ROUNDSPHER3D,
VAR_SCRY ,
VAR_SCRY3D ,
VAR_SEC ,
VAR_SECANT2 ,
VAR_SECH ,
VAR_SECHQ,
VAR_SECQ,
VAR_SEPARATION ,
VAR_SHRED_RAD ,
VAR_SHRED_LIN ,
VAR_SIGMOID ,
VAR_SIN ,
VAR_SINEBLUR ,
VAR_SINH ,
VAR_SINHQ ,
VAR_SINQ ,
VAR_SINTRANGE,
VAR_SINUS_GRID ,
VAR_SINUSOIDAL ,
VAR_SINUSOIDAL3D,
//VAR_SMARTCROP ,
VAR_SPHERICAL ,
VAR_SPHERICAL3D ,
VAR_SPHERICALN ,
VAR_SPHERIVOID ,
VAR_SPHYP3D ,
VAR_SPIRAL ,
VAR_SPIRAL_WING ,
VAR_SPIROGRAPH ,
VAR_SPLIT ,
VAR_SPLIT_BRDR ,
VAR_SPLITS ,
VAR_SPLITS3D ,
VAR_SQUARE ,
VAR_SQUARE3D ,
VAR_SQUARIZE ,
VAR_SQUIRREL ,
VAR_SQUISH ,
VAR_SSCHECKS ,
VAR_STARBLUR ,
VAR_STRIPES ,
VAR_STWIN ,
VAR_SUPER_SHAPE ,
VAR_SUPER_SHAPE3D ,
VAR_SVF ,
VAR_SWIRL ,
VAR_SYNTH ,
VAR_TAN ,
VAR_TANCOS ,
VAR_TANGENT ,
VAR_TANH ,
VAR_TANHQ ,
VAR_TANQ ,
VAR_TARGET ,
VAR_TAURUS ,
VAR_TRADE ,
VAR_TRUCHET ,
VAR_TWINTRIAN ,
VAR_TWO_FACE ,
VAR_UNPOLAR ,
VAR_VORON ,
VAR_W ,
VAR_WAFFLE ,
VAR_WAVES ,
VAR_WAVES2 ,
VAR_WAVES23D ,
VAR_WAVES2B ,
VAR_WAVESN ,
VAR_WDISC ,
VAR_WEDGE ,
VAR_WEDGE_JULIA ,
VAR_WEDGE_SPH ,
VAR_WHORL ,
VAR_X ,
VAR_XERF ,
VAR_XHEART ,
VAR_XTRB ,
VAR_Y ,
VAR_Z ,
VAR_ZBLUR ,
VAR_ZCONE ,
VAR_ZSCALE ,
VAR_ZTRANSLATE ,
VAR_SPHERICAL ,
VAR_SPHERICAL3D ,
VAR_SPHERICALN ,
VAR_SPHERIVOID,
VAR_SPHYP3D ,
VAR_SPIRAL ,
VAR_SPIRAL_WING ,
VAR_SPIROGRAPH ,
VAR_SPLIT ,
VAR_SPLIT_BRDR,
VAR_SPLITS ,
VAR_SPLITS3D ,
VAR_SQUARE ,
VAR_SQUARE3D ,
VAR_SQUARIZE ,
VAR_SQUIRREL ,
VAR_SQUISH,
VAR_SSCHECKS ,
VAR_STARBLUR ,
VAR_STRIPES ,
VAR_STWIN ,
VAR_SUPER_SHAPE ,
VAR_SUPER_SHAPE3D,
VAR_SVF ,
VAR_SWIRL ,
VAR_SYNTH ,
VAR_TAN ,
VAR_TANCOS,
VAR_TANGENT ,
VAR_TANH ,
VAR_TANHQ ,
VAR_TANQ ,
VAR_TARGET ,
VAR_TAURUS ,
VAR_TILE_LOG,
VAR_TRADE ,
VAR_TRUCHET,
VAR_TRUCHET_FILL,
VAR_TWINTRIAN ,
VAR_TWO_FACE ,
VAR_UNPOLAR ,
VAR_VORON,
VAR_W ,
VAR_WAFFLE,
VAR_WAVES ,
VAR_WAVES2 ,
VAR_WAVES2_RADIAL,
VAR_WAVES23D ,
VAR_WAVES2B ,
VAR_WAVESN ,
VAR_WDISC ,
VAR_WEDGE ,
VAR_WEDGE_JULIA ,
VAR_WEDGE_SPH ,
VAR_WHORL ,
VAR_X ,
VAR_XERF ,
VAR_XHEART ,
VAR_XTRB ,
VAR_Y ,
VAR_Z ,
VAR_ZBLUR ,
VAR_ZCONE ,
VAR_ZSCALE ,
VAR_ZTRANSLATE,
VAR_PRE_ARCH,
VAR_PRE_AUGER,
@ -408,6 +413,7 @@ enum class eVariationId : et
VAR_PRE_CIRCLECROP,
VAR_PRE_CIRCLELINEAR,
VAR_PRE_CIRCLERAND,
VAR_PRE_CIRCLESPLIT,
VAR_PRE_CIRCLETRANS1,
VAR_PRE_CIRCLIZE,
VAR_PRE_CIRCLIZE2,
@ -444,6 +450,7 @@ enum class eVariationId : et
VAR_PRE_CURVATURE,
VAR_PRE_CURVE,
VAR_PRE_CYLINDER,
VAR_PRE_CYLINDER2,
VAR_PRE_DELTA_A,
VAR_PRE_DEPTH,
VAR_PRE_DIAMOND,
@ -663,8 +670,10 @@ enum class eVariationId : et
VAR_PRE_TANQ,
VAR_PRE_TARGET,
VAR_PRE_TAURUS,
VAR_PRE_TILE_LOG,
VAR_PRE_TRADE,
VAR_PRE_TRUCHET,
VAR_PRE_TRUCHET_FILL,
VAR_PRE_TWINTRIAN,
VAR_PRE_TWO_FACE,
VAR_PRE_UNPOLAR,
@ -673,6 +682,7 @@ enum class eVariationId : et
VAR_PRE_WAFFLE,
VAR_PRE_WAVES,
VAR_PRE_WAVES2,
VAR_PRE_WAVES2_RADIAL,
VAR_PRE_WAVES23D,
VAR_PRE_WAVES2B,
VAR_PRE_WAVESN,
@ -732,6 +742,7 @@ enum class eVariationId : et
VAR_POST_CIRCLECROP,
VAR_POST_CIRCLELINEAR,
VAR_POST_CIRCLERAND,
VAR_POST_CIRCLESPLIT,
VAR_POST_CIRCLETRANS1,
VAR_POST_CIRCLIZE,
VAR_POST_CIRCLIZE2,
@ -768,6 +779,7 @@ enum class eVariationId : et
VAR_POST_CURVATURE,
VAR_POST_CURVE,
VAR_POST_CYLINDER,
VAR_POST_CYLINDER2,
VAR_POST_DELTA_A,
VAR_POST_DEPTH,
VAR_POST_DIAMOND,
@ -987,8 +999,10 @@ enum class eVariationId : et
VAR_POST_TANQ,
VAR_POST_TARGET,
VAR_POST_TAURUS,
VAR_POST_TILE_LOG,
VAR_POST_TRADE,
VAR_POST_TRUCHET,
VAR_POST_TRUCHET_FILL,
VAR_POST_TWINTRIAN,
VAR_POST_TWO_FACE,
VAR_POST_UNPOLAR,
@ -997,6 +1011,7 @@ enum class eVariationId : et
VAR_POST_WAFFLE,
VAR_POST_WAVES,
VAR_POST_WAVES2,
VAR_POST_WAVES2_RADIAL,
VAR_POST_WAVES23D,
VAR_POST_WAVES2B,
VAR_POST_WAVESN,

View File

@ -344,6 +344,11 @@ VariationList<T>::VariationList()
ADDPREPOSTREGVAR(Gamma)
ADDPREPOSTREGVAR(PRose3D)
ADDPREPOSTREGVAR(LogDB)
ADDPREPOSTREGVAR(CircleSplit)
ADDPREPOSTREGVAR(Cylinder2)
ADDPREPOSTREGVAR(TileLog)
ADDPREPOSTREGVAR(TruchetFill)
ADDPREPOSTREGVAR(Waves2Radial)
//ADDPREPOSTREGVAR(LinearXZ)
//ADDPREPOSTREGVAR(LinearYZ)
//DC are special.

View File

@ -3940,7 +3940,7 @@ public:
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
{
T expx = std::exp(helper.In.x) * T(0.5);
T expnx = T(0.25) / expx;
T expnx = T(0.25) / Zeps(expx);
T sn, cn, tmp;
sincos(helper.In.y, &sn, &cn);
tmp = m_Weight / Zeps(expx + expnx - cn);
@ -3955,7 +3955,7 @@ public:
intmax_t varIndex = IndexInXform();
ss << "\t{\n"
<< "\t\treal_t expx = exp(vIn.x) * (real_t)(0.5);\n"
<< "\t\treal_t expnx = (real_t)(0.25) / expx;\n"
<< "\t\treal_t expnx = (real_t)(0.25) / Zeps(expx);\n"
<< "\t\treal_t sn = sin(vIn.y);\n"
<< "\t\treal_t cn = cos(vIn.y);\n"
<< "\t\treal_t tmp = Zeps(expx + expnx - cn);\n"

View File

@ -1951,7 +1951,6 @@ class DeltaAVariation : public Variation<T>
{
public:
DeltaAVariation(T weight = 1.0) : Variation<T>("deltaa", eVariationId::VAR_DELTA_A, weight) { }
VARCOPY(DeltaAVariation)
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
@ -4551,7 +4550,7 @@ protected:
m_Params.push_back(ParamWithName<T>(true, &m_S, prefix + "ripple_s"));
m_Params.push_back(ParamWithName<T>(true, &m_Is, prefix + "ripple_is"));
m_Params.push_back(ParamWithName<T>(true, &m_Vxp, prefix + "ripple_vxp"));
m_Params.push_back(ParamWithName<T>(true, &m_Pxa , prefix + "ripple_pxa"));
m_Params.push_back(ParamWithName<T>(true, &m_Pxa, prefix + "ripple_pxa"));
m_Params.push_back(ParamWithName<T>(true, &m_Pixa, prefix + "ripple_pixa"));
}
@ -5420,14 +5419,14 @@ public:
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
{
T a = helper.m_PrecalcAtanyx;
int n = rand.Rand(uint(m_Spread));
int n = rand.Rand(m_SpreadUint);
if (a < 0)
n++;
a += M_2PI * n;
if (std::cos(a * m_InvSpread) < rand.Rand() * 2 / 0xFFFFFFFF - 1)//Rand max.
if (std::cos(a * m_InvSpread) < rand.Rand() * T(2) / 0xFFFFFFFF - T(1))//Rand max.
a -= m_FullSpread;
T lnr2 = std::log(helper.m_PrecalcSumSquares);
@ -5464,7 +5463,7 @@ public:
<< "\n"
<< "\t\ta += M_2PI * n;\n"
<< "\n"
<< "\t\tif (cos(a * " << invSpread << ") < MwcNext(mwc) * 2 / 0xFFFFFFFF - 1)\n"
<< "\t\tif (cos(a * " << invSpread << ") < MwcNext(mwc) * (real_t)2.0 / 0xFFFFFFFF - (real_t)1.0)\n"
<< "\t\t a -= " << fullSpread << ";\n"
<< "\n"
<< "\t\treal_t lnr2 = log(precalcSumSquares);\n"
@ -5487,6 +5486,7 @@ public:
m_HalfD = m_D / 2;
m_InvSpread = T(0.5) / m_Spread;
m_FullSpread = M_2PI * m_Spread;
m_SpreadUint = uint(m_Spread);
}
protected:
@ -5512,7 +5512,8 @@ private:
T m_A;
T m_Divisor;
T m_Spread;
T m_C;//Precalc.
uint m_SpreadUint;//Precalc.
T m_C;
T m_HalfC;
T m_D;
T m_HalfD;

View File

@ -1038,7 +1038,7 @@ public:
T expx = std::exp(helper.In.x) * T(0.5);
T expnx = T(0.25) / expx;
T boot = helper.In.z == 0 ? helper.m_PrecalcAtanyx : helper.In.z;
T tmp = m_Weight / (expx + expnx - (std::cos(helper.In.y) * std::cos(boot)));
T tmp = m_Weight / Zeps(expx + expnx - (std::cos(helper.In.y) * std::cos(boot)));
helper.Out.x = (expx - expnx) * tmp;
helper.Out.y = std::sin(helper.In.y) * tmp;
helper.Out.z = std::sin(boot) * tmp;
@ -1052,7 +1052,7 @@ public:
<< "\t\treal_t expx = exp(vIn.x) * (real_t)(0.5);\n"
<< "\t\treal_t expnx = (real_t)(0.25) / expx;\n"
<< "\t\treal_t boot = vIn.z == 0 ? precalcAtanyx : vIn.z;\n"
<< "\t\treal_t tmp = xform->m_VariationWeights[" << varIndex << "] / (expx + expnx - (cos(vIn.y) * cos(boot)));\n"
<< "\t\treal_t tmp = xform->m_VariationWeights[" << varIndex << "] / Zeps(expx + expnx - (cos(vIn.y) * cos(boot)));\n"
<< "\n"
<< "\t\tvOut.x = (expx - expnx) * tmp;\n"
<< "\t\tvOut.y = sin(vIn.y) * tmp;\n"
@ -1060,6 +1060,11 @@ public:
<< "\t}\n";
return ss.str();
}
virtual vector<string> OpenCLGlobalFuncNames() const override
{
return vector<string> { "Zeps" };
}
};
/// <summary>

View File

@ -4379,17 +4379,17 @@ protected:
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName<T>(&m_Power , prefix + "smartcrop_power", 4)); //Original used a prefix of scrop_, which is incompatible with Ember's design.
m_Params.push_back(ParamWithName<T>(&m_Radius , prefix + "smartcrop_radius", 1));
m_Params.push_back(ParamWithName<T>(&m_Roundstr , prefix + "smartcrop_roundstr"));
m_Params.push_back(ParamWithName<T>(&m_Power, prefix + "smartcrop_power", 4)); //Original used a prefix of scrop_, which is incompatible with Ember's design.
m_Params.push_back(ParamWithName<T>(&m_Radius, prefix + "smartcrop_radius", 1));
m_Params.push_back(ParamWithName<T>(&m_Roundstr, prefix + "smartcrop_roundstr"));
m_Params.push_back(ParamWithName<T>(&m_Roundwidth, prefix + "smartcrop_roundwidth", 1));
m_Params.push_back(ParamWithName<T>(&m_Distortion, prefix + "smartcrop_distortion", 1));
m_Params.push_back(ParamWithName<T>(&m_Edge , prefix + "smartcrop_edge"));
m_Params.push_back(ParamWithName<T>(&m_Scatter , prefix + "smartcrop_scatter"));
m_Params.push_back(ParamWithName<T>(&m_Offset , prefix + "smartcrop_offset"));
m_Params.push_back(ParamWithName<T>(&m_Rotation , prefix + "smartcrop_rotation"));
m_Params.push_back(ParamWithName<T>(&m_Cropmode , prefix + "smartcrop_cropmode", 1, eParamType::INTEGER, -1, 2));
m_Params.push_back(ParamWithName<T>(&m_Static , prefix + "smartcrop_static", 1, eParamType::INTEGER, -1, 3));
m_Params.push_back(ParamWithName<T>(&m_Edge, prefix + "smartcrop_edge"));
m_Params.push_back(ParamWithName<T>(&m_Scatter, prefix + "smartcrop_scatter"));
m_Params.push_back(ParamWithName<T>(&m_Offset, prefix + "smartcrop_offset"));
m_Params.push_back(ParamWithName<T>(&m_Rotation, prefix + "smartcrop_rotation"));
m_Params.push_back(ParamWithName<T>(&m_Cropmode, prefix + "smartcrop_cropmode", 1, eParamType::INTEGER, -1, 2));
m_Params.push_back(ParamWithName<T>(&m_Static , prefix + "smartcrop_static", 1, eParamType::INTEGER, -1, 3));
m_Params.push_back(ParamWithName<T>(true, &m_Mode, prefix + "smartcrop_mode"));//Precalc.
m_Params.push_back(ParamWithName<T>(true, &m_Radial, prefix + "smartcrop_radial"));
m_Params.push_back(ParamWithName<T>(true, &m_WorkRadius, prefix + "smartcrop_work_radius"));
@ -4649,7 +4649,7 @@ public:
<< "\n"
<< "\t\tif (" << hypergon << " != 0)\n"
<< "\t\t{\n"
<< "\t\t temp1 = fmod(fabs(a), M_2PI / " << hypergonN << ") - M_PI / " << hypergonN << ";\n"
<< "\t\t temp1 = fmod(fabs(a), (real_t)M_2PI / " << hypergonN << ") - M_PI / " << hypergonN << ";\n"
<< "\t\t temp2 = Sqr(tan(temp1)) + 1;\n"
<< "\n"
<< "\t\t if (temp2 >= Sqr(" << hypergonD << "))\n"
@ -4664,7 +4664,7 @@ public:
<< "\n"
<< "\t\tif (" << star << "!= 0)\n"
<< "\t\t{\n"
<< "\t\t temp1 = tan(fabs(fmod(fabs(a), M_2PI / " << starN << ") - M_PI / " << starN << "));\n"
<< "\t\t temp1 = tan(fabs(fmod(fabs(a), (real_t)M_2PI / " << starN << ") - M_PI / " << starN << "));\n"
<< "\t\t total += " << star << " * sqrt(Sqr(" << tanStarSlope << ") * (1 + Sqr(temp1)) / Sqr(temp1 + " << tanStarSlope << "));\n"
<< "\t\t}\n"
<< "\n"
@ -4684,7 +4684,7 @@ public:
<< "\t\t{\n"
<< "\t\t if (" << hypergon << " != 0.0)\n"
<< "\t\t {\n"
<< "\t\t temp1 = fmod(fabs(a2), M_2PI / " << hypergonN << ") - M_PI / " << hypergonN << ";\n"
<< "\t\t temp1 = fmod(fabs(a2), (real_t)M_2PI / " << hypergonN << ") - M_PI / " << hypergonN << ";\n"
<< "\t\t temp2 = Sqr(tan(temp1)) + 1;\n"
<< "\n"
<< "\t\t if (temp2 >= Sqr(" << hypergonD << "))\n"
@ -4699,7 +4699,7 @@ public:
<< "\n"
<< "\t\t if (" << star << " != 0)\n"
<< "\t\t {\n"
<< "\t\t temp1 = tan(fabs(fmod(fabs(a2), M_2PI / " << starN << ") - M_PI / " << starN << "));\n"
<< "\t\t temp1 = tan(fabs(fmod(fabs(a2), (real_t)M_2PI / " << starN << ") - M_PI / " << starN << "));\n"
<< "\t\t total2 += " << star << " * sqrt(Sqr(" << tanStarSlope << ") * (1 + Sqr(temp1)) / Sqr(temp1 + " << tanStarSlope << "));\n"
<< "\t\t }\n"
<< "\n"

View File

@ -948,6 +948,513 @@ private:
T m_FixPe;
};
/// <summary>
/// circlesplit.
/// By tatasz.
/// http://fav.me/dapecsh
/// </summary>
template <typename T>
class CircleSplitVariation : public ParametricVariation<T>
{
public:
CircleSplitVariation(T weight = 1.0) : ParametricVariation<T>("circlesplit", eVariationId::VAR_CIRCLESPLIT, weight, true, true)
{
Init();
}
PARVARCOPY(CircleSplitVariation)
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
{
T x1, y1;
if (helper.m_PrecalcSqrtSumSquares < (m_Radius - m_Split))
{
x1 = helper.In.x;
y1 = helper.In.y;
}
else
{
T a = std::atan2(helper.In.y, helper.In.x);
T len = helper.m_PrecalcSqrtSumSquares + m_Split;
x1 = std::cos(a) * len;
y1 = std::sin(a) * len;
}
helper.Out.x = m_Weight * x1;
helper.Out.y = m_Weight * y1;
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string cs_radius = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string cs_split = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t x1, y1;\n"
<< "\n"
<< "\t\tif (precalcSqrtSumSquares < (" << cs_radius << " - " << cs_split << "))\n"
<< "\t\t{\n"
<< "\t\t\tx1 = vIn.x;\n"
<< "\t\t\ty1 = vIn.y;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t\treal_t a = (real_t)atan2(vIn.y, vIn.x);\n"
<< "\t\t\treal_t len = precalcSqrtSumSquares + " << cs_split << ";\n"
<< "\t\t\tx1 = cos(a) * len;\n"
<< "\t\t\ty1 = sin(a) * len;\n"
<< "\t\t}"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * x1;\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * y1;\n"
<< "\t}\n";
return ss.str();
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName<T>(&m_Radius, prefix + "circlesplit_radius", 1));
m_Params.push_back(ParamWithName<T>(&m_Split, prefix + "circlesplit_split", T(0.5)));
}
private:
T m_Radius;
T m_Split;
};
/// <summary>
/// cylinder2.
/// By tatasz.
/// http://fav.me/dapecsh
/// </summary>
template <typename T>
class Cylinder2Variation : public Variation<T>
{
public:
Cylinder2Variation(T weight = 1.0) : Variation<T>("cylinder2", eVariationId::VAR_CYLINDER2, weight) { }
VARCOPY(Cylinder2Variation)
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
{
helper.Out.x = m_Weight * (helper.In.x / Zeps(std::sqrt(SQR(helper.In.x) + 1)));
helper.Out.y = m_Weight * helper.In.y;
}
virtual string OpenCLString() const override
{
ostringstream ss;
intmax_t varIndex = IndexInXform();
ss << "\t{\n"
<< "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x / Zeps(sqrt(SQR(vIn.x) + (real_t)1.0)));\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n"
<< "\t}\n";
return ss.str();
}
virtual vector<string> OpenCLGlobalFuncNames() const override
{
return vector<string> { "Zeps" };
}
};
/// <summary>
/// tile_log.
/// By zy0rg.
/// http://zy0rg.deviantart.com
/// </summary>
template <typename T>
class TileLogVariation : public ParametricVariation<T>
{
public:
TileLogVariation(T weight = 1.0) : ParametricVariation<T>("tile_log", eVariationId::VAR_TILE_LOG, weight)
{
Init();
}
PARVARCOPY(TileLogVariation)
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
{
T temp = Round(std::log(rand.Frand01<T>()) * (rand.Rand() & 1 ? m_Spread : -m_Spread));
helper.Out.x = m_Weight * (helper.In.x + temp);
helper.Out.y = m_Weight * helper.In.y;
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string spread = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t temp = (real_t) (Round(log(MwcNext01(mwc)) * (MwcNext(mwc) & 1 ? " << spread << " : -" << spread << ")));\n"
<< "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (vIn.x + temp);\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * vIn.y;\n"
<< "\t}\n";
return ss.str();
}
virtual vector<string> OpenCLGlobalFuncNames() const override
{
return vector<string> { "Round" };
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName<T>(&m_Spread, prefix + "tile_log_spread", 1));
}
private:
T m_Spread;
};
/// <summary>
/// Truchet_fill.
/// By tatasz.
/// http://fav.me/dapecsh
/// </summary>
template <typename T>
class TruchetFillVariation : public ParametricVariation<T>
{
public:
TruchetFillVariation(T weight = 1.0) : ParametricVariation<T>("Truchet_fill", eVariationId::VAR_TRUCHET_FILL, weight)
{
Init();
}
PARVARCOPY(TruchetFillVariation)
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
{
T modbase = T(65535);
T multiplier = T(32747); //1103515245;
T offset = T(12345);
T x = helper.In.x * m_Scale;
T y = helper.In.y * m_Scale;
T intx = Round(x);
T inty = Round(y);
T r = x - intx;
if (r < 0)
x = 1 + r;
else
x = r;
r = y - inty;
if (r < 0)
y = 1 + r;
else
y = r;
T tiletype = 0;
if (m_Seed != 0)
{
if (m_Seed == 1)
{
tiletype = m_Seed;
}
else
{
T xrand = helper.In.x;
T yrand = helper.In.y;
xrand = Round(std::abs(xrand)) * m_Seed2;
yrand = Round(std::abs(yrand)) * m_Seed2;
T niter = xrand + yrand + (xrand * yrand);
T randint = (m_Seed + niter) * m_Seed2 * T(0.5);
randint = std::fmod((randint * multiplier + offset), modbase);
tiletype = std::fmod(randint, T(2.0));
}
}
T r0, r1;
if (tiletype < T(1))
{
//Slow drawmode
r0 = std::pow((std::pow(std::fabs(x), m_FinalExponent) + std::pow(std::fabs(y), m_FinalExponent)), m_OneOverEx);
r1 = std::pow((std::pow(std::fabs(x - T(1.0)), m_FinalExponent) + std::pow(std::fabs(y - 1), m_FinalExponent)), m_OneOverEx);
}
else
{
r0 = std::pow((std::pow(std::fabs(x - T(1.0)), m_FinalExponent) + std::pow(std::fabs(y), m_FinalExponent)), m_OneOverEx);
r1 = std::pow((std::pow(std::fabs(x), m_FinalExponent) + std::pow(std::fabs(y - T(1.0)), m_FinalExponent)), m_OneOverEx);
}
T x1, y1;
T r00 = fabs(r0 - T(0.5)) / m_Rmax;
if (r00 < 1)
{
x1 = 2 * (x + std::floor(helper.In.x));
y1 = 2 * (y + std::floor(helper.In.y));
}
else
{
x1 = 0;
y1 = 0;
}
T r11 = std::fabs(r1 - T(0.5)) / m_Rmax;
if (r11 < 1)
{
helper.Out.x = x1 + (2 * (x + std::floor(helper.In.x))) - helper.In.x;
helper.Out.y = y1 + (2 * (y + std::floor(helper.In.y))) - helper.In.y;
}
else
{
helper.Out.x = x1 - helper.In.x;
helper.Out.y = y1 - helper.In.y;
}
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0;
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string exponent = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string arcWidth = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string seed = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string finalexponent = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string oneOverEx = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string width = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string seed2 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string rmax = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string scale = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t modbase = 65535;\n"
<< "\t\treal_t multiplier = 32747;\n"
<< "\t\treal_t offset = 12345;\n"
<< "\n"
<< "\t\treal_t x = vIn.x * " << scale << ";\n"
<< "\t\treal_t y = vIn.y * " << scale << ";\n"
<< "\t\treal_t intx = Round(x);\n"
<< "\t\treal_t inty = Round(y);\n"
<< "\n"
<< "\t\treal_t r = x - intx;\n"
<< "\n"
<< "\t\tif (r < 0)\n"
<< "\t\t\tx = r + 1;\n"
<< "\t\telse\n"
<< "\t\t\tx = r;\n"
<< "\n"
<< "\t\tr = y - inty;\n"
<< "\n"
<< "\t\tif (r < 0)\n"
<< "\t\t\ty = r + 1;\n"
<< "\t\telse\n"
<< "\t\t\ty = r;\n"
<< "\n"
<< "\t\treal_t tiletype = 0;\n"
<< "\n"
<< "\t\tif (" << seed << " != 0)\n"
<< "\t\t{\n"
<< "\t\t\tif (" << seed << " == 1)\n"
<< "\t\t\t{\n"
<< "\t\t\t\ttiletype = " << seed << ";\n"
<< "\t\t\t}\n"
<< "\t\t\telse\n"
<< "\t\t\t{\n"
<< "\t\t\t\treal_t xrand = vIn.x;\n"
<< "\t\t\t\treal_t yrand = vIn.y;\n"
<< "\n"
<< "\t\t\t\txrand = Round(fabs(xrand)) * " << seed2 << ";\n"
<< "\t\t\t\tyrand = Round(fabs(yrand)) * " << seed2 << ";\n"
<< "\n"
<< "\t\t\t\treal_t niter = xrand + yrand + (xrand * yrand);\n"
<< "\t\t\t\treal_t randint = (" << seed << " + niter) * " << seed2 << " * ((real_t) 0.5);\n"
<< "\n"
<< "\t\t\t\trandint = fmod((randint * multiplier + offset), modbase);\n"
<< "\t\t\t\ttiletype = fmod(randint, 2);\n"
<< "\t\t\t}\n"
<< "\t\t}\n"
<< "\n"
<< "\t\treal_t r0, r1;\n"
<< "\n"
<< "\t\tif (tiletype < 1)\n"
<< "\t\t{\n"
<< "\t\t\tr0 = pow((pow(fabs(x), " << finalexponent << ") + pow(fabs(y), " << finalexponent << ")), " << oneOverEx << ");\n"
<< "\t\t\tr1 = pow((pow(fabs(x-1), " << finalexponent << ") + pow(fabs(y-1), " << finalexponent << ")), " << oneOverEx << ");\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t\tr0 = pow((pow(fabs(x-1), " << finalexponent << ") + pow(fabs(y), " << finalexponent << ")), " << oneOverEx << ");\n"
<< "\t\t\tr1 = pow((pow(fabs(x), " << finalexponent << ") + pow(fabs(y-1), " << finalexponent << ")), " << oneOverEx << ");\n"
<< "\t\t}\n"
<< "\n"
<< "\t\treal_t x1, y1;\n"
<< "\t\treal_t r00 = fabs(r0 - (real_t) 0.5) / " << rmax << ";\n"
<< "\n"
<< "\t\tif (r00 < 1.0)\n"
<< "\t\t{\n"
<< "\t\t\tx1 = 2 * (x + floor(vIn.x));\n"
<< "\t\t\ty1 = 2 * (y + floor(vIn.y));\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t\tx1 = 0;\n"
<< "\t\t\ty1 = 0;\n"
<< "\t\t}\n"
<< "\n"
<< "\t\treal_t r11 = fabs(r1 - (real_t) 0.5) / " << rmax << ";\n"
<< "\n"
<< "\t\tif (r11 < 1)\n"
<< "\t\t{\n"
<< "\t\t\tvOut.x = x1 + (2 * (x + floor(vIn.x))) - vIn.x;\n"
<< "\t\t\tvOut.y = y1 + (2 * (y + floor(vIn.y))) - vIn.y;\n"
<< "\t\t}\n"
<< "\t\telse\n"
<< "\t\t{\n"
<< "\t\t\tvOut.x = x1 - vIn.x;\n"
<< "\t\t\tvOut.y = y1 - vIn.y;\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual vector<string> OpenCLGlobalFuncNames() const override
{
return vector<string> { "Round" };
}
virtual void Precalc() override
{
m_FinalExponent = m_Exponent > T(2) ? T(2) : (m_Exponent < T(0.001) ? T(0.001) : m_Exponent);
m_OneOverEx = T(1) / m_FinalExponent;
m_Width = m_ArcWidth > T(1) ? T(1) : (m_ArcWidth < T(0.001) ? T(0.001) : m_ArcWidth);
m_Seed2 = std::sqrt(m_Seed * T(1.5)) / (m_Seed * T(0.5)) * T(0.25);
m_Rmax = T(0.5) * (std::pow(T(2), m_OneOverEx) - T(1)) * m_Width;
m_Scale = T(1) / m_Weight;
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName<T>(&m_Exponent, prefix + "Truchet_fill_exponent", 2, eParamType::REAL_CYCLIC, T(0.001), 2));
m_Params.push_back(ParamWithName<T>(&m_ArcWidth, prefix + "Truchet_fill_arc_width", T(0.5), eParamType::REAL_CYCLIC, T(0.001), 1));
m_Params.push_back(ParamWithName<T>(&m_Seed, prefix + "Truchet_fill_seed"));
m_Params.push_back(ParamWithName<T>(true, &m_FinalExponent, prefix + "Truchet_fill_final_exponent"));//Precalc
m_Params.push_back(ParamWithName<T>(true, &m_OneOverEx, prefix + "Truchet_fill_oneoverex"));
m_Params.push_back(ParamWithName<T>(true, &m_Width, prefix + "Truchet_fill_width"));
m_Params.push_back(ParamWithName<T>(true, &m_Seed2, prefix + "Truchet_fill_seed2"));
m_Params.push_back(ParamWithName<T>(true, &m_Rmax, prefix + "Truchet_fill_rmax"));
m_Params.push_back(ParamWithName<T>(true, &m_Scale, prefix + "Truchet_fill_scale"));
}
private:
T m_Exponent;
T m_ArcWidth;
T m_Seed;
T m_FinalExponent;//Precalc.
T m_OneOverEx;
T m_Width;
T m_Seed2;
T m_Rmax;
T m_Scale;
};
/// <summary>
/// waves2_radial.
/// By tatasz.
/// http://fav.me/dapecsh
/// </summary>
template <typename T>
class Waves2RadialVariation : public ParametricVariation<T>
{
public:
Waves2RadialVariation(T weight = 1.0) : ParametricVariation<T>("waves2_radial", eVariationId::VAR_WAVES2_RADIAL, weight, true, true)
{
Init();
}
PARVARCOPY(Waves2RadialVariation)
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
{
T x0 = helper.In.x;
T y0 = helper.In.y;
T dist = helper.m_PrecalcSqrtSumSquares;
T factor = (dist < m_Distance) ? (dist - m_Null) / Zeps(m_Distance - m_Null) : T(1);
factor = (dist < m_Null) ? T(0) : factor;
helper.Out.x = m_Weight * (x0 + factor * std::sin(y0 * m_Freqx) * m_Scalex);
helper.Out.y = m_Weight * (y0 + factor * std::sin(x0 * m_Freqy) * m_Scaley);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t i = 0, varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
string freqX = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string scaleX = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string freqY = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string scaleY = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string nullVar = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string distance = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal_t x0 = vIn.x;\n"
<< "\t\treal_t y0 = vIn.y;\n"
<< "\n"
<< "\t\treal_t dist = precalcSqrtSumSquares;\n"
<< "\t\treal_t factor = (dist < " << distance << ") ? (dist - " << nullVar << ") / Zeps(" << distance << "-" << nullVar << ") : (real_t)(1.0);\n"
<< "\t\tfactor = (dist < " << nullVar << ") ? (real_t) 0.0 : factor;\n"
<< "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (x0 + factor * sin(y0 * " << freqX << ") * " << scaleX << ");\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (y0 + factor * sin(x0 * " << freqY << ") * " << scaleY << ");\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
virtual vector<string> OpenCLGlobalFuncNames() const override
{
return vector<string> { "Zeps" };
}
protected:
void Init()
{
string prefix = Prefix();
m_Params.clear();
m_Params.push_back(ParamWithName<T>(&m_Freqx, prefix + "waves2_radial_freqx", 7));
m_Params.push_back(ParamWithName<T>(&m_Scalex, prefix + "waves2_radial_scalex", T(0.1)));
m_Params.push_back(ParamWithName<T>(&m_Freqy, prefix + "waves2_radial_freqy", 13));
m_Params.push_back(ParamWithName<T>(&m_Scaley, prefix + "waves2_radial_scaley", T(0.1)));
m_Params.push_back(ParamWithName<T>(&m_Null, prefix + "waves2_radial_null", 2));
m_Params.push_back(ParamWithName<T>(&m_Distance, prefix + "waves2_radial_distance", 10));
}
private:
T m_Freqx;
T m_Scalex;
T m_Freqy;
T m_Scaley;
T m_Null;
T m_Distance;
};
MAKEPREPOSTPARVAR(Splits3D, splits3D, SPLITS3D)
MAKEPREPOSTPARVAR(Waves2B, waves2b, WAVES2B)
MAKEPREPOSTPARVAR(JacCn, jac_cn, JAC_CN)
@ -957,4 +1464,9 @@ MAKEPREPOSTPARVAR(PressureWave, pressure_wave, PRESSURE_WAVE)
MAKEPREPOSTVAR(Gamma, gamma, GAMMA)
MAKEPREPOSTPARVAR(PRose3D, pRose3D, PROSE3D)
MAKEPREPOSTPARVAR(LogDB, log_db, LOG_DB)
MAKEPREPOSTPARVAR(CircleSplit, circlesplit, CIRCLESPLIT)
MAKEPREPOSTVAR(Cylinder2, cylinder2, CYLINDER2)
MAKEPREPOSTPARVAR(TileLog, tile_log, TILE_LOG)
MAKEPREPOSTPARVAR(TruchetFill, Truchet_fill, TRUCHET_FILL)
MAKEPREPOSTPARVAR(Waves2Radial, waves2_radial, WAVES2_RADIAL)
}

1456
Source/Ember/XmlToEmber.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -137,7 +137,7 @@ bool EmberAnimate(EmberOptions& opt)
renderers.push_back(std::move(tempRenderer));
}
if (!InitPaletteList<T>(opt.PalettePath()))
if (!InitPaletteList<T>(opt.PalettePath()))//For any modern flames, the palette isn't used. This is for legacy purposes and should be removed.
return false;
cout << "Parsing ember file " << opt.Input() << "\n";

View File

@ -238,7 +238,6 @@ string IterOpenCLKernelCreator<T>::CreateIterKernelString(const Ember<T>& ember,
" uint histSize,\n"
" __read_only image2d_t palette,\n"
" __global Point* points\n"
//" uint startRender\n"
"\t)\n"
"{\n"
" bool fuse, ok;\n"
@ -456,7 +455,7 @@ string IterOpenCLKernelCreator<T>::CreateIterKernelString(const Ember<T>& ember,
{
os <<
" real_t colorIndexFrac;\n"
" real_t colorIndex = secondPoint.m_ColorX * COLORMAP_LENGTH;\n"
" real_t colorIndex = secondPoint.m_ColorX * COLORMAP_LENGTH_MINUS_1;\n"
" int intColorIndex = (int)colorIndex;\n"
" float4 palColor2;\n"
"\n"
@ -484,7 +483,7 @@ string IterOpenCLKernelCreator<T>::CreateIterKernelString(const Ember<T>& ember,
else if (ember.m_PaletteMode == ePaletteMode::PALETTE_STEP)
{
os <<
" iPaletteCoord.x = (int)(secondPoint.m_ColorX * COLORMAP_LENGTH);\n"
" iPaletteCoord.x = (int)(secondPoint.m_ColorX * COLORMAP_LENGTH_MINUS_1);\n"
" palColor1 = read_imagef(palette, paletteSampler, iPaletteCoord);\n";
}
@ -675,7 +674,7 @@ void IterOpenCLKernelCreator<T>::ParVarIndexDefines(const Ember<T>& ember, pair<
/// <param name="doVals">True if the vector should be populated, else false. Default: true.</param>
/// <param name="doString">True if the string should be populated, else false. Default: true.</param>
template <typename T>
void IterOpenCLKernelCreator<T>::SharedDataIndexDefines(const Ember<T>& ember, pair<string, vector<T>>& params, bool doVals = true, bool doString = true)
void IterOpenCLKernelCreator<T>::SharedDataIndexDefines(const Ember<T>& ember, pair<string, vector<T>>& params, bool doVals, bool doString)
{
size_t i, j, offset = 0, xformCount = ember.TotalXformCount();
string s;

View File

@ -118,7 +118,7 @@ public:
void ClearBuffers();
//Images.
bool AddAndWriteImage(const string& name, cl_mem_flags flags, const cl::ImageFormat& format, ::size_t width, ::size_t height, ::size_t row_pitch, void* data = NULL, bool shared = false, GLuint texName = 0);
bool AddAndWriteImage(const string& name, cl_mem_flags flags, const cl::ImageFormat& format, ::size_t width, ::size_t height, ::size_t row_pitch, void* data = nullptr, bool shared = false, GLuint texName = 0);
bool WriteImage2D(size_t index, bool shared, size_t width, size_t height, size_t row_pitch, void* data);
bool ReadImage(const string& name, ::size_t width, ::size_t height, ::size_t row_pitch, bool shared, void* data);
bool ReadImage(size_t imageIndex, ::size_t width, ::size_t height, ::size_t row_pitch, bool shared, void* data);
@ -127,14 +127,14 @@ public:
size_t GetImageSize(size_t imageIndex, bool shared);
bool CompareImageParams(cl::Image& image, cl_mem_flags flags, const cl::ImageFormat& format, ::size_t width, ::size_t height, ::size_t row_pitch);
void ClearImages(bool shared);
bool CreateImage2D(cl::Image2D& image2D, cl_mem_flags flags, cl::ImageFormat format, ::size_t width, ::size_t height, ::size_t row_pitch = 0, void* data = NULL);
bool CreateImage2D(cl::Image2D& image2D, cl_mem_flags flags, cl::ImageFormat format, ::size_t width, ::size_t height, ::size_t row_pitch = 0, void* data = nullptr);
bool CreateImage2DGL(cl::ImageGL& image2DGL, cl_mem_flags flags, GLenum target, GLint miplevel, GLuint texobj);
bool EnqueueAcquireGLObjects(const string& name);
bool EnqueueAcquireGLObjects(cl::ImageGL& image);
bool EnqueueReleaseGLObjects(const string& name);
bool EnqueueReleaseGLObjects(cl::ImageGL& image);
bool EnqueueAcquireGLObjects(const VECTOR_CLASS<cl::Memory>* memObjects = NULL);
bool EnqueueReleaseGLObjects(const VECTOR_CLASS<cl::Memory>* memObjects = NULL);
bool EnqueueAcquireGLObjects(const VECTOR_CLASS<cl::Memory>* memObjects = nullptr);
bool EnqueueReleaseGLObjects(const VECTOR_CLASS<cl::Memory>* memObjects = nullptr);
bool CreateSampler(cl::Sampler& sampler, cl_bool normalizedCoords, cl_addressing_mode addressingMode, cl_filter_mode filterMode);
//Arguments.

View File

@ -125,19 +125,23 @@ static bool InitPaletteList(const string& filename)
PaletteList<T> paletteList;//Even though this is local, the members are static so they will remain.
static vector<string> paths =
{
"./",
"./"
#ifndef _WIN32
"~"
, "~",
"~/.config/fractorium",
"/usr/share/fractorium",
"/usr/local/share/fractorium"
#endif
};
bool added = paletteList.Add(filename);
bool added = false;
for (auto& p : paths)
{
if (!added)
added |= paletteList.Add(p + "/" + filename);
else
break;
}
if (!added || !paletteList.Size())
{

View File

@ -63,7 +63,7 @@ bool EmberRender(EmberOptions& opt)
if (opt.EmberCL() && renderer->RendererType() != eRendererType::OPENCL_RENDERER)//OpenCL init failed, so fall back to CPU.
opt.EmberCL(false);
if (!InitPaletteList<T>(opt.PalettePath()))
if (!InitPaletteList<T>(opt.PalettePath()))//For any modern flames, the palette isn't used. This is for legacy purposes and should be removed.
return false;
if (!ParseEmberFile(parser, opt.Input(), embers))

View File

@ -113,7 +113,7 @@ void MakeTestAllVarsRegPrePost(vector<Ember<T>>& embers)
ss << "NoVars";
emberNoVars.m_Name = ss.str();
ss.str("");
emberNoVars.m_Palette = *paletteList.GetPalette(paletteList.m_DefaultFilename, 0);
emberNoVars.m_Palette = *paletteList.GetPaletteByFilename(paletteList.m_DefaultFilename, 0);
embers.push_back(emberNoVars);
while (index < varList->RegSize())
@ -1945,11 +1945,23 @@ int _tmain(int argc, _TCHAR* argv[])
vector<Ember<double>> dv;
list<Ember<float>> fl;
list<Ember<double>> dl;
EmberContainerTester<float>::TestEmberContainer(fv);
EmberContainerTester<double>::TestEmberContainer(dv);
EmberContainerTester<float>::TestEmberContainer(fl);
EmberContainerTester<double>::TestEmberContainer(dl);
CopyCont(fv, fl);
string line = "title=\"cj_aerie\" smooth=no", delim = " =\"";
auto vec = Split(line, delim, true);
for (auto& s : vec) cout << s << endl;
line = "index=0 color=2177354", delim = " =";
vec = Split(line, delim, true);
for (auto& s : vec) cout << s << endl;
/*
EmberContainerTester<float>::TestEmberContainer(fv);
EmberContainerTester<double>::TestEmberContainer(dv);
EmberContainerTester<float>::TestEmberContainer(fl);
EmberContainerTester<double>::TestEmberContainer(dl);
CopyCont(fv, fl);
*/
//QTIsaac<ISAAC_SIZE, ISAAC_INT> rand(1, 2, 3);
//mt19937 meow(1729);
/* TestAffine<float>();

View File

@ -58,7 +58,7 @@
<enum>QFrame::NoFrame</enum>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;br/&gt;Fractorium 1.0.0.2&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;http://fractorium.com&quot;&gt;fractorium.com&lt;/a&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;&lt;br/&gt;Lead: Matt Feemster&lt;br/&gt;Contributors: Simon Detheridge&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;Fractorium 1.0.0.2&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;http://fractorium.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;fractorium.com&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;&lt;br/&gt;Lead: Matt Feemster&lt;br/&gt;Contributors: Simon Detheridge, Michel Mastriani&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
@ -86,9 +86,9 @@
<property name="geometry">
<rect>
<x>5</x>
<y>180</y>
<y>170</y>
<width>585</width>
<height>483</height>
<height>500</height>
</rect>
</property>
<layout class="QVBoxLayout" name="AboutVerticalLayout">
@ -128,7 +128,7 @@
<enum>QFrame::NoFrame</enum>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/scottdraves/flam3&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;flam3&lt;/span&gt;&lt;/a&gt;: Scott Draves, Erik Reckase (GPL v2)&lt;br/&gt;&lt;a href=&quot;http://github.com/stevenrobertson/cuburn&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;cuburn&lt;/span&gt;&lt;/a&gt;: Steven Robertson, Michael Semeniuk, Matthew Znoj, Nicolas Mejia (GPL v3)&lt;br/&gt;&lt;a href=&quot;http://fractron9000.sourceforge.net&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Fractron 9000&lt;/span&gt;&lt;/a&gt;: Mike Thiesen (GPL)&lt;br/&gt;&lt;a href=&quot;http://sourceforge.net/projects/apophysis7x&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Apophysis&lt;/span&gt;&lt;/a&gt;: Mark Townsend, Ronald Hordijk, Peter Sdobnov, Piotr Borys, Georg Kiehne (GPL)&lt;br/&gt;&lt;a href=&quot;http://jwildfire.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;JWildfire&lt;/span&gt;&lt;/a&gt;: Andreas Maschke (LGPL)&lt;br/&gt;Numerous Apophysis plugin developers (GPL)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/scottdraves/flam3&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;flam3&lt;/span&gt;&lt;/a&gt;: Scott Draves, Erik Reckase (GPL v2)&lt;br/&gt;&lt;a href=&quot;http://github.com/stevenrobertson/cuburn&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;cuburn&lt;/span&gt;&lt;/a&gt;: Steven Robertson, Michael Semeniuk, Matthew Znoj, Nicolas Mejia (GPL v3)&lt;br/&gt;&lt;a href=&quot;http://fractron9000.sourceforge.net&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Fractron 9000&lt;/span&gt;&lt;/a&gt;: Mike Thiesen (GPL)&lt;br/&gt;&lt;a href=&quot;http://sourceforge.net/projects/apophysis7x&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Apophysis&lt;/span&gt;&lt;/a&gt;: Mark Townsend, Ronald Hordijk, Peter Sdobnov, Piotr Borys, Georg Kiehne (GPL)&lt;br/&gt;&lt;a href=&quot;http://jwildfire.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;JWildfire&lt;/span&gt;&lt;/a&gt;: Andreas Maschke (LGPL)&lt;br/&gt;gradLib: Stian Broen&lt;br/&gt;ColorPickerWidget: Etienne Moutot&lt;br/&gt;Numerous Apophysis plugin developers (GPL)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
@ -211,7 +211,7 @@
</sizepolicy>
</property>
<property name="title">
<string>Icons Used</string>
<string>Icons and Palettes Used</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="topMargin">
@ -232,7 +232,7 @@
<enum>QFrame::NoFrame</enum>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;http://famfamfam.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Silk&lt;/span&gt;&lt;/a&gt;: Mark James (Creative Commons Attribution 2.5 License)&lt;br/&gt;&lt;a href=&quot;http://momentumdesignlab.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Momentum&lt;/span&gt;&lt;/a&gt;: Momentum Design Lab (Creative Commons Attribution-ShareAlike 3.5 License)&lt;br/&gt;&lt;a href=&quot;http://everaldo.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Crystal Clear&lt;/span&gt;&lt;/a&gt;: Everaldo Coelho (LGPL)&lt;br/&gt;&lt;a href=&quot;http://openiconlibrary.sourceforge.net&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Open Icon Library&lt;/span&gt;&lt;/a&gt;: Jeff Israel (GPL, LGPL, Creative Commons, Public Domain)&lt;br/&gt;&lt;a href=&quot;http://icons.mysitemyway.com/category/3d-transparent-glass-icons/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;3D Transparent Glass&lt;/span&gt;&lt;/a&gt;: iconsETC (Public Domain)&lt;br/&gt;&lt;a href=&quot;http://p.yusukekamiyamane.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Fugue&lt;/span&gt;&lt;/a&gt;: Yusuke Kamiyamane (Creative Commons Attribution 3.0 License)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Palettes&lt;/span&gt;: Boxtail, FarDareisMai, FractalDesire, Rce, Tatasz (Public Domain)&lt;br/&gt;&lt;a href=&quot;http://famfamfam.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Silk&lt;/span&gt;&lt;/a&gt;: Mark James (Creative Commons Attribution 2.5 License)&lt;br/&gt;&lt;a href=&quot;http://momentumdesignlab.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Momentum&lt;/span&gt;&lt;/a&gt;: Momentum Design Lab (Creative Commons Attribution-ShareAlike 3.5 License)&lt;br/&gt;&lt;a href=&quot;http://everaldo.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Crystal Clear&lt;/span&gt;&lt;/a&gt;: Everaldo Coelho (LGPL)&lt;br/&gt;&lt;a href=&quot;http://openiconlibrary.sourceforge.net&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Open Icon Library&lt;/span&gt;&lt;/a&gt;: Jeff Israel (GPL, LGPL, Creative Commons, Public Domain)&lt;br/&gt;&lt;a href=&quot;http://icons.mysitemyway.com/category/3d-transparent-glass-icons/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;3D Transparent Glass&lt;/span&gt;&lt;/a&gt;: iconsETC (Public Domain)&lt;br/&gt;&lt;a href=&quot;http://p.yusukekamiyamane.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Fugue&lt;/span&gt;&lt;/a&gt;: Yusuke Kamiyamane (Creative Commons Attribution 3.0 License)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
@ -253,7 +253,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="">
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>5</x>

View File

@ -32,7 +32,7 @@ class CurvesGraphicsView : public QGraphicsView
Q_OBJECT
public:
CurvesGraphicsView(QWidget* parent = 0);
CurvesGraphicsView(QWidget* parent = nullptr);
void PointChanged(int curveIndex, int pointIndex, const QPointF& point);
QPointF Get(int curveIndex, int pointIndex);
@ -82,7 +82,7 @@ public:
/// <param name="pointIndex">The point index within the curve</param>
/// <param name="viewParent">The graphics view this point is displayed on</param>
/// <param name="p">The parent widget of this item</param>
EllipseItem(const QRectF& rect, int curveIndex, int pointIndex, CurvesGraphicsView* viewParent, QGraphicsItem* parent = 0)
EllipseItem(const QRectF& rect, int curveIndex, int pointIndex, CurvesGraphicsView* viewParent, QGraphicsItem* parent = nullptr)
: QGraphicsEllipseItem(rect, parent)
{
setFlag(QGraphicsItem::ItemSendsScenePositionChanges);

View File

@ -1,6 +1,5 @@
#include "FractoriumPch.h"
#include "DoubleSpinBox.h"
#include "FractoriumSettings.h"
QTimer DoubleSpinBox::s_Timer;
@ -17,10 +16,12 @@ DoubleSpinBox::DoubleSpinBox(QWidget* p, int h, double step)
: QDoubleSpinBox(p)
{
m_DoubleClick = false;
m_DoubleClickLowVal = 0;
m_DoubleClickNonZero = 0;
m_DoubleClickZero = 1;
m_Step = step;
m_SmallStep = step / 10.0;
m_Settings = FractoriumSettings::DefInstance();
setSingleStep(step);
setFrame(false);
setButtonSymbols(QAbstractSpinBox::NoButtons);
@ -53,6 +54,16 @@ void DoubleSpinBox::DoubleClick(bool b)
m_DoubleClick = b;
}
/// <summary>
/// Set the value to be used instead of zero to represent the lower value
/// used when responding to a double click.
/// </summary>
/// <param name="val">The value to be used for the lower value instead of zero</param>
void DoubleSpinBox::DoubleClickLowVal(double val)
{
m_DoubleClickLowVal = val;
}
/// <summary>
/// Set the value to be used when the user double clicks the spinner while
/// it contains zero.
@ -120,7 +131,7 @@ QLineEdit* DoubleSpinBox::lineEdit()
/// <summary>
/// Another workaround for the persistent text selection bug in Qt.
/// </summary>
void DoubleSpinBox::OnSpinBoxValueChanged(double d)
void DoubleSpinBox::OnSpinBoxValueChanged(double)
{
lineEdit()->deselect();//Gets rid of nasty "feature" that always has text selected.
}
@ -159,35 +170,34 @@ void DoubleSpinBox::OnTimeout()
bool DoubleSpinBox::eventFilter(QObject* o, QEvent* e)
{
QMouseEvent* me = dynamic_cast<QMouseEvent*>(e);
auto settings = FractoriumSettings::DefInstance();
if (isEnabled() && me)
{
if (!settings->ToggleType() &&//Ensure double click toggles, not right click.
if (!m_Settings->ToggleType() &&//Ensure double click toggles, not right click.
me->type() == QMouseEvent::MouseButtonPress &&
me->button() == Qt::RightButton)
{
m_MouseDownPoint = m_MouseMovePoint = me->pos();
StartTimer();
}
else if (!settings->ToggleType() &&
else if (!m_Settings->ToggleType() &&
me->type() == QMouseEvent::MouseButtonRelease &&
me->button() == Qt::RightButton)
{
StopTimer();
m_MouseDownPoint = m_MouseMovePoint = me->pos();
}
else if (!settings->ToggleType() &&
else if (!m_Settings->ToggleType() &&
me->type() == QMouseEvent::MouseMove &&
QGuiApplication::mouseButtons() & Qt::RightButton)
{
m_MouseMovePoint = me->pos();
}
else if (m_DoubleClick &&
((!settings->ToggleType() && e->type() == QMouseEvent::MouseButtonDblClick && me->button() == Qt::LeftButton) ||
(settings->ToggleType() && me->type() == QMouseEvent::MouseButtonRelease && me->button() == Qt::RightButton)))
((!m_Settings->ToggleType() && e->type() == QMouseEvent::MouseButtonDblClick && me->button() == Qt::LeftButton) ||
(m_Settings->ToggleType() && me->type() == QMouseEvent::MouseButtonRelease && me->button() == Qt::RightButton)))
{
if (IsNearZero(value()))
if (IsClose(m_DoubleClickLowVal, value()))
setValue(m_DoubleClickZero);
else
setValue(m_DoubleClickNonZero);
@ -276,4 +286,4 @@ void DoubleSpinBox::StopTimer()
{
s_Timer.stop();
disconnect(&s_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout()));
}
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "FractoriumPch.h"
#include "FractoriumSettings.h"
/// <summary>
/// DoubleSpinBox and VariationTreeDoubleSpinBox classes.
@ -22,6 +23,7 @@ public:
virtual ~DoubleSpinBox() { }
void SetValueStealth(double d);
void DoubleClick(bool b);
void DoubleClickLowVal(double val);
void DoubleClickZero(double val);
void DoubleClickNonZero(double val);
double Step();
@ -46,12 +48,14 @@ private:
void StopTimer();
bool m_DoubleClick;
double m_DoubleClickLowVal;
double m_DoubleClickNonZero;
double m_DoubleClickZero;
double m_Step;
double m_SmallStep;
QPoint m_MouseDownPoint;
QPoint m_MouseMovePoint;
shared_ptr<FractoriumSettings> m_Settings;
static QTimer s_Timer;
};

View File

@ -31,8 +31,8 @@ public:
/// The re-parenting is done so that the DoubleSpinBox appears directly on top of the cell.
/// </summary>
/// <param name="parent">The parent cell</param>
/// <param name="option">Unused</param>
/// <param name="index">unused</param>
/// <param name="option">Ignored</param>
/// <param name="index">Ignored</param>
/// <returns>The DoubleSpinBox member</returns>
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override
{
@ -44,8 +44,8 @@ public:
/// <summary>
/// Prevent DoubleSpinBox control from being destroyed when the cell loses focus.
/// </summary>
/// <param name="editor">Unused</param>
/// <param name="index">Unused</param>
/// <param name="editor">Ignored</param>
/// <param name="index">Ignored</param>
virtual void destroyEditor(QWidget* editor, const QModelIndex& index) const override
{
}
@ -53,8 +53,8 @@ public:
/// <summary>
/// Set the value of the DoubleSpinBox as well as its tableindex property.
/// </summary>
/// <param name="editor">Unused</param>
/// <param name="index">Unused</param>
/// <param name="editor">Ignored</param>
/// <param name="index">Ignored</param>
virtual void setEditorData(QWidget* editor, const QModelIndex& index) const override
{
QPoint p(index.row(), index.column());
@ -67,7 +67,7 @@ public:
/// <summary>
/// Set the cell in the model to the value of the DoubleSpinBox.
/// </summary>
/// <param name="editor">Unused</param>
/// <param name="editor">Ignored</param>
/// <param name="model">The model whose value will be set</param>
/// <param name="index">The cell index of the model</param>
virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override
@ -80,7 +80,7 @@ public:
/// </summary>
/// <param name="editor">The DoubleSpinBox member</param>
/// <param name="option">Contains the rectangle to be used for the geometry of the DoubleSpinBox</param>
/// <param name="index">Unused</param>
/// <param name="index">Ignored</param>
virtual void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override
{
editor->setGeometry(option.rect);

View File

@ -196,7 +196,11 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(QWidget* p, Qt::WindowF
void FractoriumFinalRenderDialog::Show(bool fromSequence)
{
m_FromSequence = fromSequence;
#ifdef __APPLE__
exec();
#else
show();
#endif
}
/// <summary>

View File

@ -186,6 +186,19 @@ Fractorium::Fractorium(QWidget* p)
}
}
#ifdef __APPLE__
for (auto dock : m_Docks)//Fixes focus problem on OSX.
{
if (!dock->isHidden())
{
dock->setFloating(!dock->isFloating());
dock->setFloating(!dock->isFloating());
break;
}
}
#endif
//At this point, everything has been setup except the renderer. Shortly after
//this constructor exits, GLWidget::InitGL() will create the initial flock and start the rendering timer
//which executes whenever the program is idle. Upon starting the timer, the renderer
@ -201,6 +214,8 @@ Fractorium::~Fractorium()
{
SyncSequenceSettings();
m_VarDialog->SyncSettings();
m_Settings->ShowXforms(ui.ActionDrawXforms->isChecked());
m_Settings->ShowGrid(ui.ActionDrawGrid->isChecked());
m_Settings->setValue("windowState", saveState());
m_Settings->sync();
}
@ -497,16 +512,13 @@ QStringList Fractorium::SetupOpenXmlDialog()
m_FileDialog->setViewMode(QFileDialog::List);
}
if (!m_FileDialog)
return QStringList("");
QStringList filenames;
m_FileDialog->disconnect(SIGNAL(filterSelected(const QString&)));
connect(m_FileDialog, &QFileDialog::filterSelected, [&](const QString & filter) { m_Settings->OpenXmlExt(filter); });
m_FileDialog->setFileMode(QFileDialog::ExistingFiles);
m_FileDialog->setAcceptMode(QFileDialog::AcceptOpen);
m_FileDialog->setNameFilter("Flam3 (*.flam3);;Flame (*.flame);;Xml (*.xml)");
m_FileDialog->setWindowTitle("Open flame");
m_FileDialog->setWindowTitle("Open Flame");
m_FileDialog->setDirectory(m_Settings->OpenFolder());
m_FileDialog->selectNameFilter(m_Settings->OpenXmlExt());
@ -709,15 +721,20 @@ void Fractorium::SetTabOrders()
w = SetTabOrder(this, w, ui.SequenceRandomizeStaggerCheckBox);
w = SetTabOrder(this, w, ui.SequenceStaggerSpinBox);
w = SetTabOrder(this, w, ui.SequenceRandomStaggerMaxSpinBox);
w = SetTabOrder(this, w, ui.SequenceRandomizeRotationsCheckBox);
w = SetTabOrder(this, w, ui.SequenceRotationsSpinBox);
w = SetTabOrder(this, w, ui.SequenceRotationsCWCheckBox);
w = SetTabOrder(this, w, ui.SequenceRandomRotationsMaxSpinBox);
w = SetTabOrder(this, w, ui.SequenceRandomizeFramesPerRotCheckBox);
w = SetTabOrder(this, w, ui.SequenceFramesPerRotSpinBox);
w = SetTabOrder(this, w, ui.SequenceRandomFramesPerRotMaxSpinBox);
w = SetTabOrder(this, w, ui.SequenceRandomizeRotationsCheckBox);
w = SetTabOrder(this, w, ui.SequenceRotationsSpinBox);
w = SetTabOrder(this, w, ui.SequenceRandomRotationsMaxSpinBox);
w = SetTabOrder(this, w, ui.SequenceRandomizeBlendFramesCheckBox);
w = SetTabOrder(this, w, ui.SequenceBlendFramesSpinBox);
w = SetTabOrder(this, w, ui.SequenceRandomBlendMaxFramesSpinBox);
w = SetTabOrder(this, w, ui.SequenceRandomizeRotationsPerBlendCheckBox);
w = SetTabOrder(this, w, ui.SequenceRotationsPerBlendSpinBox);
w = SetTabOrder(this, w, ui.SequenceRotationsPerBlendCWCheckBox);
w = SetTabOrder(this, w, ui.SequenceRotationsPerBlendMaxSpinBox);
w = SetTabOrder(this, w, ui.SequenceGenerateButton);
w = SetTabOrder(this, w, ui.SequenceRenderButton);
w = SetTabOrder(this, w, ui.SequenceSaveButton);
@ -738,7 +755,6 @@ void Fractorium::SetTabOrders()
w = SetTabOrder(this, w, m_XformOpacitySpin);
w = SetTabOrder(this, w, m_XformDirectColorSpin);
w = SetTabOrder(this, w, ui.SoloXformCheckBox);
w = SetTabOrder(this, ui.LockAffineCheckBox, ui.PreAffineGroupBox);//Xforms affine.
w = SetTabOrder(this, w, m_PreX1Spin);
w = SetTabOrder(this, w, m_PreX2Spin);
w = SetTabOrder(this, w, m_PreY1Spin);
@ -802,8 +818,9 @@ void Fractorium::SetTabOrders()
w = SetTabOrder(this, w, m_PaletteBlurSpin);
w = SetTabOrder(this, w, m_PaletteBrightnessSpin);
w = SetTabOrder(this, w, m_PaletteFrequencySpin);
w = SetTabOrder(this, w, ui.PaletteRandomSelect);
w = SetTabOrder(this, w, ui.PaletteRandomAdjust);
w = SetTabOrder(this, w, ui.PaletteRandomSelectButton);
w = SetTabOrder(this, w, ui.PaletteRandomAdjustButton);
w = SetTabOrder(this, w, ui.PaletteEditorButton);
w = SetTabOrder(this, w, ui.PaletteFilterLineEdit);
w = SetTabOrder(this, w, ui.PaletteFilterClearButton);
w = SetTabOrder(this, w, ui.PaletteListTable);

View File

@ -13,6 +13,7 @@
#include "AboutDialog.h"
#include "CurvesGraphicsView.h"
#include "DoubleSpinBoxTableItemDelegate.h"
#include "PaletteEditor/PaletteEditor.h"
/// <summary>
/// Fractorium class.
@ -90,6 +91,11 @@ public:
Fractorium(QWidget* p = nullptr);
~Fractorium();
//Toolbar.
bool DrawXforms();
bool DrawImage();
bool DrawGrid();
//Library.
void SyncFileCountToSequenceCount();
@ -135,6 +141,8 @@ public slots:
void OnActionPasteSelectedXforms(bool checked);
void OnActionResetWorkspace(bool checked);//View
void OnActionAlternateEditorImage(bool checked);
void OnActionResetScale(bool checked);
void OnActionAddReflectiveSymmetry(bool checked);//Tools.
void OnActionAddRotationalSymmetry(bool checked);
@ -158,6 +166,9 @@ public slots:
void OnActionDP(bool checked);
void OnActionStyle(bool checked);
void OnActionStartStopRenderer(bool checked);
void OnActionDrawXforms(bool checked);
void OnActionDrawImage(bool checked);
void OnActionDrawGrid(bool checked);
//Library.
void OnEmberTreeItemChanged(QTreeWidgetItem* item, int col);
@ -237,7 +248,6 @@ public slots:
void OnXformAnimateCheckBoxStateChanged(int state);
//Xforms Affine.
void OnLockAffineScaleCheckBoxStateChanged(int state);
void OnPreAffineRowDoubleClicked(int logicalIndex);
void OnPreAffineColDoubleClicked(int logicalIndex);
void OnPostAffineRowDoubleClicked(int logicalIndex);
@ -275,6 +285,9 @@ public slots:
void OnXformScrollColorIndexChanged(int d);
void OnRandomColorIndicesButtonClicked(bool b);
void OnToggleColorIndicesButtonClicked(bool b);
void OnRandomColorSpeedButtonClicked(bool b);
void OnToggleColorSpeedButtonClicked(bool b);
void OnXformColorSpeedChanged(double d);
void OnXformOpacityChanged(double d);
void OnXformDirectColorChanged(double d);
@ -313,9 +326,12 @@ public slots:
void OnPaletteCellDoubleClicked(int row, int col);
void OnPaletteRandomSelectButtonClicked(bool checked);
void OnPaletteRandomAdjustButtonClicked(bool checked);
void OnPaletteEditorButtonClicked(bool checked);
void OnPaletteFilterLineEditTextChanged(const QString& text);
void OnPaletteFilterClearButtonClicked(bool checked);
void OnPaletteHeaderSectionClicked(int col);
void OnPaletteEditorColorChanged();
void OnPaletteEditorFileChanged();
//Info.
void OnSummaryTableHeaderResized(int logicalIndex, int oldSize, int newSize);
@ -371,6 +387,7 @@ private:
void SyncOptionsToToolbar();
//Library.
void SelectLibraryItem(size_t index);
vector<pair<size_t, QTreeWidgetItem*>> GetCurrentEmberIndex();
void SyncSequenceSettings();
@ -384,7 +401,6 @@ private:
//Xforms Variations.
void Filter();
void Filter(const QString& text);
//Xforms Selection.
void ClearXformsSelections();
@ -397,6 +413,7 @@ private:
void ResetPaletteControls();
void SetPaletteFileComboIndex(const string& filename);
void SetPaletteTableItem(QPixmap* pixmap, QTableWidget* table, QTableWidgetItem* item, int row, int col);
bool PaletteChanged();
//Info.
void FillSummary();
@ -415,11 +432,12 @@ private:
QString SetupSaveXmlDialog(const QString& defaultFilename);
QString SetupSaveImageDialog(const QString& defaultFilename);
QString SetupSaveFolderDialog();
QColorDialog* m_ColorDialog;
FractoriumFinalRenderDialog* m_FinalRenderDialog;
FractoriumOptionsDialog* m_OptionsDialog;
FractoriumVariationsDialog* m_VarDialog;
FractoriumAboutDialog* m_AboutDialog;
QColorDialog* m_ColorDialog = nullptr;
FractoriumFinalRenderDialog* m_FinalRenderDialog = nullptr;
FractoriumOptionsDialog* m_OptionsDialog = nullptr;
FractoriumVariationsDialog* m_VarDialog = nullptr;
FractoriumAboutDialog* m_AboutDialog = nullptr;
PaletteEditor* m_PaletteEditor = nullptr;
//Params.
DoubleSpinBox* m_BrightnessSpin;//Color.
@ -494,6 +512,8 @@ private:
DoubleSpinBoxTableItemDelegate* m_XaosTableItemDelegate;
//Palette.
bool m_PaletteChanged;
bool m_PaletteFileChanged;
SpinBox* m_PaletteHueSpin;
SpinBox* m_PaletteSaturationSpin;
SpinBox* m_PaletteBrightnessSpin;
@ -510,9 +530,9 @@ private:
QTableWidgetItem* m_InfoFinalXformItem;
//Files.
QFileDialog* m_FileDialog;
QFileDialog* m_FolderDialog;
QssDialog* m_QssDialog;
QFileDialog* m_FileDialog = nullptr;
QFileDialog* m_FolderDialog = nullptr;
QssDialog* m_QssDialog = nullptr;
QString m_LastSaveAll;
QString m_LastSaveCurrent;
QString m_Style;

View File

@ -47,5 +47,8 @@
<file>Icons/checkbox_unchecked.png</file>
<file>Icons/control.png</file>
<file>Icons/control-stop-square.png</file>
<file>Icons/Function-512.png</file>
<file>Icons/pic.png</file>
<file>Icons/grid.png</file>
</qresource>
</RCC>

View File

@ -74,7 +74,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>1284</width>
<width>1269</width>
<height>987</height>
</rect>
</property>
@ -2007,13 +2007,13 @@
<rect>
<x>770</x>
<y>0</y>
<width>255</width>
<width>294</width>
<height>881</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>255</width>
<width>294</width>
<height>617</height>
</size>
</property>
@ -2420,7 +2420,7 @@
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="PaletteRandomSelect">
<widget class="QPushButton" name="PaletteRandomSelectButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -2442,7 +2442,7 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="PaletteRandomAdjust">
<widget class="QPushButton" name="PaletteRandomAdjustButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -2466,6 +2466,16 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="PaletteEditorButton">
<property name="toolTip">
<string>Open the palette editor to make a custom palette</string>
</property>
<property name="text">
<string>Palette Editor...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="9" column="0">
@ -3050,7 +3060,7 @@
<enum>QTabWidget::Triangular</enum>
</property>
<property name="currentIndex">
<number>2</number>
<number>1</number>
</property>
<widget class="QWidget" name="XformColorTab">
<property name="sizePolicy">
@ -3370,6 +3380,53 @@
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QPushButton" name="RandomColorIndicesButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set all xform color indices to random numbers between 0 and 1, inclusive&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Random Indices</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="ToggleColorIndicesButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set all xform color indices to 0 or 1&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Toggle Indices</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="RandomColorSpeedButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set all xform color indices to 0 or 1&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Random Color Speed</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="ToggleColorSpeedButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set all xform color indices to 0 or 1&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Toggle Color Speed</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0" colspan="2">
<widget class="TableWidget" name="XformColorValuesTable">
<property name="sizePolicy">
@ -3565,36 +3622,6 @@
</item>
</widget>
</item>
<item row="3" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>4</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="RandomColorIndicesButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set all xform color indices to random numbers between 0 and 1, inclusive&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Random Indices</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ToggleColorIndicesButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set all xform color indices to 0 or 1&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Toggle Indices</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="SoloXformCheckBox">
<property name="toolTip">
@ -3642,16 +3669,6 @@
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QCheckBox" name="LockAffineCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Checking this box will lock the display size of the affines at their current level, allowing for easy manipulation no matter what zoom level is used.&lt;/p&gt;&lt;p&gt;Unchecking this resets the scale used to draw the affines to its native value.&lt;/p&gt;&lt;p&gt;Note this only affects the display and does not alter any internal values used for rendering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Lock Affine Scale</string>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="AffineTabScrollArea">
<property name="autoFillBackground">
@ -3672,7 +3689,7 @@
<x>0</x>
<y>0</y>
<width>263</width>
<height>700</height>
<height>722</height>
</rect>
</property>
<property name="autoFillBackground">
@ -6843,6 +6860,8 @@
<string>&amp;View</string>
</property>
<addaction name="ActionResetWorkspace"/>
<addaction name="ActionAlternateEditorImage"/>
<addaction name="ActionResetScale"/>
</widget>
<addaction name="MenuFile"/>
<addaction name="MenuEdit"/>
@ -6997,7 +7016,7 @@
<x>0</x>
<y>0</y>
<width>432</width>
<height>572</height>
<height>589</height>
</rect>
</property>
<property name="sizePolicy">
@ -7685,6 +7704,11 @@
<addaction name="ActionOptions"/>
<addaction name="separator"/>
<addaction name="ActionStyle"/>
<addaction name="separator"/>
<addaction name="ActionDrawXforms"/>
<addaction name="ActionDrawImage"/>
<addaction name="ActionDrawGrid"/>
<addaction name="ActionResetScale"/>
</widget>
<action name="ActionNewFlock">
<property name="icon">
@ -7870,6 +7894,9 @@
<property name="toolTip">
<string>Add a copy of the current flame to the end of the current file</string>
</property>
<property name="shortcut">
<string>Ctrl+J</string>
</property>
</action>
<action name="ActionClearFlame">
<property name="icon">
@ -8128,6 +8155,67 @@
<string>Ctrl+P</string>
</property>
</action>
<action name="ActionDrawImage">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="Fractorium.qrc">
<normaloff>:/Fractorium/Icons/pic.png</normaloff>:/Fractorium/Icons/pic.png</iconset>
</property>
<property name="text">
<string>Show/Hide Image</string>
</property>
<property name="toolTip">
<string>Show/Hide Image</string>
</property>
<property name="shortcut">
<string>Ctrl+I</string>
</property>
</action>
<action name="ActionDrawGrid">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="Fractorium.qrc">
<normaloff>:/Fractorium/Icons/grid.png</normaloff>:/Fractorium/Icons/grid.png</iconset>
</property>
<property name="text">
<string>Show/Hide Grid</string>
</property>
<property name="toolTip">
<string>Show/Hide Grid</string>
</property>
</action>
<action name="ActionDrawXforms">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="Fractorium.qrc">
<normaloff>:/Fractorium/Icons/Function-512.png</normaloff>:/Fractorium/Icons/Function-512.png</iconset>
</property>
<property name="text">
<string>Show/Hide Xforms</string>
</property>
<property name="toolTip">
<string>Show/Hide Xforms</string>
</property>
</action>
<action name="ActionAlternateEditorImage">
<property name="text">
<string>Alternate Editor/Image</string>
</property>
<property name="shortcut">
<string>Ctrl+W</string>
</property>
</action>
<action name="ActionResetScale">
<property name="text">
<string>Reset Scale</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View File

@ -2,10 +2,12 @@
#include "FractoriumPch.h"
#include "FractoriumSettings.h"
#include "PaletteTableWidgetItem.h"
/// <summary>
/// Fractorium global utility functions.
/// </summary>
#define PALETTE_CELL_HEIGHT 16
/// <summary>
/// Setup a spinner to be placed in a table cell.
@ -368,6 +370,116 @@ static void HandleDeviceTableCheckChanged(QTableWidget* table, int row, int col)
primaryItem->setCheckState(Qt::Checked);
}
/// <summary>
/// Set a row in a table to represent a palette.
/// This will place the palette name as a string value in the first column,
/// and a QPixmap representing the palette in the second column.
/// </summary>
/// <param name="paletteTable">The table write to the row to</param>
/// <param name="palette">A pointer to the palette to write to the row</param>
/// <param name="row">The row to write the palette to</param>
static void AddPaletteToTable(QTableWidget* paletteTable, Palette<float>* palette, int row)
{
auto v = palette->MakeRgbPaletteBlock(PALETTE_CELL_HEIGHT);
auto nameCol = new QTableWidgetItem(palette->m_Name.c_str());
nameCol->setToolTip(palette->m_Name.c_str());
paletteTable->setItem(row, 0, nameCol);
QImage image(v.data(), int(palette->Size()), PALETTE_CELL_HEIGHT, QImage::Format_RGB888);
auto paletteItem = new PaletteTableWidgetItem(palette);
paletteItem->setData(Qt::DecorationRole, QPixmap::fromImage(image));
paletteItem->setFlags(paletteItem->flags() & ~Qt::ItemIsEditable);
paletteTable->setItem(row, 1, paletteItem);
}
/// <summary>
/// Read a palette Xml file and populate the palette table with the contents.
/// This will clear any previous contents.
/// Called upon initialization, palette combo index change, and controller type change.
/// </summary>
/// <param name="s">The name of the palette file without the path</param>
/// <returns>True if successful, else false.</returns>
static bool FillPaletteTable(const string& s, QTableWidget* paletteTable, PaletteList<float>& paletteList)
{
if (!s.empty())//This occasionally seems to get called with an empty string for reasons unknown.
{
if (auto palettes = paletteList.GetPaletteListByFilename(s))
{
paletteTable->clear();
paletteTable->blockSignals(true);
paletteTable->setRowCount(int(palettes->size()));
//Headers get removed when clearing, so must re-create here.
auto nameHeader = new QTableWidgetItem("Name");
auto paletteHeader = new QTableWidgetItem("Palette");
nameHeader->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
paletteHeader->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
paletteTable->setHorizontalHeaderItem(0, nameHeader);
paletteTable->setHorizontalHeaderItem(1, paletteHeader);
//Palette list table.
for (auto i = 0; i < palettes->size(); i++)
if (auto palette = &(*palettes)[i])
AddPaletteToTable(paletteTable, palette, i);
paletteTable->blockSignals(false);
return true;
}
}
return false;
}
/// <summary>
/// Get the default search paths for config and palette files.
/// </summary>
/// <returns>vector<QString> of paths</returns>
static vector<QString> GetDefaultPaths()
{
static vector<QString> paths =
{
(QDir::homePath() + "/AppData/Roaming/Fractorium").toLocal8Bit().data(),
#ifndef _WIN32
QString("/usr/share/fractorium").toLocal8Bit().data(),
QString("/usr/local/share/fractorium").toLocal8Bit().data(),
(QDir::homePath() + "/.config/fractorium").toLocal8Bit().data(),
#endif
QDir::currentPath().toLocal8Bit().data(),
QCoreApplication::applicationDirPath().toLocal8Bit().data()
};
return paths;
}
/// <summary>
/// Get the default user path for config and palette files.
/// </summary>
/// <returns>vector<QString> of paths</returns>
static QString GetDefaultUserPath()
{
#ifdef _WIN32
return (QDir::homePath() + "/AppData/Roaming/Fractorium").toLocal8Bit().data();
#else
return (QDir::homePath() + "/.config/fractorium").toLocal8Bit().data();
#endif
}
/// <summary>
/// Get the first flam3-palettes.xml file in the default search paths.
/// </summary>
/// <returns>The full path and filename if found, else empty string.</returns>
static QString FindFirstDefaultPalette()
{
auto paths = GetDefaultPaths();
for (auto& path : paths)
{
auto full = path + "/flam3-palettes.xml";
if (QFile::exists(full))
return full;
}
return "";
}
/// <summary>
/// The basic style that is needed for things to look right, this varies by OS.
/// </summary>

View File

@ -42,33 +42,38 @@ FractoriumEmberController<T>::FractoriumEmberController(Fractorium* fractorium)
: FractoriumEmberControllerBase(fractorium),
m_VariationList(VariationList<T>::Instance())
{
bool b = false;
size_t b = 0;
m_GLController = make_unique<GLEmberController<T>>(fractorium, fractorium->ui.GLDisplay, this);
m_LibraryPreviewRenderer = make_unique<TreePreviewRenderer<T>>(this, m_Fractorium->ui.LibraryTree, m_EmberFile);
m_SequencePreviewRenderer = make_unique<TreePreviewRenderer<T>>(this, m_Fractorium->ui.SequenceTree, m_SequenceFile);
m_PaletteList.Clear();
m_Fractorium->ui.PaletteFilenameCombo->clear();
//Initial combo change event to fill the palette table will be called automatically later.
//Look hard for a palette.
static vector<string> paths =
{
QDir::currentPath().toLocal8Bit().data(),
QDir::homePath().toLocal8Bit().data(),
QCoreApplication::applicationDirPath().toLocal8Bit().data(),
QString(QDir::homePath() + "/.config/fractorium").toLocal8Bit().data(),
QString("/usr/share/fractorium").toLocal8Bit().data(),
QString("/usr/local/share/fractorium").toLocal8Bit().data()
};
auto paths = GetDefaultPaths();
for (auto& path : paths)
b |= InitPaletteList(path);
if (b)
{
if (b = InitPaletteList(path))
{
m_SheepTools = make_unique<SheepTools<T, float>>(m_PaletteList.Name(0), new EmberNs::Renderer<T, float>());
break;
}
m_SheepTools = make_unique<SheepTools<T, float>>(m_PaletteList.Name(0), new EmberNs::Renderer<T, float>());
}
else
{
QString allPaths;
for (auto& path : paths)
allPaths += path + "\r\n";
allPaths = QString("No palettes found in paths:\r\n") + allPaths + "\r\nExiting.";
std::runtime_error ex(allPaths.toStdString());
throw ex;
}
if (!b)
throw "No palettes found, exiting.";
if (m_PaletteList.Size() >= 1)//Only add the user palette if the folder already had a palette, which means we'll be using this folder.
if (m_PaletteList.AddEmptyPaletteFile((GetDefaultUserPath() + "/user-palettes.xml").toStdString()))
m_Fractorium->ui.PaletteFilenameCombo->addItem("user-palettes.xml");
BackgroundChanged(QColor(0, 0, 0));//Default to black.
ClearUndo();
@ -146,18 +151,7 @@ void FractoriumEmberController<T>::SetEmber(size_t index, bool verbatim)
{
if (index < m_EmberFile.Size())
{
if (auto top = m_Fractorium->ui.LibraryTree->topLevelItem(0))
{
for (int i = 0; i < top->childCount(); i++)
{
if (auto emberItem = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(i)))
{
emberItem->setSelected(i == index);
emberItem->setCheckState(0, i == index ? Qt::Checked : Qt::Unchecked);
}
}
}
m_Fractorium->SelectLibraryItem(index);
ClearUndo();
SetEmber(*m_EmberFile.Get(index), verbatim, true);
}
@ -335,6 +329,13 @@ void FractoriumEmberController<T>::SetEmberPrivate(const Ember<U>& ember, bool v
static EmberToXml<T> writer;//Save parameters of last full render just in case there is a crash.
#ifdef _WIN32
string filename = "last.flame";
#elif defined(__APPLE__)
QDir dir(QDir::applicationDirPath());
if (!dir.exists())
dir.mkpath(".");
string filename = QDir::applicationDirPath().toStdString() + "/last.flame";
#else
QDir dir(QDir::homePath() + "/.config/fractorium");

View File

@ -49,6 +49,8 @@ template <typename T> class TreePreviewRenderer;
/// </summary>
class FractoriumEmberControllerBase : public RenderCallback
{
friend Fractorium;
public:
FractoriumEmberControllerBase(Fractorium* fractorium);
FractoriumEmberControllerBase(const FractoriumEmberControllerBase& controller) = delete;
@ -194,13 +196,15 @@ public:
double LockedX() { return m_LockedX; }
double LockedY() { return m_LockedY; }
void LockedScale(double scale) { m_LockedScale = scale; }
virtual void LockAffineScaleCheckBoxStateChanged(int state) { }
virtual void InitLockedScale() { }
//Xforms Color.
virtual void XformColorIndexChanged(double d, bool updateRender) { }
virtual void XformScrollColorIndexChanged(int d) { }
virtual void RandomColorIndicesButtonClicked() { }
virtual void ToggleColorIndicesButtonClicked() { }
virtual void RandomColorSpeedButtonClicked() { }
virtual void ToggleColorSpeedButtonClicked() { }
virtual void XformColorSpeedChanged(double d) { }
virtual void XformOpacityChanged(double d) { }
virtual void XformDirectColorChanged(double d) { }
@ -222,11 +226,13 @@ public:
virtual void RandomXaos() { }
//Palette.
virtual size_t InitPaletteList(const string& s) { return 0; }
virtual size_t InitPaletteList(const QString& s) { return 0; }
virtual bool FillPaletteTable(const string& s) { return false; }
virtual void ApplyPaletteToEmber() { }
virtual void PaletteAdjust() { }
virtual void PaletteCellClicked(int row, int col) { }
virtual void SetBasePaletteAndAdjust(const Palette<float>& palette) { }
virtual void PaletteEditorButtonClicked() { }
QImage& FinalPaletteImage() { return m_FinalPaletteImage; }
//Info.
@ -287,6 +293,8 @@ protected:
unique_ptr<EmberNs::RendererBase> m_Renderer;
QTIsaac<ISAAC_SIZE, ISAAC_INT> m_Rand;
Fractorium* m_Fractorium;
Palette<float> m_TempPalette;
PaletteList<float> m_PaletteList;
std::unique_ptr<QTimer> m_RenderTimer;
std::unique_ptr<QTimer> m_RenderRestartTimer;
shared_ptr<OpenCLInfo> m_Info = OpenCLInfo::Instance();
@ -451,8 +459,9 @@ public:
virtual void ResetXformsAffine(bool pre) override;
virtual void RandomXformsAffine(bool pre) override;
virtual void FillBothAffines() override;
virtual void LockAffineScaleCheckBoxStateChanged(int state) override;
virtual void InitLockedScale() override;
void FillAffineWithXform(Xform<T>* xform, bool pre);
void ChangeLockedScale(T value);
T AffineScaleCurrentToLocked();
T AffineScaleLockedToCurrent();
@ -461,6 +470,8 @@ public:
virtual void XformScrollColorIndexChanged(int d) override;
virtual void RandomColorIndicesButtonClicked() override;
virtual void ToggleColorIndicesButtonClicked() override;
virtual void RandomColorSpeedButtonClicked() override;
virtual void ToggleColorSpeedButtonClicked() override;
virtual void XformColorSpeedChanged(double d) override;
virtual void XformOpacityChanged(double d) override;
virtual void XformDirectColorChanged(double d) override;
@ -486,11 +497,13 @@ public:
bool XformCheckboxAt(Xform<T>* xform, std::function<void(QCheckBox*)> func);
//Palette.
virtual size_t InitPaletteList(const string& s) override;
virtual size_t InitPaletteList(const QString& s) override;
virtual bool FillPaletteTable(const string& s) override;
virtual void ApplyPaletteToEmber() override;
virtual void PaletteAdjust() override;
virtual void PaletteCellClicked(int row, int col) override;
virtual void SetBasePaletteAndAdjust(const Palette<float>& palette) override;
virtual void PaletteEditorButtonClicked() override;
//Info.
virtual void FillSummary() override;
@ -522,7 +535,7 @@ private:
QString MakeXformCaption(size_t i);
//Palette.
void UpdateAdjustedPaletteGUI(Palette<T>& palette);
void UpdateAdjustedPaletteGUI(Palette<float>& palette);
//Rendering/progress.
void Update(std::function<void (void)> func, bool updateRender = true, eProcessAction action = eProcessAction::FULL_RENDER);
@ -540,8 +553,6 @@ private:
deque<Ember<T>> m_UndoList;
vector<Xform<T>> m_CopiedXforms;
Xform<T> m_CopiedFinalXform;
Palette<T> m_TempPalette;
PaletteList<T> m_PaletteList;
shared_ptr<VariationList<T>> m_VariationList;
unique_ptr<SheepTools<T, float>> m_SheepTools;
unique_ptr<GLEmberController<T>> m_GLController;

View File

@ -43,6 +43,25 @@ void Fractorium::InitLibraryUI()
connect(ui.SequenceRandomBlendMaxFramesSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnSequenceRandomBlendMaxFramesSpinBoxChanged(int)), Qt::QueuedConnection);
}
/// <summary>
/// Select the item in the library tree specified by the passed in index.
/// </summary>
/// <param name="index">The 0-based index of the item in the library tree to select</param>
void Fractorium::SelectLibraryItem(size_t index)
{
if (auto top = ui.LibraryTree->topLevelItem(0))
{
for (int i = 0; i < top->childCount(); i++)
{
if (auto emberItem = dynamic_cast<EmberTreeWidgetItemBase*>(top->child(i)))
{
emberItem->setSelected(i == index);
emberItem->setCheckState(0, i == index ? Qt::Checked : Qt::Unchecked);
}
}
}
}
/// <summary>
/// Get the index of the currently selected ember in the library tree.
/// </summary>
@ -153,9 +172,7 @@ void FractoriumEmberController<T>::FillLibraryTree(int selectIndex)
tree->blockSignals(false);
if (selectIndex != -1)
if (auto top = tree->topLevelItem(0))
if (auto emberItem = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(selectIndex)))
emberItem->setSelected(true);
m_Fractorium->SelectLibraryItem(selectIndex);
m_Fractorium->SyncFileCountToSequenceCount();
QCoreApplication::flush();
@ -568,12 +585,13 @@ void FractoriumEmberController<T>::SequenceGenerateButtonClicked()
vector<pair<size_t, size_t>> devices;//Dummy.
EmberReport emberReport;
ostringstream os;
string palettePath =
#ifdef _WIN32
"./flam3-palettes.xml";
#else
"~/.config/fractorium";
#endif
string palettePath = FindFirstDefaultPalette().toStdString();
if (palettePath.empty())//This should never happen because the program requires a palette file to run this far.
{
QMessageBox::warning(nullptr, "Sequence", "No flam3-palettes.xml file found, sequence will not be generated.");
return;
}
if (!randRot && !randBlend)
{
@ -700,12 +718,15 @@ void Fractorium::OnSequenceGenerateButtonClicked(bool checked) { m_Controller->S
/// <param name="checked">Ignored.</param>
void Fractorium::OnSequenceRenderButtonClicked(bool checked)
{
//First completely stop what the current rendering process is doing.
m_Controller->DeleteRenderer();//Delete the renderer, but not the controller.
m_Controller->StopAllPreviewRenderers();
m_Controller->SaveCurrentToOpenedFile(false);//Save whatever was edited back to the current open file.
m_RenderStatusLabel->setText("Renderer stopped.");
m_FinalRenderDialog->Show(true);//Show with a bool specifying that it came from the sequence generator.
if (ui.SequenceTree->topLevelItemCount() > 0)
{
//First completely stop what the current rendering process is doing.
m_Controller->DeleteRenderer();//Delete the renderer, but not the controller.
m_Controller->StopAllPreviewRenderers();
m_Controller->SaveCurrentToOpenedFile(false);//Save whatever was edited back to the current open file.
m_RenderStatusLabel->setText("Renderer stopped.");
m_FinalRenderDialog->Show(true);//Show with a bool specifying that it came from the sequence generator.
}
}
/// <summary>
@ -825,5 +846,5 @@ void Fractorium::SyncSequenceSettings()
template class FractoriumEmberController<float>;
#ifdef DO_DOUBLE
template class FractoriumEmberController<double>;
template class FractoriumEmberController<double>;
#endif

View File

@ -27,7 +27,9 @@ void Fractorium::InitMenusUI()
connect(ui.ActionPasteSelectedXforms, SIGNAL(triggered(bool)), this, SLOT(OnActionPasteSelectedXforms(bool)), Qt::QueuedConnection);
ui.ActionPasteSelectedXforms->setEnabled(false);
//View menu.
connect(ui.ActionResetWorkspace, SIGNAL(triggered(bool)), this, SLOT(OnActionResetWorkspace(bool)), Qt::QueuedConnection);
connect(ui.ActionResetWorkspace, SIGNAL(triggered(bool)), this, SLOT(OnActionResetWorkspace(bool)), Qt::QueuedConnection);
connect(ui.ActionAlternateEditorImage, SIGNAL(triggered(bool)), this, SLOT(OnActionAlternateEditorImage(bool)), Qt::QueuedConnection);
connect(ui.ActionResetScale, SIGNAL(triggered(bool)), this, SLOT(OnActionResetScale(bool)), Qt::QueuedConnection);
//Tools menu.
connect(ui.ActionAddReflectiveSymmetry, SIGNAL(triggered(bool)), this, SLOT(OnActionAddReflectiveSymmetry(bool)), Qt::QueuedConnection);
connect(ui.ActionAddRotationalSymmetry, SIGNAL(triggered(bool)), this, SLOT(OnActionAddRotationalSymmetry(bool)), Qt::QueuedConnection);
@ -698,6 +700,38 @@ void Fractorium::OnActionResetWorkspace(bool checked)
ui.LibraryDockWidget->show();
}
/// <summary>
/// Alternate between Editor/Image.
/// </summary>
/// <param name="checked">Ignored</param>
void Fractorium::OnActionAlternateEditorImage(bool checked)
{
if (DrawImage())
{
ui.ActionDrawImage->setChecked(false);
ui.ActionDrawXforms->setChecked(true);
ui.ActionDrawGrid->setChecked(true);
}
else
{
ui.ActionDrawXforms->setChecked(false);
ui.ActionDrawGrid->setChecked(false);
ui.ActionDrawImage->setChecked(true);
}
ui.GLDisplay->update();
}
/// <summary>
/// Reset the scale used to draw affines, which was adjusted by zooming with the Alt key pressed.
/// </summary>
/// <param name="checked">Ignored</param>
void Fractorium::OnActionResetScale(bool checked)
{
m_Controller->InitLockedScale();
ui.GLDisplay->update();
}
/// <summary>
/// Add reflective symmetry to the current ember.
/// Resets the rendering process.
@ -877,5 +911,5 @@ void Fractorium::OnActionAbout(bool checked)
template class FractoriumEmberController<float>;
#ifdef DO_DOUBLE
template class FractoriumEmberController<double>;
template class FractoriumEmberController<double>;
#endif

View File

@ -2,8 +2,6 @@
#include "Fractorium.h"
#include "PaletteTableWidgetItem.h"
#define PALETTE_CELL_HEIGHT 16
/// <summary>
/// Initialize the palette UI.
/// </summary>
@ -25,8 +23,10 @@ void Fractorium::InitPaletteUI()
SetupSpinner<SpinBox, int>(table, this, row, 3, m_PaletteContrastSpin, spinHeight, -100, 100, 1, SIGNAL(valueChanged(int)), SLOT(OnPaletteAdjust(int)), true, 0, 0, 0);
SetupSpinner<SpinBox, int>(table, this, row, 3, m_PaletteBlurSpin, spinHeight, 0, 127, 1, SIGNAL(valueChanged(int)), SLOT(OnPaletteAdjust(int)), true, 0, 0, 0);
SetupSpinner<SpinBox, int>(table, this, row, 3, m_PaletteFrequencySpin, spinHeight, 1, 10, 1, SIGNAL(valueChanged(int)), SLOT(OnPaletteAdjust(int)), true, 1, 1, 1);
connect(ui.PaletteRandomSelect, SIGNAL(clicked(bool)), this, SLOT(OnPaletteRandomSelectButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.PaletteRandomAdjust, SIGNAL(clicked(bool)), this, SLOT(OnPaletteRandomAdjustButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.PaletteRandomSelectButton, SIGNAL(clicked(bool)), this, SLOT(OnPaletteRandomSelectButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.PaletteRandomAdjustButton, SIGNAL(clicked(bool)), this, SLOT(OnPaletteRandomAdjustButtonClicked(bool)), Qt::QueuedConnection);
//Palette editor.
connect(ui.PaletteEditorButton, SIGNAL(clicked(bool)), this, SLOT(OnPaletteEditorButtonClicked(bool)), Qt::QueuedConnection);
//Preview table.
palettePreviewTable->setRowCount(1);
palettePreviewTable->setColumnWidth(1, 260);//256 plus small margin on each side.
@ -38,13 +38,13 @@ void Fractorium::InitPaletteUI()
connect(ui.PaletteFilterClearButton, SIGNAL(clicked(bool)), this, SLOT(OnPaletteFilterClearButtonClicked(bool)));
paletteTable->setColumnWidth(1, 260);//256 plus small margin on each side.
paletteTable->horizontalHeader()->setSectionsClickable(true);
connect(paletteTable->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(OnPaletteHeaderSectionClicked(int)), Qt::QueuedConnection);
connect(ui.ResetCurvesButton, SIGNAL(clicked(bool)), this, SLOT(OnResetCurvesButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.CurvesView, SIGNAL(PointChangedSignal(int, int, const QPointF&)), this, SLOT(OnCurvesPointChanged(int, int, const QPointF&)), Qt::QueuedConnection);
connect(ui.CurvesAllRadio, SIGNAL(toggled(bool)), this, SLOT(OnCurvesAllRadioButtonToggled(bool)), Qt::QueuedConnection);
connect(ui.CurvesRedRadio, SIGNAL(toggled(bool)), this, SLOT(OnCurvesRedRadioButtonToggled(bool)), Qt::QueuedConnection);
connect(ui.CurvesGreenRadio, SIGNAL(toggled(bool)), this, SLOT(OnCurvesGreenRadioButtonToggled(bool)), Qt::QueuedConnection);
connect(ui.CurvesBlueRadio, SIGNAL(toggled(bool)), this, SLOT(OnCurvesBlueRadioButtonToggled(bool)), Qt::QueuedConnection);
connect(paletteTable->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(OnPaletteHeaderSectionClicked(int)), Qt::QueuedConnection);
connect(ui.ResetCurvesButton, SIGNAL(clicked(bool)), this, SLOT(OnResetCurvesButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.CurvesView, SIGNAL(PointChangedSignal(int, int, const QPointF&)), this, SLOT(OnCurvesPointChanged(int, int, const QPointF&)), Qt::QueuedConnection);
connect(ui.CurvesAllRadio, SIGNAL(toggled(bool)), this, SLOT(OnCurvesAllRadioButtonToggled(bool)), Qt::QueuedConnection);
connect(ui.CurvesRedRadio, SIGNAL(toggled(bool)), this, SLOT(OnCurvesRedRadioButtonToggled(bool)), Qt::QueuedConnection);
connect(ui.CurvesGreenRadio, SIGNAL(toggled(bool)), this, SLOT(OnCurvesGreenRadioButtonToggled(bool)), Qt::QueuedConnection);
connect(ui.CurvesBlueRadio, SIGNAL(toggled(bool)), this, SLOT(OnCurvesBlueRadioButtonToggled(bool)), Qt::QueuedConnection);
}
/// <summary>
@ -55,20 +55,28 @@ void Fractorium::InitPaletteUI()
/// <param name="s">The full path to the palette files folder</param>
/// <returns>The number of palettes successfully added</returns>
template <typename T>
size_t FractoriumEmberController<T>::InitPaletteList(const string& s)
size_t FractoriumEmberController<T>::InitPaletteList(const QString& s)
{
QDirIterator it(s.c_str(), QStringList() << "*.xml", QDir::Files, QDirIterator::FollowSymlinks);
m_PaletteList.Clear();
m_Fractorium->ui.PaletteFilenameCombo->clear();
m_Fractorium->ui.PaletteFilenameCombo->setProperty("path", QString::fromStdString(s));
QDirIterator it(s, QStringList() << "*.xml" << "*.ugr" << "*.gradient" << "*.gradients", QDir::Files, QDirIterator::FollowSymlinks);
while (it.hasNext())
{
auto path = it.next().toStdString();
auto path = it.next();
auto qfilename = it.fileName();
if (m_PaletteList.Add(path))
m_Fractorium->ui.PaletteFilenameCombo->addItem(qfilename);
try
{
if (QFile::exists(path) && m_PaletteList.Add(path.toStdString()))
m_Fractorium->ui.PaletteFilenameCombo->addItem(qfilename);
}
catch (const std::exception& e)
{
QMessageBox::critical(nullptr, "Palette Parsing Error", QString::fromStdString(e.what()));
}
catch (const char* e)
{
QMessageBox::critical(nullptr, "Palette Parsing Error", e);
}
}
return m_PaletteList.Size();
@ -79,7 +87,7 @@ size_t FractoriumEmberController<T>::InitPaletteList(const string& s)
/// This will clear any previous contents.
/// Called upon initialization, palette combo index change, and controller type change.
/// </summary>
/// <param name="s">The name to the palette file without the path</param>
/// <param name="s">The name of the palette file without the path</param>
/// <returns>True if successful, else false.</returns>
template <typename T>
bool FractoriumEmberController<T>::FillPaletteTable(const string& s)
@ -87,38 +95,10 @@ bool FractoriumEmberController<T>::FillPaletteTable(const string& s)
if (!s.empty())//This occasionally seems to get called with an empty string for reasons unknown.
{
auto paletteTable = m_Fractorium->ui.PaletteListTable;
m_CurrentPaletteFilePath = m_Fractorium->ui.PaletteFilenameCombo->property("path").toString().toStdString() + "/" + s;
m_CurrentPaletteFilePath = s;
if (int paletteSize = int(m_PaletteList.Size(m_CurrentPaletteFilePath)))
if (::FillPaletteTable(m_CurrentPaletteFilePath, paletteTable, m_PaletteList))
{
paletteTable->clear();
paletteTable->blockSignals(true);
paletteTable->setRowCount(paletteSize);
//Headers get removed when clearing, so must re-create here.
auto nameHeader = new QTableWidgetItem("Name");
auto paletteHeader = new QTableWidgetItem("Palette");
nameHeader->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
paletteHeader->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
paletteTable->setHorizontalHeaderItem(0, nameHeader);
paletteTable->setHorizontalHeaderItem(1, paletteHeader);
//Palette list table.
for (auto i = 0; i < paletteSize; i++)
{
if (auto p = m_PaletteList.GetPalette(m_CurrentPaletteFilePath, i))
{
auto v = p->MakeRgbPaletteBlock(PALETTE_CELL_HEIGHT);
auto nameCol = new QTableWidgetItem(p->m_Name.c_str());
nameCol->setToolTip(p->m_Name.c_str());
paletteTable->setItem(i, 0, nameCol);
QImage image(v.data(), int(p->Size()), PALETTE_CELL_HEIGHT, QImage::Format_RGB888);
auto paletteItem = new PaletteTableWidgetItem<T>(p);
paletteItem->setData(Qt::DecorationRole, QPixmap::fromImage(image));
paletteTable->setItem(i, 1, paletteItem);
}
}
paletteTable->blockSignals(false);
return true;
}
else
@ -126,15 +106,24 @@ bool FractoriumEmberController<T>::FillPaletteTable(const string& s)
vector<string> errors = m_PaletteList.ErrorReport();
m_Fractorium->ErrorReportToQTextEdit(errors, m_Fractorium->ui.InfoFileOpeningTextEdit);
m_Fractorium->ShowCritical("Palette Read Error", "Could not load palette file, all images will be black. See info tab for details.");
m_PaletteList.ClearErrorReport();
}
}
return false;
}
/// <summary>
/// Fill the palette table with the passed in string.
/// Called when the palette name combo box changes.
/// </summary>
/// <param name="text">The full path to the palette file</param>
void Fractorium::OnPaletteFilenameComboChanged(const QString& text)
{
m_Controller->FillPaletteTable(text.toStdString());
auto s = text.toStdString();
m_Controller->FillPaletteTable(s);
auto fullname = m_Controller->m_PaletteList.GetFullPathFromFilename(s);
ui.PaletteFilenameCombo->setToolTip(QString::fromStdString(fullname));
ui.PaletteListTable->sortItems(0, m_PaletteSortMode == 0 ? Qt::AscendingOrder : Qt::DescendingOrder);
}
@ -161,7 +150,7 @@ void FractoriumEmberController<T>::ApplyPaletteToEmber()
/// <param name="palette">The palette to use</param>
/// <param name="paletteName">Name of the palette</param>
template <typename T>
void FractoriumEmberController<T>::UpdateAdjustedPaletteGUI(Palette<T>& palette)
void FractoriumEmberController<T>::UpdateAdjustedPaletteGUI(Palette<float>& palette)
{
auto xform = CurrentXform();
auto palettePreviewTable = m_Fractorium->ui.PalettePreviewTable;
@ -205,6 +194,20 @@ void FractoriumEmberController<T>::PaletteAdjust()
void Fractorium::OnPaletteAdjust(int d) { m_Controller->PaletteAdjust(); }
/// <summary>
/// Set the passed in palette as the current one,
/// applying any adjustments previously specified.
/// Resets the rendering process.
/// </summary>
/// <param name="palette">The palette to assign to the temporary palette</param>
template <typename T>
void FractoriumEmberController<T>::SetBasePaletteAndAdjust(const Palette<float>& palette)
{
m_TempPalette = palette;//Deep copy.
ApplyPaletteToEmber();//Copy temp palette to ember palette and apply adjustments.
UpdateAdjustedPaletteGUI(m_Ember.m_Palette);//Show the adjusted palette.
}
/// <summary>
/// Set the selected palette as the current one,
/// applying any adjustments previously specified.
@ -219,12 +222,8 @@ void Fractorium::OnPaletteAdjust(int d) { m_Controller->PaletteAdjust(); }
template <typename T>
void FractoriumEmberController<T>::PaletteCellClicked(int row, int col)
{
if (auto palette = m_PaletteList.GetPalette(m_CurrentPaletteFilePath, row))
{
m_TempPalette = *palette;//Deep copy.
ApplyPaletteToEmber();//Copy temp palette to ember palette and apply adjustments.
UpdateAdjustedPaletteGUI(m_Ember.m_Palette);//Show the adjusted palette.
}
if (auto palette = m_PaletteList.GetPaletteByFilename(m_CurrentPaletteFilePath, row))
SetBasePaletteAndAdjust(*palette);
}
/// <summary>
@ -237,7 +236,7 @@ void FractoriumEmberController<T>::PaletteCellClicked(int row, int col)
/// <param name="col">The table column clicked, ignored</param>
void Fractorium::OnPaletteCellClicked(int row, int col)
{
if (auto item = dynamic_cast<PaletteTableWidgetItemBase*>(ui.PaletteListTable->item(row, 1)))
if (auto item = dynamic_cast<PaletteTableWidgetItem*>(ui.PaletteListTable->item(row, 1)))
{
auto index = int(item->Index());
@ -311,6 +310,85 @@ void Fractorium::OnPaletteRandomAdjustButtonClicked(bool checked)
OnPaletteAdjust(0);
}
/// <summary>
/// Open the palette editor dialog.
/// Called when the palette editor button is clicked.
/// </summary>
template <typename T>
void FractoriumEmberController<T>::PaletteEditorButtonClicked()
{
auto ed = m_Fractorium->m_PaletteEditor;
Palette<float> prevPal = m_TempPalette;
ed->SetPalette(m_TempPalette);
if (ed->exec() == QDialog::Accepted)
{
if (!m_Fractorium->PaletteChanged())//If the clicked ok, but never synced, set the palette now.
SetBasePaletteAndAdjust(ed->GetPalette(int(256)));
}
else if (m_Fractorium->PaletteChanged())//They clicked cancel, but synced at least once, restore the previous palette.
{
SetBasePaletteAndAdjust(prevPal);
}
//If the palette was modifiable, and any palette was changed at least once
if (m_Fractorium->m_PaletteFileChanged && m_PaletteList.IsModifiable(m_CurrentPaletteFilePath))
{
if (!::FillPaletteTable(m_CurrentPaletteFilePath, m_Fractorium->ui.PaletteListTable, m_PaletteList))
{
vector<string> errors = m_PaletteList.ErrorReport();
m_Fractorium->ErrorReportToQTextEdit(errors, m_Fractorium->ui.InfoFileOpeningTextEdit);
m_Fractorium->ShowCritical("Palette Read Error", "Could not re-load modified palette file, all images will be black. See info tab for details.");
m_PaletteList.ClearErrorReport();
}
}
}
/// <summary>
/// Slot called when the palette editor changes the palette and the Sync checkbox is checked.
/// </summary>
bool Fractorium::PaletteChanged()
{
return m_PaletteChanged;
}
/// <summary>
/// Open the palette editor dialog.
/// This creates the palette editor dialog if it has not been created at least once.
/// Called when the palette editor button is clicked.
/// </summary>
/// <param name="checked">Ignored</param>
void Fractorium::OnPaletteEditorButtonClicked(bool checked)
{
if (!m_PaletteEditor)
{
m_PaletteEditor = new PaletteEditor(m_Controller->m_PaletteList, this);
connect(m_PaletteEditor, SIGNAL(PaletteChanged()), this, SLOT(OnPaletteEditorColorChanged()), Qt::QueuedConnection);
connect(m_PaletteEditor, SIGNAL(PaletteFileChanged()), this, SLOT(OnPaletteEditorFileChanged()), Qt::QueuedConnection);
}
m_PaletteChanged = false;
m_PaletteFileChanged = false;
m_Controller->PaletteEditorButtonClicked();
}
/// <summary>
/// Slot called every time a color is changed in the palette editor.
/// </summary>
void Fractorium::OnPaletteEditorColorChanged()
{
m_PaletteChanged = true;
m_Controller->SetBasePaletteAndAdjust(m_PaletteEditor->GetPalette(int(256)));
}
/// <summary>
/// Slot called every time a palette file is changed in the palette editor.
/// </summary>
void Fractorium::OnPaletteEditorFileChanged()
{
m_PaletteFileChanged = true;
}
/// <summary>
/// Apply the text in the palette filter text box to only show palettes whose names
/// contain the substring.
@ -427,7 +505,7 @@ void Fractorium::OnCurvesPointChanged(int curveIndex, int pointIndex, const QPoi
/// select a point by putting it on top of all the others.
/// Called when the any of the curve color radio buttons are toggled.
/// </summary>
/// <param name="curveIndex">The curve index, 0-1/</param>
/// <param name="checked">Ignored</param>
void Fractorium::OnCurvesAllRadioButtonToggled(bool checked) { if (checked) ui.CurvesView->SetTop(CurveIndex::ALL); }
void Fractorium::OnCurvesRedRadioButtonToggled(bool checked) { if (checked) ui.CurvesView->SetTop(CurveIndex::RED); }
void Fractorium::OnCurvesGreenRadioButtonToggled(bool checked) { if (checked) ui.CurvesView->SetTop(CurveIndex::GREEN); }
@ -457,5 +535,5 @@ void FractoriumEmberController<T>::FillCurvesControl()
template class FractoriumEmberController<float>;
#ifdef DO_DOUBLE
template class FractoriumEmberController<double>;
template class FractoriumEmberController<double>;
#endif

View File

@ -22,11 +22,12 @@ void Fractorium::InitParamsUI()
SetFixedTableHeader(ui.IterationTableHeader->horizontalHeader());
SetFixedTableHeader(ui.AnimationTableHeader->horizontalHeader());
//Color.
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_BrightnessSpin, spinHeight, 0.05, 1000, 1, SIGNAL(valueChanged(double)), SLOT(OnBrightnessChanged(double)), true, 4.0, 4.0, 4.0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_GammaSpin, spinHeight, 1, 9999, 0.5, SIGNAL(valueChanged(double)), SLOT(OnGammaChanged(double)), true, 4.0, 4.0, 4.0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_GammaThresholdSpin, spinHeight, 0, 10, 0.01, SIGNAL(valueChanged(double)), SLOT(OnGammaThresholdChanged(double)), true, 0.1, 0.1, 0.0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_VibrancySpin, spinHeight, 0, 30, 0.01, SIGNAL(valueChanged(double)), SLOT(OnVibrancyChanged(double)), true, 1.0, 1.0, 0.0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_HighlightSpin, spinHeight, -1.0, 10, 0.1, SIGNAL(valueChanged(double)), SLOT(OnHighlightPowerChanged(double)), true, 1.0, -1.0, -1.0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_BrightnessSpin, spinHeight, 0.05, 1000, 1, SIGNAL(valueChanged(double)), SLOT(OnBrightnessChanged(double)), true, 4.0, 4.0, 4.0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_GammaSpin, spinHeight, 1, 9999, 0.5, SIGNAL(valueChanged(double)), SLOT(OnGammaChanged(double)), true, 4.0, 4.0, 4.0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_GammaThresholdSpin, spinHeight, 0, 10, 0.01, SIGNAL(valueChanged(double)), SLOT(OnGammaThresholdChanged(double)), true, 0.1, 0.1, 0.0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_VibrancySpin, spinHeight, 0, 30, 0.01, SIGNAL(valueChanged(double)), SLOT(OnVibrancyChanged(double)), true, 1.0, 1.0, 0.0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_HighlightSpin, spinHeight, -1.0, 10, 0.1, SIGNAL(valueChanged(double)), SLOT(OnHighlightPowerChanged(double)), true, 1.0, 1.0, -1.0);
m_HighlightSpin->DoubleClickLowVal(-1.0);
m_GammaThresholdSpin->setDecimals(4);
m_BackgroundColorButton = new QPushButton("...", table);
m_BackgroundColorButton->setMinimumWidth(21);
@ -63,7 +64,8 @@ void Fractorium::InitParamsUI()
//Filter.
row = 0;
table = ui.FilterTable;
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_SpatialFilterWidthSpin, spinHeight, 0.1, 2, 0.1, SIGNAL(valueChanged(double)), SLOT(OnSpatialFilterWidthChanged(double)), true, 1.0, 1.0, 1.0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_SpatialFilterWidthSpin, spinHeight, 0.1, 2, 0.1, SIGNAL(valueChanged(double)), SLOT(OnSpatialFilterWidthChanged(double)), true, 1.0, 1.0, 0.1);
m_SpatialFilterWidthSpin->DoubleClickLowVal(0.1);
comboVals = SpatialFilterCreator<float>::FilterTypes();
SetupCombo(table, this, row, 1, m_SpatialFilterTypeCombo, comboVals, SIGNAL(currentIndexChanged(const QString&)), SLOT(OnSpatialFilterTypeComboCurrentIndexChanged(const QString&)));
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_DEFilterMinRadiusSpin, spinHeight, 0, 25, 1, SIGNAL(valueChanged(double)), SLOT(OnDEFilterMinRadiusWidthChanged(double)), true, 0, 0, 0);
@ -192,7 +194,7 @@ void Fractorium::OnHighlightPowerChanged(double d) { m_Controller->HighlightPowe
/// <param name="checked">Ignored</param>
void Fractorium::OnBackgroundColorButtonClicked(bool checked)
{
m_ColorDialog->show();
m_ColorDialog->exec();
}
/// <summary>
@ -725,6 +727,7 @@ void FractoriumEmberController<T>::FillParamTablesAndPalette()
//Since the controls were cleared above, the adjusted palette will be identical to the base palette.
//Callers can set, apply and display palette adjustments after this function exits if needed.
UpdateAdjustedPaletteGUI(m_Ember.m_Palette);//Updating the palette GUI will trigger a full render.
InitLockedScale();
}
/// <summary>
@ -803,5 +806,5 @@ void Fractorium::SetScale(double scale)
template class FractoriumEmberController<float>;
#ifdef DO_DOUBLE
template class FractoriumEmberController<double>;
template class FractoriumEmberController<double>;
#endif

View File

@ -26,41 +26,69 @@
#include <QtWidgets>
#endif
#include <math.h>
#include <deque>
#include "qfunctions.h"
#include <QApplication>
#include <QBrush>
#include <QCheckBox>
#include <QClipboard>
#include <QColor>
#include <QColorDialog>
#include <QComboBox>
#include <QConicalGradient>
#include <QDebug>
#include <QDesktopWidget>
#include <QDial>
#include <QDoubleSpinBox>
#include <QEvent>
#include <QFile>
#include <QFileInfo>
#include <QFont>
#include <QFontDialog>
#include <QFontMetrics>
#include <QFrame>
#include <QFuture>
#include <QGraphicsView>
#include <QGridLayout>
#include <QGroupBox>
#include <QHash>
#include <QHBoxLayout>
#include <QIcon>
#include <QImage>
#include <QImageReader>
#include <QItemDelegate>
#include <QKeyEvent>
#include <QLabel>
#include <QLayout>
#include <QLinearGradient>
#include <QLineEdit>
#include <QMap>
#include <QMenu>
#include <QMessageBox>
#include <QMimeData>
#include <QModelIndex>
#include <QMouseEvent>
#include <qopenglfunctions_2_0.h>
#include <QOpenGLWidget>
#include <QPainter>
#include <QPainterPath>
#include <QPaintEvent>
#include <QPixmap>
#include <QPoint>
#include <QPolygon>
#include <QPushButton>
#include <QRect>
#include <QResizeEvent>
#include <QSettings>
#include <QSignalMapper>
#include <QSize>
#include <QSizePolicy>
#include <QSpinBox>
#include <QStandardPaths>
#include <QTextEdit>
#include <QTimer>
#include <QToolBar>
#include <QTreeWidget>
#include <QWheelEvent>
#include <QtConcurrentRun>
#include <QtCore/qglobal.h>
#include <QtCore/QMultiHash>
#include <QtCore/QPair>
#include <QtCore/QSharedData>
@ -68,11 +96,31 @@
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtCore/QVector>
#include <QtCore/qglobal.h>
#include <QTextEdit>
#include <QTextStream>
#include <QtGui/QFont>
#include <QtGui/QPalette>
#include <QtGui/QSyntaxHighlighter>
#include <QThread>
#include <QTime>
#include <QTimer>
#include <QToolBar>
#include <QToolTip>
#include <QTreeWidget>
#include <QtWidgets/QMainWindow>
#include <QVarLengthArray>
#include <QVBoxLayout>
#include <QVector>
#include <QWheelEvent>
#include <QWidget>
#include <QWidgetAction>
#define GLM_FORCE_RADIANS 1
#define GLM_ENABLE_EXPERIMENTAL 1
#ifndef __APPLE__
#define GLM_FORCE_INLINE 1
#endif
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"

View File

@ -109,6 +109,12 @@ void FractoriumSettings::Double(bool b) { setValue(DOUBLEPRECISION, b);
bool FractoriumSettings::ShowAllXforms() { return value(SHOWALLXFORMS).toBool(); }
void FractoriumSettings::ShowAllXforms(bool b) { setValue(SHOWALLXFORMS, b); }
bool FractoriumSettings::ShowXforms() { return value(SHOWXFORMS, QVariant::fromValue(true)).toBool(); }
void FractoriumSettings::ShowXforms(bool b) { setValue(SHOWXFORMS, b); }
bool FractoriumSettings::ShowGrid() { return value(SHOWGRID, QVariant::fromValue(true)).toBool(); }
void FractoriumSettings::ShowGrid(bool b) { setValue(SHOWGRID, b); }
bool FractoriumSettings::ToggleType() { return value(TOGGLETYPE).toBool(); }
void FractoriumSettings::ToggleType(bool b) { setValue(TOGGLETYPE, b); }

View File

@ -13,6 +13,8 @@
#define DOUBLEPRECISION "render/dp64"
#define CONTUPDATE "render/continuousupdate"
#define SHOWALLXFORMS "render/dragshowallxforms"
#define SHOWXFORMS "render/showxforms"
#define SHOWGRID "render/showgrid"
#define TOGGLETYPE "render/toggletype"
#define DEVICES "render/devices"
#define THREADCOUNT "render/threadcount"
@ -112,6 +114,12 @@ public:
bool ShowAllXforms();
void ShowAllXforms(bool b);
bool ShowXforms();
void ShowXforms(bool b);
bool ShowGrid();
void ShowGrid(bool b);
bool ToggleType();
void ToggleType(bool b);

View File

@ -14,14 +14,26 @@ void Fractorium::InitToolbarUI()
spGroup->addAction(ui.ActionSP);
spGroup->addAction(ui.ActionDP);
SyncOptionsToToolbar();
ui.ActionDrawImage->setChecked(true);
connect(ui.ActionCpu, SIGNAL(triggered(bool)), this, SLOT(OnActionCpu(bool)), Qt::QueuedConnection);
connect(ui.ActionCL, SIGNAL(triggered(bool)), this, SLOT(OnActionCL(bool)), Qt::QueuedConnection);
connect(ui.ActionSP, SIGNAL(triggered(bool)), this, SLOT(OnActionSP(bool)), Qt::QueuedConnection);
connect(ui.ActionDP, SIGNAL(triggered(bool)), this, SLOT(OnActionDP(bool)), Qt::QueuedConnection);
connect(ui.ActionStyle, SIGNAL(triggered(bool)), this, SLOT(OnActionStyle(bool)), Qt::QueuedConnection);
connect(ui.ActionStartStopRenderer, SIGNAL(triggered(bool)), this, SLOT(OnActionStartStopRenderer(bool)), Qt::QueuedConnection);
connect(ui.ActionDrawXforms, SIGNAL(triggered(bool)), this, SLOT(OnActionDrawXforms(bool)), Qt::QueuedConnection);
connect(ui.ActionDrawImage, SIGNAL(triggered(bool)), this, SLOT(OnActionDrawImage(bool)), Qt::QueuedConnection);
connect(ui.ActionDrawGrid, SIGNAL(triggered(bool)), this, SLOT(OnActionDrawGrid(bool)), Qt::QueuedConnection);
}
/// <summary>
/// GUI wrapper functions, getters only.
/// </summary>
bool Fractorium::DrawXforms() { return ui.ActionDrawXforms->isChecked(); }
bool Fractorium::DrawImage() { return ui.ActionDrawImage->isChecked(); }
bool Fractorium::DrawGrid() { return ui.ActionDrawGrid->isChecked(); }
/// <summary>
/// Called when the CPU render option on the toolbar is clicked.
/// </summary>
@ -80,7 +92,11 @@ void Fractorium::OnActionDP(bool checked)
/// <param name="checked">Ignored</param>
void Fractorium::OnActionStyle(bool checked)
{
#ifdef __APPLE__
m_QssDialog->exec();
#else
m_QssDialog->show();
#endif
}
/// <summary>
@ -105,6 +121,42 @@ void Fractorium::OnActionStartStopRenderer(bool checked)
}
}
/// <summary>
/// Toggle whether to show the affines.
/// Called when the editor image button is clicked.
/// </summary>
/// <param name="checked">Check state, show editor if true, else hide.</param>
void Fractorium::OnActionDrawXforms(bool checked)
{
if (!ui.ActionDrawImage->isChecked() && !ui.ActionDrawXforms->isChecked())
ui.ActionDrawImage->setChecked(true);
ui.GLDisplay->update();
}
/// <summary>
/// Toggle whether to show the image.
/// Called when the image button is clicked.
/// </summary>
/// <param name="checked">Check state, show image if true, else hide.</param>
void Fractorium::OnActionDrawImage(bool checked)
{
if (!ui.ActionDrawImage->isChecked() && !ui.ActionDrawXforms->isChecked())
ui.ActionDrawXforms->setChecked(true);
ui.GLDisplay->update();
}
/// <summary>
/// Toggle whether to show the grid.
/// Called when the grid image button is clicked.
/// </summary>
/// <param name="checked">Check state, show grid if true, else hide.</param>
void Fractorium::OnActionDrawGrid(bool checked)
{
ui.GLDisplay->update();
}
/// <summary>
/// Sync options data to the check state of the toolbar buttons.
/// This does not trigger a clicked() event.
@ -139,4 +191,7 @@ void Fractorium::SyncOptionsToToolbar()
ui.ActionSP->setChecked(true);
ui.ActionDP->setChecked(false);
}
ui.ActionDrawGrid->setChecked(m_Settings->ShowGrid());
ui.ActionDrawXforms->setChecked(m_Settings->ShowXforms());
}

View File

@ -70,7 +70,7 @@ void FractoriumEmberController<T>::XaosChanged(int x, int y, double val)
void Fractorium::OnXaosChanged(double d)
{
if (auto senderSpinBox = qobject_cast<DoubleSpinBox*>(this->sender()))
if (auto senderSpinBox = qobject_cast<DoubleSpinBox*>(sender()))
{
auto p = senderSpinBox->property("tableindex").toPoint();
m_Controller->XaosChanged(p.x(), p.y(), d);

View File

@ -9,7 +9,6 @@ void Fractorium::InitXformsAffineUI()
int affinePrec = 6, spinHeight = 20;
double affineStep = 0.01, affineMin = std::numeric_limits<double>::lowest(), affineMax = std::numeric_limits<double>::max();
auto table = ui.PreAffineTable;
connect(ui.LockAffineCheckBox, SIGNAL(stateChanged(int)), this, SLOT(OnLockAffineScaleCheckBoxStateChanged(int)), Qt::QueuedConnection);
table->verticalHeader()->setVisible(true);//The designer continually clobbers these values, so must manually set them here.
table->horizontalHeader()->setVisible(true);
table->verticalHeader()->setSectionsClickable(true);
@ -155,20 +154,29 @@ void Fractorium::InitXformsAffineUI()
}
/// <summary>
/// Toggle whether to lock the visual scale of the affine spinners.
/// Called when the user checks LockAffineCheckBox.
/// Set the scale used for drawing the affines to a default value.
/// </summary>
/// <param name="state">True if checked, else false.</param>
template <typename T>
void FractoriumEmberController<T>::LockAffineScaleCheckBoxStateChanged(int state)
void FractoriumEmberController<T>::InitLockedScale()
{
m_LockedScale = m_Ember.m_PixelsPerUnit;
m_LockedScale = (T)std::min<size_t>(m_Ember.m_FinalRasW, m_Ember.m_FinalRasH) / 4.0;
m_LockedX = m_Ember.m_CenterX;
m_LockedY = m_Ember.m_CenterY;
m_Fractorium->ui.GLDisplay->update();
}
void Fractorium::OnLockAffineScaleCheckBoxStateChanged(int state) { m_Controller->LockAffineScaleCheckBoxStateChanged(state); }
/// <summary>
/// Multiply the scale used for drawing the affines by the passed in value.
/// </summary>
/// <param name="value">The value to scale by</param>
template <typename T>
void FractoriumEmberController<T>::ChangeLockedScale(T value)
{
T min_size = 25.0;
m_LockedScale *= value;
if (m_LockedScale < min_size)
m_LockedScale = min_size;
}
/// <summary>
/// Return the value needed to multiply the current scale by to get back to the locked scale.
@ -177,10 +185,7 @@ void Fractorium::OnLockAffineScaleCheckBoxStateChanged(int state) { m_Controller
template <typename T>
T FractoriumEmberController<T>::AffineScaleCurrentToLocked()
{
if (m_Fractorium->ui.LockAffineCheckBox->isChecked())
return LockedScale() / m_Ember.m_PixelsPerUnit;
else
return 1;
return LockedScale() / m_Ember.m_PixelsPerUnit;
}
/// <summary>
@ -190,10 +195,7 @@ T FractoriumEmberController<T>::AffineScaleCurrentToLocked()
template <typename T>
T FractoriumEmberController<T>::AffineScaleLockedToCurrent()
{
if (m_Fractorium->ui.LockAffineCheckBox->isChecked())
return m_Ember.m_PixelsPerUnit / LockedScale();
else
return 1;
return m_Ember.m_PixelsPerUnit / LockedScale();
}
/// <summary>
@ -736,5 +738,5 @@ bool Fractorium::LocalPivot() { return ui.LocalPivotRadio->isChecked();
template class FractoriumEmberController<float>;
#ifdef DO_DOUBLE
template class FractoriumEmberController<double>;
template class FractoriumEmberController<double>;
#endif

View File

@ -18,6 +18,8 @@ void Fractorium::InitXformsColorUI()
connect(ui.XformPaletteRefTable->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), this, SLOT(OnXformRefPaletteResized(int, int, int)), Qt::QueuedConnection);
connect(ui.RandomColorIndicesButton, SIGNAL(clicked(bool)), this, SLOT(OnRandomColorIndicesButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.ToggleColorIndicesButton, SIGNAL(clicked(bool)), this, SLOT(OnToggleColorIndicesButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.RandomColorSpeedButton, SIGNAL(clicked(bool)), this, SLOT(OnRandomColorSpeedButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.ToggleColorSpeedButton, SIGNAL(clicked(bool)), this, SLOT(OnToggleColorSpeedButtonClicked(bool)), Qt::QueuedConnection);
SetupSpinner<DoubleSpinBox, double>(ui.XformColorIndexTable, this, row, 1, m_XformColorIndexSpin, spinHeight, 0, 1, 0.01, SIGNAL(valueChanged(double)), SLOT(OnXformColorIndexChanged(double)), false, 0, 1, 0);
SetupSpinner<DoubleSpinBox, double>(ui.XformColorValuesTable, this, row, 1, m_XformColorSpeedSpin, spinHeight, -1, 1, 0.1, SIGNAL(valueChanged(double)), SLOT(OnXformColorSpeedChanged(double)), true, 0.5, 0.5, 0.5);
SetupSpinner<DoubleSpinBox, double>(ui.XformColorValuesTable, this, row, 1, m_XformOpacitySpin, spinHeight, 0, 1, 0.1, SIGNAL(valueChanged(double)), SLOT(OnXformOpacityChanged(double)), true, 1, 1, 0);
@ -104,6 +106,33 @@ void FractoriumEmberController<T>::ToggleColorIndicesButtonClicked()
}
void Fractorium::OnToggleColorIndicesButtonClicked(bool b) { m_Controller->ToggleColorIndicesButtonClicked(); }
/// <summary>
/// Set all xform color speeds to a random value between 0 and 1, inclusive.
/// Called when the Random Color Speed button is clicked.
/// Resets the rendering process.
/// </summary>
template <typename T>
void FractoriumEmberController<T>::RandomColorSpeedButtonClicked()
{
UpdateXform([&](Xform<T>* xform) { xform->m_ColorSpeed = m_Rand.Frand01<T>(); }, eXformUpdate::UPDATE_ALL);
m_Fractorium->m_XformColorSpeedSpin->SetValueStealth(CurrentXform()->m_ColorSpeed);
}
void Fractorium::OnRandomColorSpeedButtonClicked(bool b) { m_Controller->RandomColorSpeedButtonClicked(); }
/// <summary>
/// Set all xform color speeds to either 0 and 0.5, sequentially toggling.
/// Called when the Toggle Color Speed button is clicked.
/// Resets the rendering process.
/// </summary>
template <typename T>
void FractoriumEmberController<T>::ToggleColorSpeedButtonClicked()
{
char ch = 1;
UpdateXform([&](Xform<T>* xform) { xform->m_ColorSpeed = (T(ch ^= 1) ? 0.5 : 0.0); }, eXformUpdate::UPDATE_ALL);
m_Fractorium->m_XformColorSpeedSpin->SetValueStealth(CurrentXform()->m_ColorSpeed);
}
void Fractorium::OnToggleColorSpeedButtonClicked(bool b) { m_Controller->ToggleColorSpeedButtonClicked(); }
/// <summary>
/// Set the color speed of the selected xforms.
/// Called when xform color speed spinner is changed.
@ -184,7 +213,7 @@ void Fractorium::OnXformRefPaletteResized(int logicalIndex, int oldSize, int new
template <typename T>
QColor FractoriumEmberController<T>::ColorIndexToQColor(double d)
{
v4T entry = m_Ember.m_Palette[Clamp<size_t>(d * COLORMAP_LENGTH_MINUS_1, 0, m_Ember.m_Palette.Size())];
v4F entry = m_Ember.m_Palette[Clamp<size_t>(d * COLORMAP_LENGTH_MINUS_1, 0, m_Ember.m_Palette.Size())];
entry.r *= 255;
entry.g *= 255;
entry.b *= 255;
@ -227,5 +256,5 @@ void Fractorium::SetPaletteTableItem(QPixmap* pixmap, QTableWidget* table, QTabl
template class FractoriumEmberController<float>;
#ifdef DO_DOUBLE
template class FractoriumEmberController<double>;
template class FractoriumEmberController<double>;
#endif

View File

@ -35,7 +35,7 @@ template <typename T>
GLEmberController<T>::GLEmberController(Fractorium* fractorium, GLWidget* glWidget, FractoriumEmberController<T>* controller)
: GLEmberControllerBase(fractorium, glWidget)
{
GridStep = T(1.0 / 8.0);
GridStep = T(1.0 / 4.0); // michel, needs to insert on GUI to be flexible//TODO
m_FractoriumEmberController = controller;
m_HoverXform = nullptr;
m_SelectedXform = nullptr;

View File

@ -112,9 +112,8 @@ public:
void CalcDragXAxis();
void CalcDragYAxis();
void CalcDragTranslation();
void SetEmber(Ember<T>* ember);
void SetSelectedXform(Xform<T>* xform);
void DrawGrid();
void DrawAffine(Xform<T>* xform, bool pre, bool selected);
int UpdateHover(v3T& glCoords);
bool CheckXformHover(Xform<T>* xform, v3T& glCoords, T& bestDist, bool pre, bool post);
@ -136,7 +135,6 @@ private:
v3T m_MouseWorldPos;
v3T m_MouseDownWorldPos;
v3T m_DragHandlePos;
v3T m_DragHandleOffset;
v3T m_HoverHandlePos;
m4T m_Modelview;

View File

@ -135,8 +135,8 @@ void GLEmberController<T>::ClearWindow()
{
auto ember = m_FractoriumEmberController->CurrentEmber();
m_GL->makeCurrent();
m_GL->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_GL->glClearColor(ember->m_Background.r, ember->m_Background.g, ember->m_Background.b, 1.0);
m_GL->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
/// <summary>
@ -209,7 +209,17 @@ void GLWidget::paintGL()
{
auto renderer = controller->Renderer();
m_Drawing = true;
GLController()->DrawImage();
if (m_Fractorium->DrawImage())
{
GLController()->DrawImage();
}
else
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
//Affine drawing.
bool pre = m_Fractorium->ui.PreAffineGroupBox->isChecked();
bool post = m_Fractorium->ui.PostAffineGroupBox->isChecked();
@ -249,8 +259,8 @@ void GLEmberController<T>::DrawImage()
{
auto renderer = m_FractoriumEmberController->Renderer();
auto ember = m_FractoriumEmberController->CurrentEmber();
m_GL->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_GL->glClearColor(ember->m_Background.r, ember->m_Background.g, ember->m_Background.b, 1.0);
m_GL->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_GL->glDisable(GL_DEPTH_TEST);
renderer->EnterFinalAccum();//Lock, may not be necessary, but just in case.
renderer->EnterResize();
@ -276,16 +286,16 @@ void GLEmberController<T>::DrawImage()
template <typename T>
void GLEmberController<T>::DrawAffines(bool pre, bool post)
{
if (!m_Fractorium->DrawXforms() || (m_DragState == eDragState::DragRotateScale))
return;
QueryVMP();//Resolves to float or double specialization function depending on T.
auto ember = m_FractoriumEmberController->CurrentEmber();
bool dragging = m_DragState == eDragState::DragDragging;
//Draw grid if control key is pressed.
if (m_GL->hasFocus() && GetControl())
{
m_GL->glLineWidth(1.0f);
m_GL->DrawGrid(m_FractoriumEmberController->AffineScaleLockedToCurrent());
}
if ((m_GL->hasFocus() && GetControl()) || m_Fractorium->DrawGrid())
DrawGrid();
//When dragging, only draw the selected xform's affine and hide all others.
if (!m_Fractorium->m_Settings->ShowAllXforms() && dragging)
@ -376,7 +386,7 @@ bool GLEmberControllerBase::KeyPress_(QKeyEvent* e)
}
/// <summary>
/// Call controller KeyPress_().
/// Call controller KeyPress().
/// </summary>
/// <param name="e">The event</param>
void GLWidget::keyPressEvent(QKeyEvent* e)
@ -466,15 +476,7 @@ void GLEmberController<T>::MousePress(QMouseEvent* e)
m_DragSrcTransforms.push_back(m_AffineType == eAffineType::AffinePre ? xform->m_Affine : xform->m_Post);
}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);//Don't update renderer here.
m_DragHandlePos = m_HoverHandlePos;//The location in local coordinates of the point selected on the spinner, x, y or center.
m_DragHandleOffset = m_DragHandlePos - m_MouseWorldPos;//The distance in world coordinates from the point selected to the center of the spinner.
m_DragState = eDragState::DragDragging;
//Draw large yellow dot on select or drag.
m_GL->glPointSize(6.0f);
m_GL->glBegin(GL_POINTS);
m_GL->glColor4f(1.0f, 1.0f, 0.5f, 1.0f);
m_GL->glVertex2f(m_DragHandlePos.x, m_DragHandlePos.y);
m_GL->glEnd();
m_GL->glPointSize(1.0f);//Restore point size.
m_GL->repaint();
}
else//Nothing was selected.
@ -491,13 +493,16 @@ void GLEmberController<T>::MousePress(QMouseEvent* e)
}
else if (e->button() == Qt::RightButton)//Right button does whole image rotation and scaling.
{
UpdateHover(mouseFlipped);
m_SelectedXform = m_HoverXform;
m_CenterDownX = ember->m_CenterX;//Capture these because they will change when rotating and scaling.
m_CenterDownY = ember->m_CenterY;
m_RotationDown = ember->m_Rotate;
m_ScaleDown = ember->m_PixelsPerUnit;
m_DragState = eDragState::DragRotateScale;
if (m_Fractorium->DrawImage())
{
UpdateHover(mouseFlipped);
m_SelectedXform = m_HoverXform;
m_CenterDownX = ember->m_CenterX;//Capture these because they will change when rotating and scaling.
m_CenterDownY = ember->m_CenterY;
m_RotationDown = ember->m_Rotate;
m_ScaleDown = ember->m_PixelsPerUnit;
m_DragState = eDragState::DragRotateScale;
}
}
}
}
@ -535,7 +540,7 @@ void GLEmberController<T>::MouseRelease(QMouseEvent* e)
m_DragState = eDragState::DragNone;
m_DragModifier = 0;
m_GL->repaint();//Force immediate redraw.
m_GL->update();
}
/// <summary>
@ -670,15 +675,27 @@ void GLWidget::mouseMoveEvent(QMouseEvent* e)
/// will zoom in the image in our out, while sacrificing quality.
/// If the user needs to preserve quality, they can use the zoom spinner
/// on the main window.
/// If Alt is pressed, only the scale of the affines is changed, the scale of the image remains untouched.
/// </summary>
/// <param name="e">The event</param>
template <typename T>
void GLEmberController<T>::Wheel(QWheelEvent* e)
{
auto ember = m_FractoriumEmberController->CurrentEmber();
if ((e->modifiers() & Qt::AltModifier) && m_Fractorium->DrawXforms())
{
m_FractoriumEmberController->ChangeLockedScale(e->angleDelta().x() >= 0 ? 1.0981 : 0.9);
m_GL->update();
}
else
{
if (m_Fractorium->DrawImage())
{
auto ember = m_FractoriumEmberController->CurrentEmber();
if (m_Fractorium && !(e->buttons() & Qt::MiddleButton))//Middle button does whole image translation, so ignore the mouse wheel while panning to avoid inadvertent zooming.
m_Fractorium->SetScale(ember->m_PixelsPerUnit + (e->angleDelta().y() >= 0 ? 50 : -50));
if (!(e->buttons() & Qt::MiddleButton))//Middle button does whole image translation, so ignore the mouse wheel while panning to avoid inadvertent zooming.
m_Fractorium->SetScale(ember->m_PixelsPerUnit + (e->angleDelta().y() >= 0 ? 50 : -50));
}
}
}
/// <summary>
@ -799,76 +816,6 @@ bool GLEmberController<T>::SizesMatch()
m_GL->m_TexHeight == m_GL->m_ViewHeight);
}
/// <summary>
/// Draw the grid in response to the control key being pressed.
/// The frequency of the grid lines will change depending on the zoom.
/// Calculated with the frame always centered, the renderer just moves the camera.
/// </summary>
/// <param name="scale">A value to scale by, used when locking the affine scale</param>
void GLWidget::DrawGrid(double scale)
{
auto renderer = m_Fractorium->m_Controller->Renderer();
float unitX = std::abs(renderer->UpperRightX(false) - renderer->LowerLeftX(false)) / 2.0f;
float unitY = std::abs(renderer->UpperRightY(false) - renderer->LowerLeftY(false)) / 2.0f;
float rad = std::max(unitX * scale, unitY * scale);
float xLow = floor(-unitX);
float xHigh = ceil(unitX);
float yLow = floor(-unitY);
float yHigh = ceil(unitY);
glBegin(GL_LINES);
if (rad <= 8.0f)
{
glColor4f(0.5f, 0.5f, 0.5f, 0.5f);
for (float fx = xLow; fx <= xHigh; fx += GridStep)
{
glVertex2f(fx, yLow);
glVertex2f(fx, yHigh);
}
for (float fy = yLow; fy < yHigh; fy += GridStep)
{
glVertex2f(xLow, fy);
glVertex2f(xHigh, fy);
}
}
unitX *= scale;
unitY *= scale;
if (unitX <= 64.0f)
{
glColor4f(0.5f, 0.5f, 0.5f, 1.0f);
for (float fx = xLow; fx <= xHigh; fx += 1.0f)
{
glVertex2f(fx, yLow);
glVertex2f(fx, yHigh);
}
for (float fy = yLow; fy < yHigh; fy += 1.0f)
{
glVertex2f(xLow, fy);
glVertex2f(xHigh, fy);
}
}
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glVertex2f(0.0f, 0.0f);
glVertex2f(xHigh, 0.0f);
glColor4f(0.5f, 0.0f, 0.0f, 1.0f);
glVertex2f(0.0f, 0.0f);
glVertex2f(xLow, 0.0f);
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.0f, yHigh);
glColor4f(0.0f, 0.5f, 0.0f, 1.0f);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.0f, yLow);
glEnd();
}
/// <summary>
/// Draw the unit square.
/// </summary>
@ -894,6 +841,60 @@ void GLWidget::DrawUnitSquare()
glEnd();
}
/// <summary>
/// Draw the grid
/// The frequency of the grid lines will change depending on the zoom (ALT+WHEEL).
/// Calculated with the frame always centered, the renderer just moves the camera.
/// </summary>
template <typename T>
void GLEmberController<T>::DrawGrid()
{
auto renderer = m_Fractorium->m_Controller->Renderer();
double scale = m_FractoriumEmberController->AffineScaleCurrentToLocked();
float unitX = (std::abs(renderer->UpperRightX(false) - renderer->LowerLeftX(false)) / 2.0f) / scale;
float unitY = (std::abs(renderer->UpperRightY(false) - renderer->LowerLeftY(false)) / 2.0f) / scale;
float xLow = floor(-unitX);
float xHigh = ceil(unitX);
float yLow = floor(-unitY);
float yHigh = ceil(unitY);
float alpha = 0.25f;
Affine2D<T> temp;
m4T mat = (temp * scale).ToMat4RowMajor();
m_GL->glPushMatrix();
m_GL->glLoadIdentity();
MultMatrix(mat);
m_GL->glLineWidth(1.0f);
m_GL->glBegin(GL_LINES);
m_GL->glColor4f(0.5f, 0.5f, 0.5f, alpha);
for (float fx = xLow; fx <= xHigh; fx += GridStep)
{
m_GL->glVertex2f(fx, yLow);
m_GL->glVertex2f(fx, yHigh);
}
for (float fy = yLow; fy < yHigh; fy += GridStep)
{
m_GL->glVertex2f(xLow, fy);
m_GL->glVertex2f(xHigh, fy);
}
m_GL->glColor4f(1.0f, 0.0f, 0.0f, alpha);
m_GL->glVertex2f(0.0f, 0.0f);
m_GL->glVertex2f(xHigh, 0.0f);
m_GL->glColor4f(0.5f, 0.0f, 0.0f, alpha);
m_GL->glVertex2f(0.0f, 0.0f);
m_GL->glVertex2f(xLow, 0.0f);
m_GL->glColor4f(0.0f, 1.0f, 0.0f, alpha);
m_GL->glVertex2f(0.0f, 0.0f);
m_GL->glVertex2f(0.0f, yHigh);
m_GL->glColor4f(0.0f, 0.5f, 0.0f, alpha);
m_GL->glVertex2f(0.0f, 0.0f);
m_GL->glVertex2f(0.0f, yLow);
m_GL->glEnd();
m_GL->glPopMatrix();
}
/// <summary>
/// Draw the pre or post affine circle for the passed in xform.
/// For drawing affine transforms, multiply the identity model view matrix by the
@ -1028,42 +1029,45 @@ int GLEmberController<T>::UpdateHover(v3T& glCoords)
auto ember = m_FractoriumEmberController->CurrentEmber();
m_HoverType = eHoverType::HoverNone;
//If there's a selected/current xform, check it first so it gets precedence over the others.
if (m_SelectedXform)
if (m_Fractorium->DrawXforms())//Don't bother checking anything if the user wants to see no xforms.
{
//These checks prevent highlighting the pre/post selected xform circle, when one is set to show all, and the other
//is set to show current, and the user hovers over another xform, but doesn't select it, then moves the mouse
//back over the hidden circle for the pre/post that was set to only show current.
bool checkSelPre = preAll || (pre && m_HoverXform == m_SelectedXform);
bool checkSelPost = postAll || (post && m_HoverXform == m_SelectedXform);
if (CheckXformHover(m_SelectedXform, glCoords, bestDist, checkSelPre, checkSelPost))
//If there's a selected/current xform, check it first so it gets precedence over the others.
if (m_SelectedXform)
{
m_HoverXform = m_SelectedXform;
bestIndex = int(ember->GetTotalXformIndex(m_SelectedXform));
}
}
//These checks prevent highlighting the pre/post selected xform circle, when one is set to show all, and the other
//is set to show current, and the user hovers over another xform, but doesn't select it, then moves the mouse
//back over the hidden circle for the pre/post that was set to only show current.
bool checkSelPre = preAll || (pre && m_HoverXform == m_SelectedXform);
bool checkSelPost = postAll || (post && m_HoverXform == m_SelectedXform);
//Check all xforms.
for (int i = 0; i < int(ember->TotalXformCount()); i++)
{
auto xform = ember->GetTotalXform(i);
if (preAll || (pre && m_HoverXform == xform))//Only check pre affine if they are shown.
{
if (CheckXformHover(xform, glCoords, bestDist, true, false))
if (CheckXformHover(m_SelectedXform, glCoords, bestDist, checkSelPre, checkSelPost))
{
m_HoverXform = xform;
bestIndex = i;
m_HoverXform = m_SelectedXform;
bestIndex = int(ember->GetTotalXformIndex(m_SelectedXform));
}
}
if (postAll || (post && m_HoverXform == xform))//Only check post affine if they are shown.
//Check all xforms.
for (int i = 0; i < int(ember->TotalXformCount()); i++)
{
if (CheckXformHover(xform, glCoords, bestDist, false, true))
auto xform = ember->GetTotalXform(i);
if (preAll || (pre && m_HoverXform == xform))//Only check pre affine if they are shown.
{
m_HoverXform = xform;
bestIndex = i;
if (CheckXformHover(xform, glCoords, bestDist, true, false))
{
m_HoverXform = xform;
bestIndex = i;
}
}
if (postAll || (post && m_HoverXform == xform))//Only check post affine if they are shown.
{
if (CheckXformHover(xform, glCoords, bestDist, false, true))
{
m_HoverXform = xform;
bestIndex = i;
}
}
}
}
@ -1207,18 +1211,17 @@ template <typename T>
void GLEmberController<T>::CalcDragXAxis()
{
size_t index = 0;
auto scale = m_FractoriumEmberController->AffineScaleLockedToCurrent();
auto scaleBack = m_FractoriumEmberController->AffineScaleCurrentToLocked();
auto affineToWorldScale = m_FractoriumEmberController->AffineScaleLockedToCurrent();
auto worldToAffineScale = m_FractoriumEmberController->AffineScaleCurrentToLocked();
bool pre = m_AffineType == eAffineType::AffinePre;
bool worldPivotShiftAlt = !m_Fractorium->LocalPivot() && GetShift() && GetAlt();
auto startDiff = (v2T(m_HoverHandlePos) * affineToWorldScale) - m_DragSrcTransform.O();
T startAngle = std::atan2(startDiff.y, startDiff.x);
if (GetShift())
{
auto posOffset = m_MouseWorldPos + m_DragHandleOffset;
v3T snapped = GetControl() ? SnapToNormalizedAngle(posOffset, 24u) : posOffset;
auto startDiff = (v2T(m_MouseDownWorldPos) * scale) - m_DragSrcTransform.O();
auto endDiff = (v2T(snapped) * scale) - m_DragSrcTransform.O();
T startAngle = std::atan2(startDiff.y, startDiff.x);
v3T snapped = GetControl() ? SnapToNormalizedAngle(m_MouseWorldPos, 24u) : m_MouseWorldPos;
auto endDiff = (v2T(snapped) * affineToWorldScale) - m_DragSrcTransform.O();
T endAngle = std::atan2(endDiff.y, endDiff.x);
T angle = startAngle - endAngle;
m_FractoriumEmberController->UpdateXform([&](Xform<T>* xform)
@ -1245,32 +1248,47 @@ void GLEmberController<T>::CalcDragXAxis()
}
if (xform == m_FractoriumEmberController->CurrentXform())
m_DragHandlePos = v3T((affine.O() + affine.X()) * scaleBack, 0);
m_DragHandlePos = v3T((affine.O() + affine.X()) * worldToAffineScale, 0);
}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);//Calling code will update renderer.
}
else
{
v3T diff;
auto posOffset = m_MouseWorldPos + m_DragHandleOffset;
v3T diff = m_MouseWorldPos - m_MouseDownWorldPos;
auto diffscale = diff * affineToWorldScale;
auto origmag = Zeps(glm::length(m_DragSrcTransform.X()));
auto origXPlusOff = v3T(m_DragSrcTransform.X(), 0) + diffscale;
if (GetControl())
diff = SnapToGrid(posOffset) - m_MouseDownWorldPos;
else
diff = posOffset - m_MouseDownWorldPos;
{
auto o3 = v3T(m_DragSrcTransform.O(), 0);
auto o3x = origXPlusOff + o3;
origXPlusOff = SnapToGrid(o3x);
origXPlusOff -= o3;
}
auto origXPlusOff = v3T(m_DragSrcTransform.X(), 0) + (diff * scale);
auto newmag = glm::length(origXPlusOff);
auto newprc = newmag / origmag;
auto endDiff = (v2T(origXPlusOff) * affineToWorldScale);
T endAngle = std::atan2(endDiff.y, endDiff.x);
T angle = startAngle - endAngle;
m_FractoriumEmberController->UpdateXform([&](Xform<T>* xform)
{
auto& affine = pre ? xform->m_Affine : xform->m_Post;
auto axis = v3T(m_DragSrcTransforms[index++].X(), 0) + (diff * scale);
auto src = m_DragSrcTransforms[index++];
if (GetAlt())
{
affine.X(v2T(origXPlusOff));//Absolute, not ratio.
}
else
affine.RotateScaleXTo(v2T(axis));
{
src.ScaleXY(newprc);
src.Rotate(angle);
affine = src;
}
if (xform == m_FractoriumEmberController->CurrentXform())
m_DragHandlePos = v3T((affine.O() + affine.X()) * scaleBack, 0);
m_DragHandlePos = v3T((affine.O() + affine.X()) * worldToAffineScale, 0);
}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);
}
}
@ -1297,18 +1315,17 @@ template <typename T>
void GLEmberController<T>::CalcDragYAxis()
{
size_t index = 0;
auto scale = m_FractoriumEmberController->AffineScaleLockedToCurrent();
auto scaleBack = m_FractoriumEmberController->AffineScaleCurrentToLocked();
auto affineToWorldScale = m_FractoriumEmberController->AffineScaleLockedToCurrent();
auto worldToAffineScale = m_FractoriumEmberController->AffineScaleCurrentToLocked();
bool pre = m_AffineType == eAffineType::AffinePre;
bool worldPivotShiftAlt = !m_Fractorium->LocalPivot() && GetShift() && GetAlt();
auto startDiff = (v2T(m_HoverHandlePos) * affineToWorldScale) - m_DragSrcTransform.O();
T startAngle = std::atan2(startDiff.y, startDiff.x);
if (GetShift())
{
auto posOffset = m_MouseWorldPos + m_DragHandleOffset;
v3T snapped = GetControl() ? SnapToNormalizedAngle(posOffset, 24u) : posOffset;
auto startDiff = (v2T(m_MouseDownWorldPos) * scale) - m_DragSrcTransform.O();
auto endDiff = (v2T(snapped) * scale) - m_DragSrcTransform.O();
T startAngle = std::atan2(startDiff.y, startDiff.x);
v3T snapped = GetControl() ? SnapToNormalizedAngle(m_MouseWorldPos, 24u) : m_MouseWorldPos;
auto endDiff = (v2T(snapped) * affineToWorldScale) - m_DragSrcTransform.O();
T endAngle = std::atan2(endDiff.y, endDiff.x);
T angle = startAngle - endAngle;
m_FractoriumEmberController->UpdateXform([&](Xform<T>* xform)
@ -1335,32 +1352,47 @@ void GLEmberController<T>::CalcDragYAxis()
}
if (xform == m_FractoriumEmberController->CurrentXform())
m_DragHandlePos = v3T((affine.O() + affine.Y()) * scaleBack, 0);
m_DragHandlePos = v3T((affine.O() + affine.Y()) * worldToAffineScale, 0);
}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);//Calling code will update renderer.
}
else
{
v3T diff;
auto posOffset = m_MouseWorldPos + m_DragHandleOffset;
v3T diff = m_MouseWorldPos - m_MouseDownWorldPos;
auto diffscale = diff * affineToWorldScale;
auto origmag = Zeps(glm::length(m_DragSrcTransform.Y()));
auto origYPlusOff = v3T(m_DragSrcTransform.Y(), 0) + diffscale;
if (GetControl())
diff = SnapToGrid(posOffset) - m_MouseDownWorldPos;
else
diff = posOffset - m_MouseDownWorldPos;
{
auto o3 = v3T(m_DragSrcTransform.O(), 0);
auto o3y = origYPlusOff + o3;
origYPlusOff = SnapToGrid(o3y);
origYPlusOff -= o3;
}
auto origXPlusOff = v3T(m_DragSrcTransform.Y(), 0) + (diff * scale);
auto newmag = glm::length(origYPlusOff);
auto newprc = newmag / origmag;
auto endDiff = (v2T(origYPlusOff) * affineToWorldScale);
T endAngle = std::atan2(endDiff.y, endDiff.x);
T angle = startAngle - endAngle;
m_FractoriumEmberController->UpdateXform([&](Xform<T>* xform)
{
auto& affine = pre ? xform->m_Affine : xform->m_Post;
auto axis = v3T(m_DragSrcTransforms[index++].Y(), 0) + (diff * scale);
auto src = m_DragSrcTransforms[index++];
if (GetAlt())
affine.Y(v2T(origXPlusOff));//Absolute, not ratio.
{
affine.Y(v2T(origYPlusOff));//Absolute, not ratio.
}
else
affine.RotateScaleYTo(v2T(axis));
{
src.ScaleXY(newprc);
src.Rotate(angle);
affine = src;
}
if (xform == m_FractoriumEmberController->CurrentXform())
m_DragHandlePos = v3T((affine.O() + affine.Y()) * scaleBack, 0);
m_DragHandlePos = v3T((affine.O() + affine.Y()) * worldToAffineScale, 0);
}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);
}
}
@ -1382,8 +1414,8 @@ template <typename T>
void GLEmberController<T>::CalcDragTranslation()
{
size_t index = 0;
auto scale = m_FractoriumEmberController->AffineScaleLockedToCurrent();
auto scaleBack = m_FractoriumEmberController->AffineScaleCurrentToLocked();
auto affineToWorldScale = m_FractoriumEmberController->AffineScaleLockedToCurrent();
auto worldToAffineScale = m_FractoriumEmberController->AffineScaleCurrentToLocked();
bool worldPivotShift = !m_Fractorium->LocalPivot() && GetShift();
bool pre = m_AffineType == eAffineType::AffinePre;
@ -1409,7 +1441,7 @@ void GLEmberController<T>::CalcDragTranslation()
affine.O(srcRotated.O());
if (xform == m_FractoriumEmberController->CurrentXform())
m_DragHandlePos = v3T(srcRotated.O(), 0) * scaleBack;
m_DragHandlePos = v3T(srcRotated.O(), 0) * worldToAffineScale;
}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);//Calling code will update renderer.
}
else
@ -1421,20 +1453,24 @@ void GLEmberController<T>::CalcDragTranslation()
m_FractoriumEmberController->UpdateXform([&](Xform<T>* xform)
{
auto& affine = pre ? xform->m_Affine : xform->m_Post;
auto offset = m_DragSrcTransforms[index++].O() + (scale * v2T(diff));
auto offset = m_DragSrcTransforms[index++].O() + (affineToWorldScale * v2T(diff));
auto snapped = SnapToGrid(offset);
affine.O(v2T(snapped.x, snapped.y));
if (xform == m_FractoriumEmberController->CurrentXform())
m_DragHandlePos = v3T(affine.O(), 0) * worldToAffineScale;
}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);
m_DragHandlePos = SnapToGrid(m_MouseWorldPos);
}
else
{
m_FractoriumEmberController->UpdateXform([&](Xform<T>* xform)
{
auto& affine = pre ? xform->m_Affine : xform->m_Post;
affine.O(m_DragSrcTransforms[index++].O() + (scale * v2T(diff)));
affine.O(m_DragSrcTransforms[index++].O() + (affineToWorldScale * v2T(diff)));
if (xform == m_FractoriumEmberController->CurrentXform())
m_DragHandlePos = v3T(affine.O(), 0) * worldToAffineScale;
}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);
m_DragHandlePos = m_MouseWorldPos;
}
}
}
@ -1454,5 +1490,5 @@ GLEmberControllerBase* GLWidget::GLController()
template class GLEmberController<float>;
#ifdef DO_DOUBLE
template class GLEmberController<double>;
template class GLEmberController<double>;
#endif

View File

@ -11,8 +11,6 @@ class GLEmberControllerBase;
template<typename T> class GLEmberController;
template<typename T> class FractoriumEmberController;
static const float GridStep = 1.0f / 8.0f;
/// <summary>
/// The main drawing area.
/// This uses the Qt wrapper around OpenGL to draw the output of the render to a texture whose
@ -68,7 +66,6 @@ private:
bool Allocate(bool force = false);
bool Deallocate();
void SetViewport();
void DrawGrid(double scale);
void DrawUnitSquare();
void DrawAffineHelper(int index, bool selected, bool pre, bool final, bool background);
GLEmberControllerBase* GLController();

View File

@ -10,6 +10,7 @@
/// <returns>0 if successful, else 1.</returns>
int main(int argc, char* argv[])
{
int rv = -1;
QApplication a(argc, argv);
#ifdef TEST_CL
QMessageBox::critical(QApplication::desktop(), "Error", "Fractorium cannot be run in test mode, undefine TEST_CL first.");
@ -19,16 +20,9 @@ int main(int argc, char* argv[])
QMessageBox::critical(QApplication::desktop(), "Error", "Fractorium cannot be run in test mode, undefine ISAAC_FLAM3_DEBUG first.");
return 1;
#endif
//Required for large allocs, else GPU memory usage will be severely limited to small sizes.
//This must be done in the application and not in the EmberCL DLL.
#ifdef _WIN32
_putenv_s("GPU_MAX_ALLOC_PERCENT", "100");
#else
putenv(const_cast<char*>("GPU_MAX_ALLOC_PERCENT=100"));
#endif
int rv = -1;
auto vf = VarFuncs<float>::Instance();//Create instances that will stay alive until the program exits.
auto vlf = VariationList<float>::Instance();
auto settings = FractoriumSettings::Instance();
#ifdef DO_DOUBLE
auto vd = VarFuncs<float>::Instance();
auto vld = VariationList<double>::Instance();//No further creations should occur after this.
@ -36,6 +30,13 @@ int main(int argc, char* argv[])
try
{
//Required for large allocs, else GPU memory usage will be severely limited to small sizes.
//This must be done in the application and not in the EmberCL DLL.
#ifdef _WIN32
_putenv_s("GPU_MAX_ALLOC_PERCENT", "100");
#else
putenv(const_cast<char*>("GPU_MAX_ALLOC_PERCENT=100"));
#endif
Fractorium w;
w.show();
a.installEventFilter(&w);
@ -43,11 +44,11 @@ int main(int argc, char* argv[])
}
catch (const std::exception& e)
{
QMessageBox::critical(0, "Fatal Error", QString::fromStdString(e.what()));
QMessageBox::critical(nullptr, "Fatal Error", QString::fromStdString(e.what()));
}
catch (const char* e)
{
QMessageBox::critical(0, "Fatal Error", e);
QMessageBox::critical(nullptr, "Fatal Error", e);
}
return rv;

View File

@ -0,0 +1,357 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PaletteEditor</class>
<widget class="QDialog" name="PaletteEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>942</width>
<height>542</height>
</rect>
</property>
<property name="windowTitle">
<string>Palette Editor</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<layout class="QVBoxLayout" name="LeftSideVertialLayout">
<property name="spacing">
<number>4</number>
</property>
<item>
<layout class="QHBoxLayout" name="LeftTopHorizontalLayout">
<item>
<widget class="QPushButton" name="NewPaletteFileButton">
<property name="text">
<string>New Palette File...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="CopyPaletteFileButton">
<property name="text">
<string>Copy Palette File</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QComboBox" name="PaletteFilenameCombo"/>
</item>
<item>
<widget class="QTableWidget" name="PaletteListTable">
<property name="frameShape">
<enum>QFrame::Panel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="autoScroll">
<bool>false</bool>
</property>
<property name="editTriggers">
<set>QAbstractItemView::AllEditTriggers</set>
</property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectItems</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="cornerButtonEnabled">
<bool>false</bool>
</property>
<property name="columnCount">
<number>2</number>
</property>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>16</number>
</attribute>
<attribute name="verticalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderMinimumSectionSize">
<number>16</number>
</attribute>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Palette</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="LeftBottomHorizontalLayout">
<item>
<widget class="QPushButton" name="AppendPaletteButton">
<property name="text">
<string>Append Palette</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="OverwritePaletteButton">
<property name="text">
<string>Overwrite Palette</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="DeletePaletteButton">
<property name="text">
<string>Delete Palette</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="MainVerticalLayout">
<item>
<widget class="QGroupBox" name="ColorViewGroupBox">
<property name="title">
<string>Palette</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="ColorPickerGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="title">
<string>Color Picker</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="ControlsGroupBox">
<property name="title">
<string>Adjustment Controls</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,4">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<layout class="QGridLayout" name="AdjustmentLeftGridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="SyncCheckBox">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>Sync</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QSpinBox" name="ArrowsSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string>Arrows: </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>256</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="AutoDistributeCheckBox">
<property name="text">
<string>Auto Distribute</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="AdjustmentRightGridLayout">
<item row="1" column="2">
<widget class="QPushButton" name="CreatePaletteFromImageButton">
<property name="text">
<string>Create From Image</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="ResetColorsButton">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="RandomColorsButton">
<property name="text">
<string>Random Colors</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="RemoveColorButton">
<property name="text">
<string>Remove Color</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="DistributeColorsButton">
<property name="text">
<string>Distribute Colors</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="AddColorButton">
<property name="text">
<string>Add Color</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="InvertColorsButton">
<property name="text">
<string>Invert Colors</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="CreatePaletteAgainFromImageButton">
<property name="text">
<string>Create Again From Image</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PaletteEditor</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PaletteEditor</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,79 @@
/*
Copyright (C) 2009, Etienne Moutot <e.moutot@gmail.com>
This file is part of colorPickerWidget.
colorPickerWidget 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 3 of the License, or
(at your option) any later version.
colorPickerWidget 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "FractoriumPch.h"
#include "ColorPanel.h"
/// <summary>
/// Constructor which passes parent widget to the base and initializes the minimum size.
/// </summary>
/// <param name="p">The parent widget</param>
ColorPanel::ColorPanel(QWidget* p)
: QPushButton(p)
{
setMinimumSize(10, 10);
}
/// <summary>
/// Derived paint event which paints the entire button surface with m_Color.
/// </summary>
void ColorPanel::paintEvent(QPaintEvent*)
{
QPainter p(this);
p.setPen(m_Pen);
p.setBrush(QBrush(m_Color));
p.drawRect(QRect(2, 2, width() - 6, height() - 6));
}
/// <summary>
/// Set the pen object used to paint the button.
/// </summary>
/// <param name="pen">The pen object used to paint the button</param>
void ColorPanel::Pen(const QPen& pen)
{
m_Pen = pen;
update();
}
/// <summary>
/// Get the pen object used to paint the button.
/// </summary>
/// <returns>QPen</returns>
QPen ColorPanel::Pen() const
{
return m_Pen;
}
/// <summary>
/// Set the color used to paint the button.
/// </summary>
/// <param name="color">The color used to paint the button</param>
void ColorPanel::Color(const QColor& color)
{
m_Color = color;
update();
}
/// <summary>
/// Get the color used to paint the button.
/// </summary>
/// <returns>QColor</returns>
QColor ColorPanel::Color() const
{
return m_Color;
}

View File

@ -0,0 +1,47 @@
/*
Copyright (C) 2009, Etienne Moutot <e.moutot@gmail.com>
This file is part of colorPickerWidget.
colorPickerWidget 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 3 of the License, or
(at your option) any later version.
colorPickerWidget 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "FractoriumPch.h"
/// <summary>
/// A derivation of a QPushButton which makes a large, clickable panel
/// which custom paints the button based on a user specified color.
/// </summary>
class ColorPanel : public QPushButton
{
Q_OBJECT
public:
ColorPanel(QWidget* p = nullptr);
void Pen(const QPen& pen);
QPen Pen() const;
void Color(const QColor& color);
QColor Color() const;
protected:
virtual void paintEvent(QPaintEvent* event) override;
private:
QPen m_Pen;
QColor m_Color;
};

View File

@ -0,0 +1,96 @@
/*
Copyright (C) 2009, Etienne Moutot <e.moutot@gmail.com>
This file is part of colorPickerWidget.
colorPickerWidget 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 3 of the License, or
(at your option) any later version.
colorPickerWidget 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include "FractoriumPch.h"
#include "ColorPickerWidget.h"
/// <summary>
/// Constructor which passes parent widget to the base and initializes the member controls
/// on a grid layout.
/// </summary>
/// <param name="p">The parent widget</param>
ColorPickerWidget::ColorPickerWidget(QWidget* p)
: QWidget(p)
{
m_ColorTriangle = new ColorTriangle(this);
m_ColorPanel = new ColorPanel(this);
m_ColorDialog = new QColorDialog(this);
m_ColorPanel->Color(m_ColorTriangle->Color());
connect(m_ColorTriangle, SIGNAL(ColorChanged(const QColor&)), this, SLOT(OnTriangleColorChanged(const QColor&)));
connect(m_ColorPanel, SIGNAL(clicked()), this, SLOT(OnColorViewerClicked()));
auto layout = new QGridLayout(this);
layout->setMargin(4);
layout->addWidget(m_ColorTriangle, 0, 0, 3, 1);
layout->addWidget(m_ColorPanel, 0, 1, 3, 1);
setLayout(layout);
}
/// <summary>
/// Get the color used to paint the color panel.
/// </summary>
/// <returns>QColor</returns>
QColor ColorPickerWidget::Color() const
{
return m_ColorPanel->Color();
}
/// <summary>
/// Set the current color for the triangle.
/// </summary>
/// <param name="col">The parent widget</param>
void ColorPickerWidget::SetColorPanelColor(const QColor& col)
{
if (col.isValid())
m_ColorTriangle->Color(col);//Internally emits ColorChanged() which will call OnTriangleColorChanged(), which will call m_ColorPanel->Color().
}
/// <summary>
/// Overridden resize event to set the color panel height slightly
/// smaller than the container it's in.
/// </summary>
/// <param name="col">The resize event</param>
void ColorPickerWidget::resizeEvent(QResizeEvent* event)
{
m_ColorPanel->setMinimumHeight(event->size().height() - 22);
m_ColorPanel->setMaximumHeight(event->size().height() - 22);
}
/// <summary>
/// Slot called when the color panel is clicked, which will show the color
/// picker dialog.
/// </summary>
void ColorPickerWidget::OnColorViewerClicked()
{
m_ColorDialog->setCurrentColor(m_ColorPanel->Color());
auto newColor = m_ColorDialog->getColor(m_ColorPanel->Color(), this);
SetColorPanelColor(newColor);
}
/// <summary>
/// Slot called when the color on the triangle changes for any reason,
/// either user initiated or programatically called.
/// </summary>
/// <param name="col">The new color on the triangle</param>
void ColorPickerWidget::OnTriangleColorChanged(const QColor& col)
{
if (col.isValid())
m_ColorPanel->Color(col);
emit ColorChanged(col);
}

View File

@ -0,0 +1,54 @@
/*
Copyright (C) 2009, Etienne Moutot <e.moutot@gmail.com>
This file is part of colorPickerWidget.
colorPickerWidget 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 3 of the License, or
(at your option) any later version.
colorPickerWidget 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "FractoriumPch.h"
#include "ColorTriangle.h"
#include "ColorPanel.h"
/// <summary>
/// Aggregator class to package a color triangle, color panel, and color dialog
/// all together on a layout.
/// </summary>
class ColorPickerWidget : public QWidget
{
Q_OBJECT
public:
ColorPickerWidget(QWidget* p = nullptr);
QColor Color() const;
void SetColorPanelColor(const QColor& col);
Q_SIGNALS:
void ColorChanged(const QColor& col);
protected:
void resizeEvent(QResizeEvent* event) override;
private slots:
void OnColorViewerClicked();
void OnTriangleColorChanged(const QColor& col);
private:
ColorTriangle* m_ColorTriangle;
ColorPanel* m_ColorPanel;
QColorDialog* m_ColorDialog;
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,138 @@
/****************************************************************************
**
** This file is part of a Qt Solutions component.
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Solutions Commercial License Agreement provided
** with the Software or, alternatively, in accordance with the terms
** contained in a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** Please note Third Party Software included with Qt Solutions may impose
** additional restrictions and it is the user's responsibility to ensure
** that they have met the licensing requirements of the GPL, LGPL, or Qt
** Solutions Commercial license and the relevant license of the Third
** Party Software they are using.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
****************************************************************************/
#pragma once
#include "FractoriumPch.h"
/// <summary>
/// DoubleColor, Vertex and ColorTriangle classes.
/// </summary>
/// <summary>
/// Used to store color values in the range 0..255 as doubles.
/// </summary>
struct DoubleColor
{
double r, g, b;
DoubleColor() : r(0.0), g(0.0), b(0.0) {}
DoubleColor(double red, double green, double blue) : r(red), g(green), b(blue) {}
DoubleColor(const DoubleColor& c) : r(c.r), g(c.g), b(c.b) {}
};
/// <summary>
/// Used to store pairs of DoubleColor and DoublePoint in one structure.
/// </summary>
struct Vertex
{
DoubleColor color;
QPointF point;
Vertex(const DoubleColor& c, const QPointF& p) : color(c), point(p) {}
Vertex(const QColor& c, const QPointF& p)
: color(DoubleColor((double)c.red(), (double)c.green(),
(double)c.blue())), point(p) {}
};
/// <summary>
/// Widget for drawing a color triangle which allows users to select colors
/// in a manner more intuitive than the usual color picker dialog.
/// This class was taken from an open source project named Chaos Helper, which took
/// it from the Qt examples, so it mostly remains as-is.
/// </summary>
class ColorTriangle : public QWidget
{
Q_OBJECT
public:
ColorTriangle(QWidget* parent = nullptr);
void Polish();
QColor Color() const;
void Color(const QColor& col);
virtual int heightForWidth(int w) const override;
virtual QSize sizeHint() const override;
signals:
void ColorChanged(const QColor& col);
protected:
virtual void paintEvent(QPaintEvent*) override;
virtual void mouseMoveEvent(QMouseEvent*) override;
virtual void mousePressEvent(QMouseEvent*) override;
virtual void mouseReleaseEvent(QMouseEvent*) override;
virtual void keyPressEvent(QKeyEvent* e) override;
virtual void resizeEvent(QResizeEvent*) override;
private:
void GenBackground();
void DrawTrigon(QImage* p, const QPointF& a, const QPointF& b, const QPointF& c, const QColor& color);
double CalcOuterRadius() const;
double RadiusAt(const QPointF& pos, const QRect& rect) const;
double AngleAt(const QPointF& pos, const QRect& rect) const;
QColor ColorFromPoint(const QPointF& p) const;
QPointF PointFromColor(const QColor& col) const;
QPointF MovePointToTriangle(double x, double y, const Vertex& a, const Vertex& b, const Vertex& c) const;
bool mustGenerateBackground;
int curHue;
int penWidth;
int ellipseSize;
int outerRadius;
double a, b, c;
QImage bg;
QColor curColor;
QPointF pa, pb, pc, pd;
QPointF selectorPos;
enum SelectionMode
{
Idle,
SelectingHue,
SelectingSatValue
} selMode;
};

View File

@ -0,0 +1,78 @@
/****************************************************************************/
// This file is part of the gradLib library originally made by Stian Broen
//
// For more free libraries, please visit <http://broentech.no>
//
// gradLib 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 3 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 library. If not, see <http://www.gnu.org/licenses/>
/****************************************************************************/
#pragma once
#include "FractoriumPch.h"
/// <summary>
/// Class for drawing the small arrows below the gradient in the palette editor.
/// The drawing is accomplished via a QPolygon object.
/// </summary>
class GradientArrow
{
public:
/// <summary>
/// Default constructor which sets up the size of the arrow.
/// </summary>
explicit GradientArrow()
{
QPolygon area;
area << QPoint(5, 5) << QPoint(10, 0) << QPoint(15, 5) << QPoint(15, 15) << QPoint(5, 15) << QPoint(5, 5);
Area(area);
}
/// <summary>
/// Constructor which takes the color and focus state of the arrow.
/// </summary>
/// <param name="col">The color of the arrow</param>
/// <param name="focus">Whether the arrow is focused</param>
explicit GradientArrow(QColor col, bool focus)
: GradientArrow()
{
m_Color = col;
m_Focus = focus;
}
/// <summary>
/// Copy constructor to copy another GradientArrow.
/// </summary>
/// <param name="other">The GradientArrow object to copy</param>
GradientArrow(const GradientArrow& other)
: m_Focus(other.Focus()),
m_Area(other.Area()),
m_Color(other.Color())
{
}
/// <summary>
/// Getters and setters.
/// </summary>
inline bool Focus() const { return m_Focus; }
inline void Focus(bool val) { m_Focus = val; }
inline const QPolygon Area() const { return m_Area; }
inline void Area(const QPolygon& val) {m_Area = val; }
inline const QColor Color() const { return m_Color; }
inline void Color(const QColor& val) { m_Color = val; }
private:
bool m_Focus;
QPolygon m_Area;
QColor m_Color;
};

View File

@ -0,0 +1,630 @@
/****************************************************************************/
// This file is part of the gradLib library originally made by Stian Broen
//
// For more free libraries, please visit <http://broentech.no>
//
// gradLib 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 3 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 library. If not, see <http://www.gnu.org/licenses/>
/****************************************************************************/
#include "FractoriumPch.h"
#include "GradientColorsView.h"
/// <summary>
/// Constructor which passes parent widget to the base and sets various size constraints.
/// </summary>
/// <param name="p">The parent widget</param>
GradientColorsView::GradientColorsView(QWidget* p)
: QWidget(p)
{
m_ViewRect = QRect(QPoint(0, 0), QPoint(0, 0));
qRegisterMetaType<GradientArrow>("GradientArrow");
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setFocusPolicy(Qt::StrongFocus);
setMinimumSize(p->width() - 10, p->height() - 10);
setMouseTracking(true);
ResetToDefault();
}
/// <summary>
/// Set the focus to the arrow at the given normalized position.
/// </summary>
/// <param name="position">The normalized position of the arrow to focus</param>
void GradientColorsView::SetFocus(float position)
{
bool focused = false;
for (auto& it : m_Arrows)
{
focused |= position == it.first;
it.second.Focus(position == it.first);
}
if (!focused)
m_Arrows.begin()->second.Focus(true);
update();
}
/// <summary>
/// Set the focus to the arrow at the given index.
/// </summary>
/// <param name="position">The index of the arrow to focus</param>
void GradientColorsView::SetFocus(size_t position)
{
bool focused = false;
size_t index = 0;
position = std::min(m_Arrows.size() - 1, position);
for (auto& it : m_Arrows)
{
bool b = position == index++;
focused |= b;
it.second.Focus(b);
}
if (!focused)
m_Arrows.begin()->second.Focus(true);
update();
}
/// <summary>
/// Set the color of the currently focused arrow to the passed in color.
/// </summary>
/// <param name="color">The color to set the focused arrow to</param>
void GradientColorsView::SetFocusColor(const QColor& color)
{
for (auto& it : m_Arrows)
{
auto& anArrow = it.second;
if (anArrow.Focus())
{
anArrow.Color(color);
update();
break;
}
}
}
/// <summary>
/// Add an arrow whose color will be assigned the passed in color.
/// </summary>
/// <param name="color">The color to assign to the new arrow</param>
void GradientColorsView::AddArrow(const QColor& color)
{
float position = 0.5f;
if (m_Arrows.size() >= 256)
return;
if (m_Arrows.empty())
{
position = 0;
}
else if (m_Arrows.size() == 1)
{
position = (m_Arrows.begin()->first < 1) ? 1 : 0;
}
else if (m_Arrows.size() == 2)
{
auto b = m_Arrows.begin();
auto rb = m_Arrows.rbegin();
position = std::abs((rb->first + b->first) / 2.0);
if (position == b->first)
position = b->first / 2.0;
else if (position == rb->first)
position = (1.0 + rb->first) / 2.0;
}
else
{
bool set = false;
auto it = m_Arrows.begin();
auto oneBeforeLast = Advance(m_Arrows.begin(), m_Arrows.size() - 1);
for (; it != oneBeforeLast; ++it)
{
if (it->second.Focus())
{
auto next = Advance(it, 1);
position = std::abs((next->first + it->first) / 2.0);
set = true;
break;
}
}
if (!set)
{
it = m_Arrows.begin();
position = std::abs((Advance(it, 1)->first + it->first) / 2.0);
}
}
AddArrow(position, color);
}
/// <summary>
/// Add an arrow whose position and color will be assigned the values passed in.
/// If an arrow exists at the specified position, it is overwritten.
/// </summary>
/// <param name="position">The position to place the new arrow in</param>
/// <param name="color">The color to assign to the new arrow</param>
void GradientColorsView::AddArrow(float position, const QColor& color)
{
GradientArrow arrow;
arrow.Focus(true);
arrow.Color(color);
m_Arrows[position] = arrow;
SetFocus(position);
update();
}
/// <summary>
/// Delete the currently focused arrow if there are more than 2 arrows.
/// Set the focus to the arrow whose index is one greater than the one deleted.
/// </summary>
void GradientColorsView::DeleteFocusedArrow()
{
if (m_Arrows.size() <= 2)
return;
size_t index = 0;
for (auto it = m_Arrows.begin(); it != m_Arrows.end(); ++it)
{
if (it->second.Focus())
{
m_Arrows.erase(it);
break;
}
index++;
}
SetFocus(index);
update();
}
/// <summary>
/// Invert the values of all colors by subtracting each component from 255.
/// </summary>
void GradientColorsView::InvertColors()
{
for (auto& it : m_Arrows)
{
auto& arrow = it.second;
auto col = arrow.Color();
arrow.Color(QColor(255 - col.red(), 255 - col.green(), 255 - col.blue()));
if (arrow.Focus())
emit ArrowDoubleClicked(arrow);
}
update();
}
/// <summary>
/// Set each component of each color to a random value between 0 and 255 inclusive.
/// </summary>
void GradientColorsView::RandomColors()
{
for (auto& it : m_Arrows)
it.second.Color(
{
int(QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand(256)),
int(QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand(256)),
int(QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand(256))
});
update();
}
/// <summary>
/// Set the distance between each arrow to be equal.
/// </summary>
void GradientColorsView::DistributeColors()
{
map<float, GradientArrow> arrows;
float index = 0, inc = 1.0f / std::max<size_t>(size_t(1), m_Arrows.size() - 1);
for (auto it : m_Arrows)
{
arrows[index] = it.second;
index = std::min(1.0f, index + inc);
}
m_Arrows = std::move(arrows);
update();
}
/// <summary>
/// Delete all arrows and add a white arrow at index 0, and a black
/// arrow at index 1.
/// </summary>
void GradientColorsView::ResetToDefault()
{
ClearArrows();
AddArrow(0.0, Qt::white);
AddArrow(1.0, Qt::black);
}
/// <summary>
/// Clear all arrows.
/// </summary>
void GradientColorsView::ClearArrows()
{
m_Arrows.clear();
}
/// <summary>
/// Set the arrow at the specified index to the specified color, and also
/// focus it.
/// </summary>
/// <param name="color">The color to assign to the arrow at the specified index</param>
/// <param name="index">The index of the arrow to assign the color to and focus</param>
void GradientColorsView::NewFocusColor(const QColor& color, int index)
{
int i = 0;
for (auto& kv : m_Arrows)
{
auto& arrow = kv.second;
if (i == index)
{
arrow.Color(color);
arrow.Focus(true);
update();
}
else
arrow.Focus(false);
kv.second = arrow;
i++;
}
}
/// <summary>
/// Set the arrow map to the passed in one.
/// </summary>
/// <param name="newArrows">The new arrows to assign to the internal m_Arrows member</param>
void GradientColorsView::SetArrows(map<float, GradientArrow>& newArrows)
{
m_Arrows = newArrows;
update();
}
/// <summary>
/// Get the number of arrows in the map.
/// </summary>
/// <returns>int</returns>
int GradientColorsView::ArrowCount()
{
return int(m_Arrows.size());
}
/// <summary>
/// Get the index of the focused arrow.
/// Return 0 if none are focused.
/// </summary>
/// <returns>The focused index if at least one arrow is focused, else 0.</returns>
int GradientColorsView::GetFocusedIndex()
{
int index = 0;
for (auto& kv : m_Arrows)
{
if (kv.second.Focus())
break;
index++;
}
return index;
}
/// <summary>
/// Return a pixmap to be used to draw the palette.
/// The pixmap is lazily instantiated on the first call, and all subsequent
/// calls return a pointer to the same pixmap.
/// </summary>
/// <returns>The pixmap</returns>
QPixmap* GradientColorsView::GetBackGround()
{
if (!m_Background.get())
CreateBackground(m_BackgroundVerSpace, m_BackgroundHorSpace);
return m_Background.get();
}
/// <summary>
/// Return a reference to the arrows map.
/// Be very careful what you do with this.
/// </summary>
/// <returns>A reference to the internal map containing the arrows</returns>
map<float, GradientArrow>& GradientColorsView::GetArrows()
{
return m_Arrows;
}
/// <summary>
/// Populate the palette member with the specified number of elements based on
/// interpolating the values in the arrows and return a reference to it.
/// </summary>
/// <param name="size">The number of elements the palette will have</param>
/// <returns>A reference to the internal map containing the arrows</returns>
Palette<float>& GradientColorsView::GetPalette(int size)
{
QSize imageSize(size, 1);
QImage image(imageSize, QImage::Format_ARGB32_Premultiplied);
QPainter p;
QLinearGradient grad(QPoint(0, 0), QPoint(imageSize.width(), imageSize.height()));
m_Palette.m_SourceColors.clear();
for (auto& it : m_Arrows)
{
auto pos = it.first;
auto col = it.second.Color();
m_Palette.m_SourceColors[pos] = v4F(col.red() / 255.0f, col.green() / 255.0f, col.blue() / 255.0f, 1.0f);
grad.setColorAt(pos, col);
}
p.begin(&image);
p.fillRect(image.rect(), grad);
p.end();
m_Palette.m_Entries.reserve(image.width());
for (int i = 0; i < image.width(); i++)
{
QColor col(image.pixel(i, 0));
m_Palette[i].r = col.red() / 255.0f;
m_Palette[i].g = col.green() / 255.0f;
m_Palette[i].b = col.blue() / 255.0f;
}
return m_Palette;
}
/// <summary>
/// Assign the values of the m_SourceColors member of the palette to the
/// internal map of arrows. Note this assignment will only take place if
/// the number of source colors is 2 or more.
/// This will only be the case if it was a user created palette made here.
/// All palettes gotten from elsewhere are not assignable.
/// </summary>
/// <param name="palette">The palette whose source colors will be assigned to the arrow map</param>
void GradientColorsView::SetPalette(const Palette<float>& palette)
{
if (palette.m_SourceColors.size() > 1)
{
m_Palette = palette;
m_Arrows.clear();
for (auto& col : m_Palette.m_SourceColors)
{
auto& rgb = col.second;
m_Arrows[col.first] = GradientArrow(QColor(rgb.r * 255, rgb.g * 255, rgb.b * 255), false);
}
SetFocus(size_t(0));
update();
}
}
/// <summary>
/// Custom paint event to draw the palette and arrows.
/// </summary>
void GradientColorsView::paintEvent(QPaintEvent*)
{
if (m_ViewRect.size().isNull() ||
m_ViewRect.size().isEmpty() ||
m_ViewRect.topLeft() == m_ViewRect.bottomRight())
{
m_ViewRect = QRect(QPoint(5, 0), QPoint(width() - 15, height() / 3 * 2 - 10));
m_ViewRect.translate(5, 5);
CreateBackground();
}
QPainter painter(this);
if (m_Background.get())
painter.drawPixmap(m_ViewRect, *m_Background.get(), m_ViewRect);
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
painter.setRenderHint(QPainter::Antialiasing);
QPoint gradStart = QPoint(m_ViewRect.topLeft().x(), m_ViewRect.bottomLeft().y() / 2);
QPoint gradStop = QPoint(m_ViewRect.topRight().x(), m_ViewRect.bottomRight().y() / 2);
QLinearGradient grad(gradStart, gradStop);
for (auto& it : m_Arrows)
{
GradientArrow& arrow = it.second;
grad.setColorAt(it.first, arrow.Color());
QPolygon arrowPolygon = arrow.Area();
int iPosX = it.first * (width() - 20),
iPosY = height() / 3 * 2;
arrowPolygon.translate(iPosX, iPosY);
QPainterPath paintPath;
paintPath.addPolygon(arrowPolygon);
painter.setBrush(QBrush(arrow.Color()));
if (arrow.Focus())
paintPath.addRect(iPosX + 5, iPosY + 20, 10, 5);
painter.drawPath(paintPath);
painter.setBrush(QBrush(Qt::NoBrush));
}
QBrush brush(grad);
painter.fillRect(m_ViewRect, brush);
painter.drawRect(m_ViewRect);
painter.end();
}
/// <summary>
/// Event for detecting when the mouse is pressed on an arrow to begin dragging.
/// </summary>
/// <param name="e">The mouse event</param>
void GradientColorsView::mousePressEvent(QMouseEvent* e)
{
m_DragStart = e->pos();
for (auto& it : m_Arrows)
{
auto& arrow = it.second;
QPolygon poly = arrow.Area();
poly.translate(it.first * (width() - 20), height() / 3 * 2);
if (poly.containsPoint(m_DragStart, Qt::OddEvenFill))
{
m_ArrowMoving = true;
arrow.Focus(true);
}
else
arrow.Focus(false);
}
update();
}
/// <summary>
/// Event for detecting when the mouse is pressed on an arrow to begin dragging.
/// </summary>
/// <param name="event">The mouse event</param>
void GradientColorsView::mouseDoubleClickEvent(QMouseEvent* e)
{
for (auto& it : m_Arrows)
{
auto& arrow = it.second;
QPolygon poly = arrow.Area();
poly.translate(it.first * (width() - 20), height() / 3 * 2);
if (poly.containsPoint(e->pos(), Qt::OddEvenFill))
{
arrow.Focus(true);
emit ArrowDoubleClicked(arrow);
}
else
arrow.Focus(false);
}
}
/// <summary>
/// Event for detecting when the mouse is moving during dragging.
/// </summary>
/// <param name="event">The mouse event</param>
void GradientColorsView::mouseMoveEvent(QMouseEvent* e)
{
if (!m_ArrowMoving) return;
size_t index = 0;
qreal maxMove = 11.5 / (width() - 20);
for (auto it = m_Arrows.begin(); it != m_Arrows.end(); ++it)
{
auto& arrow = it->second;
if (arrow.Focus())
{
qreal lastPos = it->first;
qreal start = m_DragStart.x();
qreal end = width() - 20;
qreal dPos = ((qreal) e->pos().x() - start) / end;
qreal newPos = lastPos + dPos;
if ( (it->first + dPos > 1) || (it->first + dPos < 0) )
return;
if (dPos < 0 && index > 0)
{
qreal posBefore = std::prev(it)->first;
if ( (lastPos - maxMove + dPos) <= posBefore )
return;
}
if ((dPos > 0) && (index < (m_Arrows.size() - 1)))
{
qreal posAfter = std::next(it)->first;
if ((lastPos + maxMove + dPos) >= posAfter)
return;
}
GradientArrow arrowCopy(it->second);
m_Arrows.erase(lastPos);
m_Arrows[newPos] = arrowCopy;
emit ArrowMove(lastPos, arrow);
break;
}
index++;
}
m_DragStart = e->pos();
update();
}
/// <summary>
/// Event for detecting when the mouse is released during dragging.
/// </summary>
void GradientColorsView::mouseReleaseEvent(QMouseEvent*)
{
m_ArrowMoving = false;
}
/// <summary>
/// Event for custom drawing the viewable area when its resized.
/// </summary>
void GradientColorsView::resizeEvent(QResizeEvent*)
{
m_ViewRect = QRect(QPoint(5, 0), QPoint(width() - 15, height() / 3 * 2 - 10));
m_ViewRect.translate(5, 5);
}
/// <summary>
/// Create the background to represent the palette.
/// </summary>
/// <param name="vertLineSpace">The space between vertical lines to use</param>
/// <param name="horLineSpace">The space between horizontal lines to use</param>
void GradientColorsView::CreateBackground(int vertLineSpace, int horLineSpace)
{
m_BackgroundVerSpace = vertLineSpace;
m_BackgroundHorSpace = horLineSpace;
m_Background = make_unique<QPixmap>(QSize(800, 800));
m_Background->fill(Qt::white);
QPainter painter(m_Background.get());
int x = 0;
while (x < m_Background->width())//Veritcal lines.
{
const QPoint lineStart(x, 0);
const QPoint lineStop(x, m_Background->height());
painter.drawLine(lineStart, lineStop);
x += vertLineSpace;
}
int y = 0;
while (y < m_Background->height())//Horizontal lines.
{
const QPoint lineStart(0, y);
const QPoint lineStop(m_Background->width(), y);
painter.drawLine(lineStart, lineStop);
y += horLineSpace;
}
painter.end();
update();
}

View File

@ -0,0 +1,80 @@
/****************************************************************************/
// This file is part of the gradLib library originally made by Stian Broen
//
// For more free libraries, please visit <http://broentech.no>
//
// gradLib 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 3 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 library. If not, see <http://www.gnu.org/licenses/>
/****************************************************************************/
#pragma once
#include "FractoriumPch.h"
#include "GradientArrow.h"
/// <summary>
/// Class for drawing the resulting palette created by interpolating the key colors
/// as well as the arrows underneath the palette.
/// The arrows are held in a sorted map whose key is the normalized index of the arrow,
/// between 0 and 1 inclusive. They value is the arrow itself.
/// The resulting palette is always stored in the m_Palette member.
/// </summary>
class GradientColorsView : public QWidget
{
Q_OBJECT
public:
explicit GradientColorsView(QWidget* p = nullptr);
void SetFocus(float position);
void SetFocus(size_t position);
void SetFocusColor(const QColor& col);
void AddArrow(const QColor& color);
void AddArrow(float position, const QColor& color);
void DeleteFocusedArrow();
void InvertColors();
void RandomColors();
void DistributeColors();
void ResetToDefault();
void ClearArrows();
void NewFocusColor(const QColor& col, int index);
void SetArrows(map<float, GradientArrow>& newArrows);
int ArrowCount();
int GetFocusedIndex();
QPixmap* GetBackGround();
map<float, GradientArrow>& GetArrows();
Palette<float>& GetPalette(int size);
void SetPalette(const Palette<float>& palette);
signals:
void ArrowMove(qreal lastPos, const GradientArrow& arrow);
void ArrowDoubleClicked(const GradientArrow& arrow);
protected:
virtual void paintEvent(QPaintEvent* e) override;
virtual void mousePressEvent(QMouseEvent* e) override;
virtual void mouseDoubleClickEvent(QMouseEvent* e) override;
virtual void mouseMoveEvent(QMouseEvent* e) override;
virtual void mouseReleaseEvent(QMouseEvent* e) override;
virtual void resizeEvent(QResizeEvent*) override;
private:
void CreateBackground(int vertLineSpace = 5, int horLineSpace = 5);
bool m_ArrowMoving = false;
int m_BackgroundVerSpace = 5;
int m_BackgroundHorSpace = 5;
QRect m_ViewRect;
QPoint m_DragStart;
unique_ptr<QPixmap> m_Background;
map<float, GradientArrow> m_Arrows;
Palette<float> m_Palette;
};

View File

@ -0,0 +1,498 @@
#include "FractoriumPch.h"
#include "PaletteEditor.h"
#include "ui_paletteeditor.h"
/// <summary>
/// Constructor which passes parent widget to the base and sets up slots and other ui
/// elements.
/// This takes a reference to a palette list, which it then searches for user created palettes
/// and only populates the combo box with those.
/// </summary>
/// <param name="paletteList">A reference to an existing palette list, gotten from the main window.</param>
/// <param name="p">The parent widget</param>
PaletteEditor::PaletteEditor(PaletteList<float>& paletteList, QWidget* p) :
QDialog(p),
ui(make_unique<Ui::PaletteEditor>()),
m_PaletteList(paletteList)
{
ui->setupUi(this);
m_ColorPicker = new ColorPickerWidget(this);
m_ColorPicker->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
m_ColorPicker->SetColorPanelColor(Qt::black);
QVBoxLayout* colorLayout = new QVBoxLayout();
colorLayout->setMargin(3);
colorLayout->addWidget(m_ColorPicker);
ui->ColorPickerGroupBox->setLayout(colorLayout);
ui->ColorPickerGroupBox->setContentsMargins(3, 8, 3, 3);
m_GradientColorView = new GradientColorsView(ui->ColorViewGroupBox);
connect(m_ColorPicker, SIGNAL(ColorChanged(const QColor&)), this, SLOT(OnColorPickerColorChanged(const QColor&)));
connect(m_GradientColorView, SIGNAL(ArrowMove(qreal, const GradientArrow&)), this, SLOT(OnArrowMoved(qreal, const GradientArrow&)));
connect(m_GradientColorView, SIGNAL(ArrowDoubleClicked(const GradientArrow&)), this, SLOT(OnArrowDoubleClicked(const GradientArrow&)));
connect(ui->CreatePaletteFromImageButton, SIGNAL(clicked()), this, SLOT(OnCreatePaletteFromImageButtonClicked()));
connect(ui->CreatePaletteAgainFromImageButton, SIGNAL(clicked()), this, SLOT(OnCreatePaletteAgainFromImageButton()));
connect(ui->AddColorButton, SIGNAL(clicked()), this, SLOT(OnAddColorButtonClicked()));
connect(ui->RemoveColorButton, SIGNAL(clicked()), this, SLOT(OnRemoveColorButtonClicked()));
connect(ui->InvertColorsButton, SIGNAL(clicked()), this, SLOT(OnInvertColorsButtonClicked()));
connect(ui->ResetColorsButton, SIGNAL(clicked()), this, SLOT(OnResetToDefaultButtonClicked()));
connect(ui->DistributeColorsButton, SIGNAL(clicked()), this, SLOT(OnDistributeColorsButtonClicked()));
connect(ui->RandomColorsButton, SIGNAL(clicked()), this, SLOT(OnRandomColorsButtonClicked()));
connect(ui->SyncCheckBox, SIGNAL(stateChanged(int)), this, SLOT(OnSyncCheckBoxStateChanged(int)), Qt::QueuedConnection);
connect(ui->PaletteFilenameCombo, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(OnPaletteFilenameComboChanged(const QString&)), Qt::QueuedConnection);
connect(ui->PaletteListTable, SIGNAL(cellClicked(int, int)), this, SLOT(OnPaletteCellClicked(int, int)), Qt::QueuedConnection);
connect(ui->PaletteListTable, SIGNAL(cellChanged(int, int)), this, SLOT(OnPaletteCellChanged(int, int)), Qt::QueuedConnection);
connect(ui->NewPaletteFileButton, SIGNAL(clicked()), this, SLOT(OnNewPaletteFileButtonClicked()));
connect(ui->CopyPaletteFileButton, SIGNAL(clicked()), this, SLOT(OnCopyPaletteFileButtonClicked()));
connect(ui->AppendPaletteButton, SIGNAL(clicked()), this, SLOT(OnAppendPaletteButtonClicked()));
connect(ui->OverwritePaletteButton, SIGNAL(clicked()), this, SLOT(OnOverwritePaletteButtonClicked()));
connect(ui->DeletePaletteButton, SIGNAL(clicked()), this, SLOT(OnDeletePaletteButtonClicked()));
ui->PaletteListTable->horizontalHeader()->setSectionsClickable(true);
auto layout = new QVBoxLayout();
layout->setMargin(0);
layout->setSpacing(0);
layout->addWidget(m_GradientColorView);
ui->ColorViewGroupBox->setLayout(layout);
auto& pals = m_PaletteList.Palettes();
for (auto& pal : pals)
{
if (m_PaletteList.IsModifiable(pal.first))//Only add user created palettes.
{
QFileInfo info(QString::fromStdString(pal.first));
ui->PaletteFilenameCombo->addItem(info.fileName());
}
}
if (ui->PaletteFilenameCombo->count() > 0)
m_CurrentPaletteFilePath = ui->PaletteFilenameCombo->itemText(0).toStdString();
}
/// <summary>
/// Get whether change events here are propagated back to the main window.
/// </summary>
/// <returns>bool</returns>
bool PaletteEditor::Sync()
{
return ui->SyncCheckBox->isChecked();
}
/// <summary>
/// Get a pointer to the palette pixmap from the underlying gradient color view.
/// </summary>
/// <returns>QPixmap*</returns>
QPixmap* PaletteEditor::GetBackGround()
{
return m_GradientColorView->GetBackGround();
}
/// <summary>
/// Populate and retrieve a reference to the palette from the underlying gradient color view
/// using the specified number of elements.
/// </summary>
/// <param name="size">The number of elements the palette will have</param>
/// <returns>A freference to the palette</returns>
Palette<float>& PaletteEditor::GetPalette(int size)
{
return m_GradientColorView->GetPalette(size);
}
/// <summary>
/// Set the palette of the underlying gradient color view.
/// Note this assignment will only take place if
/// the number of source colors is 2 or more.
/// This will only be the case if it was a user created palette made here.
/// All palettes gotten from elsewhere are not assignable.
/// </summary>
/// <param name="palette">The palette to assign</param>
void PaletteEditor::SetPalette(Palette<float>& palette)
{
if (palette.m_SourceColors.size() > 1)
{
m_PaletteIndex = std::numeric_limits<int>::max();
m_GradientColorView->SetPalette(palette);
auto& arrows = m_GradientColorView->GetArrows();
if (!arrows.empty())
m_ColorPicker->SetColorPanelColor(arrows.begin()->second.Color());
}
}
/// <summary>
/// Add a new arrow using the current color.
/// Called when the Add Color button is clicked.
/// </summary>
void PaletteEditor::OnAddColorButtonClicked()
{
AddArrow(m_ColorPicker->Color());
EmitPaletteChanged();
}
/// <summary>
/// Delete the focused arrow and optionally redistribute the arrows.
/// Called when the Remove Color button is clicked.
/// </summary>
void PaletteEditor::OnRemoveColorButtonClicked()
{
m_GradientColorView->DeleteFocusedArrow();
if (ui->AutoDistributeCheckBox->isChecked())
m_GradientColorView->DistributeColors();
EmitPaletteChanged();
}
/// <summary>
/// Invert the colors of the arrows.
/// Called when the Invert Colors button is clicked.
/// </summary>
void PaletteEditor::OnInvertColorsButtonClicked()
{
m_GradientColorView->InvertColors();
EmitPaletteChanged();
}
/// <summary>
/// Randomize the colors of the arrows.
/// Called when the Random Colors button is clicked.
/// </summary>
void PaletteEditor::OnRandomColorsButtonClicked()
{
m_GradientColorView->RandomColors();
EmitPaletteChanged();
}
/// <summary>
/// Set the distance between each arrow to be equal.
/// Called when the Distribute Colors button is clicked.
/// </summary>
void PaletteEditor::OnDistributeColorsButtonClicked()
{
m_GradientColorView->DistributeColors();
EmitPaletteChanged();
}
/// <summary>
/// Delete all arrows and add a white arrow at index 0, and a black
/// arrow at index 1.
/// Called when the Reset button is clicked.
/// </summary>
void PaletteEditor::OnResetToDefaultButtonClicked()
{
m_GradientColorView->ResetToDefault();
EmitPaletteChanged();
}
/// <summary>
/// Create a palette by opening an image and selecting the colors from
/// pixels at random locations.
/// Ensure arrows spin box has a value of at least two.
/// Called when the From Image button is clicked.
/// </summary>
void PaletteEditor::OnCreatePaletteFromImageButtonClicked()
{
auto filenames = SetupOpenImagesDialog();
if (!filenames.empty())
{
m_Filename = filenames[0];
if (ui->ArrowsSpinBox->value() < 2)
ui->ArrowsSpinBox->setValue(2);
auto colors = GetRandomColorsFromImage(m_Filename, ui->ArrowsSpinBox->value());
m_GradientColorView->SetArrows(colors);
EmitPaletteChanged();
}
}
/// <summary>
/// Create a palette by re-opening the previously selected image and selecting the colors from
/// pixels at random locations.
/// Ensure arrows spin box has a value of at least two.
/// Called when the From Image Again button is clicked.
/// </summary>
void PaletteEditor::OnCreatePaletteAgainFromImageButton()
{
if (QFile::exists(m_Filename))
{
if (ui->ArrowsSpinBox->value() < 2)
ui->ArrowsSpinBox->setValue(2);
auto colors = GetRandomColorsFromImage(m_Filename, ui->ArrowsSpinBox->value());
m_GradientColorView->SetArrows(colors);
EmitPaletteChanged();
}
}
/// <summary>
/// Set the focus color as a result of selecting a stock in the color picker.
/// Called when the color picker signals the ColorChanged event.
/// </summary>
void PaletteEditor::OnColorPickerColorChanged(const QColor& col)
{
m_GradientColorView->SetFocusColor(col);
EmitPaletteChanged();
}
/// <summary>
/// Set the color panel color as a result of double clicking an arrow.
/// Called when the color view signals the ArrowDoubleClicked event.
/// </summary>
/// <param name="arrow">The arrow which was double clicked on</param>
void PaletteEditor::OnArrowDoubleClicked(const GradientArrow& arrow)
{
m_ColorPicker->SetColorPanelColor(arrow.Color());
}
/// <summary>
/// Change whether palette changes are synced with the main window.
/// Called when the Sync checkbox is checked/unchecked.
/// </summary>
/// <param name="state">Ignored</param>
void PaletteEditor::OnSyncCheckBoxStateChanged(int state)
{
EmitPaletteChanged();
}
/// <summary>
/// Load the palette file based on the currently selected index in the combo box.
/// Called when the index of the palette filename combo box changes.
/// </summary>
/// <param name="text">The text of the combo box, which is just the palette filename without the path.</param>
void PaletteEditor::OnPaletteFilenameComboChanged(const QString& text)
{
if (!text.isEmpty())//This occasionally seems to get called with an empty string for reasons unknown.
{
auto paletteTable = ui->PaletteListTable;
m_CurrentPaletteFilePath = text.toStdString();
::FillPaletteTable(text.toStdString(), paletteTable, m_PaletteList);
auto fullname = m_PaletteList.GetFullPathFromFilename(m_CurrentPaletteFilePath);
ui->PaletteFilenameCombo->setToolTip(QString::fromStdString(fullname));
OnPaletteCellClicked(0, 1);
}
}
/// <summary>
/// Load the palette into the editor controls.
/// Called when the second column in a row in the palette list is clicked.
/// </summary>
/// <param name="row">The table row clicked</param>
/// <param name="col">The table column clicked</param>
void PaletteEditor::OnPaletteCellClicked(int row, int col)
{
if (col == 1)
{
if (auto palette = m_PaletteList.GetPaletteByFilename(m_CurrentPaletteFilePath, row))
{
SetPalette(*palette);
m_PaletteIndex = row;
}
}
}
/// <summary>
/// Update the name of the palette.
/// Called when the first column in a row in the palette list is clicked and edited.
/// </summary>
/// <param name="row">The table row clicked</param>
/// <param name="col">The table column clicked</param>
void PaletteEditor::OnPaletteCellChanged(int row, int col)
{
if (col == 0)
{
if (auto palette = m_PaletteList.GetPaletteByFilename(m_CurrentPaletteFilePath, row))
{
palette->m_Name = ui->PaletteListTable->item(row, col)->text().toStdString();
emit PaletteFileChanged();
}
}
}
/// <summary>
/// Create a new palette file.
/// The newly created file will have a unique name.
/// Called when the new palette file button is clicked.
/// </summary>
void PaletteEditor::OnNewPaletteFileButtonClicked()
{
auto filename = EmberFile<float>::UniqueFilename(GetDefaultUserPath() + "/user-palettes.xml");
if (m_PaletteList.AddEmptyPaletteFile(filename.toStdString()))
{
QFileInfo info(filename);
ui->PaletteFilenameCombo->addItem(info.fileName());
ui->PaletteFilenameCombo->setCurrentIndex(ui->PaletteFilenameCombo->count() - 1);
}
}
/// <summary>
/// Copy the current palette file, add it to the combo box and load the new palette file.
/// The newly created file will have a unique name.
/// Called when the copy palette file button is clicked.
/// </summary>
void PaletteEditor::OnCopyPaletteFileButtonClicked()
{
auto& paletteFiles = m_PaletteList.Palettes();
auto qscurr = QString::fromStdString(m_CurrentPaletteFilePath);
auto qfilename = EmberFile<float>::UniqueFilename(GetDefaultUserPath() + "/" + qscurr);
auto filename = qfilename.toStdString();
if (m_PaletteList.GetPaletteListByFullPath(filename) == nullptr)//Ensure the new filename does not exist in the map.
{
//Get the list of palettes for the current filename, this will be added as a copy below.
if (auto currentPaletteFile = m_PaletteList.GetPaletteListByFilename(m_CurrentPaletteFilePath))//Ensure the list of palettes was properly retrieved.
{
if (m_PaletteList.AddPaletteFile(filename, *currentPaletteFile))//Add the current vector of palettes to an entry with the new filename.
{
QFileInfo info(qfilename);
ui->PaletteFilenameCombo->addItem(info.fileName());
ui->PaletteFilenameCombo->setCurrentIndex(ui->PaletteFilenameCombo->count() - 1);
}
else
QMessageBox::critical(this, "Copy palette file error", "Failed copy palette to " + qfilename + ", because already exists in memory, but not on disk. Did you delete it while the program was running?");
}
else
QMessageBox::critical(this, "Copy palette file error", "The current file " + qscurr + " did not exist. Did you delete it while the program was running?");
}
else
QMessageBox::critical(this, "Copy palette file error", "Failed copy palette to " + qfilename + ", because it likely already exists");
}
/// <summary>
/// Copy the current palette to the end of the palette file.
/// Called when the append palette button is clicked.
/// </summary>
void PaletteEditor::OnAppendPaletteButtonClicked()
{
auto& pal = m_GradientColorView->GetPalette(256);
m_PaletteList.AddPaletteToFile(m_CurrentPaletteFilePath, pal);
::FillPaletteTable(m_CurrentPaletteFilePath, ui->PaletteListTable, m_PaletteList);
m_PaletteIndex = ui->PaletteListTable->rowCount() - 1;
emit PaletteFileChanged();
}
/// <summary>
/// Overwrite the current palette in the palette file.
/// Called when the overwrite palette button is clicked.
/// </summary>
void PaletteEditor::OnOverwritePaletteButtonClicked()
{
auto& pal = m_GradientColorView->GetPalette(256);
m_PaletteList.Replace(m_CurrentPaletteFilePath, pal, m_PaletteIndex);
::FillPaletteTable(m_CurrentPaletteFilePath, ui->PaletteListTable, m_PaletteList);
emit PaletteFileChanged();
}
/// <summary>
/// Delete the current palette from the palette file.
/// Called when the delete palette button is clicked.
/// Note that the palette will not be deleted if it's the only palette in the file.
/// </summary>
void PaletteEditor::OnDeletePaletteButtonClicked()
{
auto table = ui->PaletteListTable;
if (table->rowCount() > 1)
{
m_PaletteList.Delete(m_CurrentPaletteFilePath, m_PaletteIndex);
::FillPaletteTable(m_CurrentPaletteFilePath, table, m_PaletteList);
emit PaletteFileChanged();
OnPaletteCellClicked(0, table->rowCount() - 1);
}
}
/// <summary>
/// Emit a palette changed event.
/// Called when an arrow is moved.
/// </summary>
void PaletteEditor::OnArrowMoved(qreal, const GradientArrow&)
{
EmitPaletteChanged();
}
/// <summary>
/// Emit a palette changed event if the sync checkbox is checked.
/// </summary>
void PaletteEditor::EmitPaletteChanged()
{
if (ui->SyncCheckBox->isChecked())
emit PaletteChanged();
}
/// <summary>
/// Helper to lazily instantiate an open file dialog.
/// Once created, it will remain alive for the duration of the program run.
/// </summary>
QStringList PaletteEditor::SetupOpenImagesDialog()
{
if (!m_FileDialog)
{
m_FileDialog = new QFileDialog(this);
m_FileDialog->setViewMode(QFileDialog::List);
m_FileDialog->setFileMode(QFileDialog::ExistingFile);
m_FileDialog->setAcceptMode(QFileDialog::AcceptOpen);
m_FileDialog->setNameFilter("Image Files (*.png *.jpg *.bmp)");
m_FileDialog->setWindowTitle("Open Image");
m_FileDialog->setDirectory(QCoreApplication::applicationDirPath());
m_FileDialog->selectNameFilter("*.jpg");
}
QStringList filenames;
if (m_FileDialog->exec() == QDialog::Accepted)
{
filenames = m_FileDialog->selectedFiles();
if (!filenames.empty())
m_FileDialog->setDirectory(QFileInfo(filenames[0]).canonicalPath());
}
return filenames;
}
/// <summary>
/// Add an arrow whose color will be assigned the passed in color.
/// Optionally distribute colors and emit a palette changed event.
/// </summary>
/// <param name="color">The color to assign to the new arrow</param>
void PaletteEditor::AddArrow(const QColor& color)
{
auto count = std::min<int>(std::abs(256 - m_GradientColorView->ArrowCount()), ui->ArrowsSpinBox->value());
for (int i = 0; i < count; i++)
{
m_GradientColorView->AddArrow(color);
if (ui->AutoDistributeCheckBox->isChecked())
m_GradientColorView->DistributeColors();
}
}
/// <summary>
/// Helper to get the colors of random pixels within an image.
/// </summary>
/// <param name="filename">The full path to the image file to get random colors from</param>
/// <param name="numPoints">The number of colors to get</param>
map<float, GradientArrow> PaletteEditor::GetRandomColorsFromImage(QString filename, int numPoints)
{
map<float, GradientArrow> colors;
QTime time = QTime::currentTime();
qsrand((uint)time.msec());
QImage image(filename);
const qreal gSize = 512;
float off = 0.0f, inc = 1.0f / std::max(1, numPoints - 1);
QLinearGradient grad(QPoint(0, 0), QPoint(gSize, 1));
for (int i = 0; i < numPoints; i++)
{
int x = QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand() % image.width();
int y = QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand() % image.height();
QRgb rgb = image.pixel(x, y);
GradientArrow arrow;
arrow.Color(QColor::fromRgb(rgb));
arrow.Focus(i == 0);
colors[off] = arrow;
off += inc;
}
return colors;
}

View File

@ -0,0 +1,78 @@
#pragma once
#include "FractoriumPch.h"
#include "ColorPickerWidget.h"
#include "GradientColorsView.h"
#include "EmberFile.h"
#include "ui_PaletteEditor.h"
namespace Ui
{
class PaletteEditor;
}
/// <summary>
/// Dialog for editing user created palettes.
/// This will load with all available user created palettes populated in the combo
/// box. As the user changes the selected index, the palettes for that file
/// are shown in the list box. The user can click on those and then edit them and either
/// save it back to the same position in the file, or append it to the end.
/// They can also click in the name column to set/rename the palette name.
/// Any changes on this dialog can be "synced". That is, when the Sync checkbox is checked
/// any changes result in a signal being sent back to the main window.
/// </summary>
class PaletteEditor : public QDialog
{
Q_OBJECT
public:
explicit PaletteEditor(PaletteList<float>& paletteList, QWidget* p = nullptr);
public:
bool Sync();
QPixmap* GetBackGround();
Palette<float>& GetPalette(int size);
void SetPalette(Palette<float>& palette);
signals:
void PaletteChanged();
void PaletteFileChanged();
private slots:
void OnAddColorButtonClicked();
void OnRemoveColorButtonClicked();
void OnInvertColorsButtonClicked();
void OnRandomColorsButtonClicked();
void OnDistributeColorsButtonClicked();
void OnResetToDefaultButtonClicked();
void OnCreatePaletteFromImageButtonClicked();
void OnCreatePaletteAgainFromImageButton();
void OnColorPickerColorChanged(const QColor& col);
void OnArrowDoubleClicked(const GradientArrow& arrow);
void OnSyncCheckBoxStateChanged(int state);
void OnArrowMoved(qreal lastPos, const GradientArrow& arrow);
void OnPaletteFilenameComboChanged(const QString& text);
void OnPaletteCellClicked(int row, int col);
void OnPaletteCellChanged(int row, int col);
void OnNewPaletteFileButtonClicked();
void OnCopyPaletteFileButtonClicked();
void OnAppendPaletteButtonClicked();
void OnOverwritePaletteButtonClicked();
void OnDeletePaletteButtonClicked();
private:
void EmitPaletteChanged();
QStringList SetupOpenImagesDialog();
void AddArrow(const QColor& color);
map<float, GradientArrow> GetRandomColorsFromImage(QString filename, int numPoints);
bool m_PaletteFileChanged = false;
int m_PaletteIndex = 0;
QString m_Filename;
string m_CurrentPaletteFilePath;
ColorPickerWidget* m_ColorPicker = nullptr;
GradientColorsView* m_GradientColorView = nullptr;
QFileDialog* m_FileDialog = nullptr;
PaletteList<float>& m_PaletteList;
std::unique_ptr<Ui::PaletteEditor> ui;
};

View File

@ -11,28 +11,17 @@
/// The lifetime of the palette object must be greater than or equal to
/// the lifetime of this object.
/// </summary>
class PaletteTableWidgetItemBase : public QTableWidgetItem
class PaletteTableWidgetItem : public QTableWidgetItem
{
public:
PaletteTableWidgetItemBase()
{
}
virtual size_t Index() const { return 0; }
};
template <typename T>
class PaletteTableWidgetItem : public PaletteTableWidgetItemBase
{
public:
PaletteTableWidgetItem(Palette<T>* palette)
PaletteTableWidgetItem(Palette<float>* palette)
: m_Palette(palette)
{
}
virtual size_t Index() const override { return m_Palette->m_Index; }
Palette<T>* GetPalette() const { return m_Palette; }
size_t Index() const { return m_Palette->m_Index; }
Palette<float>* GetPalette() const { return m_Palette; }
private:
Palette<T>* m_Palette;
Palette<float>* m_Palette;
};

Some files were not shown because too many files have changed in this diff Show More