--User changes

-Show image index in the library and sequence trees.
 -Add progress bar showing when preview renders are complete.
 -Automatically show animation preview when sequence generation is done.
 -Add the ability in the final render dialog to start a render within a sequence from a given point, rather than always having to start from the beginning.
 --Allow using the image index as its name rather than the file name.
This commit is contained in:
Person 2023-12-19 13:24:50 -07:00
parent c3078f018a
commit 9990d538f6
20 changed files with 191 additions and 93 deletions

View File

@ -1,7 +1,7 @@
<Project Sdk="WixToolset.Sdk/4.0.0">
<PropertyGroup>
<ProductVersion>3.7</ProductVersion>
<OutputName>Fractorium_23.23.8.101</OutputName>
<OutputName>Fractorium_23.23.8.102</OutputName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>$(SolutionDir)..\..\..\Bin\$(Platform)\$(Configuration)\</OutputPath>

View File

@ -1,5 +1,5 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
<?define ProductVersion="23.23.8.101" ?>
<?define ProductVersion="23.23.8.102" ?>
<?define ProductName="Fractorium $(var.ProductVersion) ($(var.GpuType))" ?>
<?define UpgradeCode="{4714cd15-bfba-44f6-8059-9e1466ebfa6e}"?>
<?define Manufacturer="Fractorium"?>
@ -12,7 +12,7 @@
<!--
Change this for every release.
-->
<?define ProductCode="{BAB35746-A149-483E-B3F8-A5FE73E8D407}"?>
<?define ProductCode="{78AAB6B2-EA2E-4CA2-956D-2483B3FD425C}"?>
<Package Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)" InstallerVersion="400" Scope="perMachine" ProductCode="$(var.ProductCode)">
<SummaryInformation Keywords="Installer" Description="$(var.Manufacturer)" Manufacturer="$(var.Manufacturer)" />

Binary file not shown.

View File

@ -49,8 +49,8 @@
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 23, 23, 8, 101
PRODUCTVERSION 23, 23, 8, 101
FILEVERSION 23, 23, 8, 102
PRODUCTVERSION 23, 23, 8, 102
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -67,12 +67,12 @@
BEGIN
VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Renders fractal flames as animations with motion blur"
VALUE "FileVersion", "23, 23, 8, 101"
VALUE "FileVersion", "23, 23, 8, 102"
VALUE "InternalName", "EmberAnimate.exe"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2021, GPL v3"
VALUE "OriginalFilename", "EmberAnimate.exe"
VALUE "ProductName", "Ember Animate"
VALUE "ProductVersion", "23, 23, 8, 101"
VALUE "ProductVersion", "23, 23, 8, 102"
END
END
BLOCK "VarFileInfo"

Binary file not shown.

View File

@ -49,8 +49,8 @@
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 23, 23, 8, 101
PRODUCTVERSION 23, 23, 8, 101
FILEVERSION 23, 23, 8, 102
PRODUCTVERSION 23, 23, 8, 102
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -67,12 +67,12 @@
BEGIN
VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Manipulates fractal flame parameter files"
VALUE "FileVersion", "23, 23, 8, 101"
VALUE "FileVersion", "23, 23, 8, 102"
VALUE "InternalName", "EmberGenome.exe"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2021, GPL v3"
VALUE "OriginalFilename", "EmberGenome.exe"
VALUE "ProductName", "Ember Genome"
VALUE "ProductVersion", "23, 23, 8, 101"
VALUE "ProductVersion", "23, 23, 8, 102"
END
END
BLOCK "VarFileInfo"

View File

@ -49,8 +49,8 @@
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 23, 23, 8, 101
PRODUCTVERSION 23, 23, 8, 101
FILEVERSION 23, 23, 8, 102
PRODUCTVERSION 23, 23, 8, 102
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -67,12 +67,12 @@
BEGIN
VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Renders fractal flames as single images"
VALUE "FileVersion", "23, 23, 8, 101"
VALUE "FileVersion", "23, 23, 8, 102"
VALUE "InternalName", "EmberRender.exe"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2021, GPL v3"
VALUE "OriginalFilename", "EmberRender.exe"
VALUE "ProductName", "Ember Render"
VALUE "ProductVersion", "23, 23, 8, 101"
VALUE "ProductVersion", "23, 23, 8, 102"
END
END
BLOCK "VarFileInfo"

Binary file not shown.

View File

@ -37,7 +37,7 @@ static void sincos(float x, float* s, float* c)
namespace EmberNs
{
#define EMBER_VERSION "23.23.8.101"
#define EMBER_VERSION "23.23.8.102"
//#define FLAM3_COMPAT 1//Uncomment this if you want full compatibility with flam3 regarding some of the trig-based variations in Variations01.h
#define EPS6 T(1e-6)
#define EPS std::numeric_limits<T>::epsilon()//Apoplugin.h uses -20, but it's more mathematically correct to do it this way.

View File

@ -61,7 +61,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;span style=&quot; font-size:10pt;&quot;&gt;Fractorium 23.23.8.101&lt;/span&gt;&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; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;fractorium.com&lt;/span&gt;&lt;/a&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;&lt;span style=&quot; font-size:10pt;&quot;&gt;Fractorium 23.23.8.102&lt;/span&gt;&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; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;fractorium.com&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>

View File

@ -2,6 +2,9 @@
#include "FractoriumPch.h"
#define INDEX_COL 0
#define NAME_COL 1
template <typename T> class FractoriumEmberController;
/// <summary>
@ -59,7 +62,7 @@ public:
m_Image = QImage(width, height, QImage::Format_RGBA8888);
memcpy(m_Image.scanLine(0), v.data(), SizeOf(v));//Memcpy the data in.
m_Pixmap = QPixmap::fromImage(m_Image).scaled(QSize(size, size), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);//Create a QPixmap out of the QImage, scaled to size.
setData(0, Qt::DecorationRole, m_Pixmap);
setData(NAME_COL, Qt::DecorationRole, m_Pixmap);
}
void SetRendered()
@ -92,7 +95,7 @@ public:
m_Ember(ember)
{
setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
setCheckState(0, Qt::Unchecked);
setCheckState(NAME_COL, Qt::Unchecked);
}
/// <summary>
@ -106,18 +109,18 @@ public:
m_Ember(ember)
{
setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
setCheckState(0, Qt::Unchecked);
setCheckState(NAME_COL, Qt::Unchecked);
}
/// <summary>
/// Copy the text of the tree item to the name of the ember.
/// </summary>
void UpdateEmberName() { m_Ember->m_Name = text(0).toStdString(); }
void UpdateEmberName() { m_Ember->m_Name = text(NAME_COL).toStdString(); }
/// <summary>
/// Set the text of the tree item.
/// </summary>
void UpdateEditText() { setText(0, QString::fromStdString(m_Ember->m_Name)); }
void UpdateEditText() { setText(NAME_COL, QString::fromStdString(m_Ember->m_Name)); }
/// <summary>
/// Get a pointer to the ember held by the tree item.

View File

@ -260,14 +260,18 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(QWidget* p, Qt::WindowF
w = SetTabOrder(this, w, ui.FinalRenderSaveXmlCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderDoAllCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderDoSequenceCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderUseNumbersForNames);
w = SetTabOrder(this, w, ui.FinalRenderStartAtCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderCurrentSpin);
w = SetTabOrder(this, w, ui.FinalRenderDeviceTable);
w = SetTabOrder(this, w, ui.FinalRenderApplyToAllCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderDeviceTable);
w = SetTabOrder(this, w, ui.FinalRenderThreadCountSpin);
w = SetTabOrder(this, w, ui.FinalRenderThreadPriorityComboBox);
w = SetTabOrder(this, w, ui.FinalRenderOpenCLSubBatchPctSpin);
w = SetTabOrder(this, w, m_WidthScaleSpin);
w = SetTabOrder(this, w, m_WidthSpin);
w = SetTabOrder(this, w, m_HeightScaleSpin);
w = SetTabOrder(this, w, m_HeightSpin);
w = SetTabOrder(this, w, ui.FinalRenderScaleNoneRadioButton);
w = SetTabOrder(this, w, ui.FinalRenderScaleWidthRadioButton);
w = SetTabOrder(this, w, ui.FinalRenderScaleHeightRadioButton);
@ -314,16 +318,16 @@ void FractoriumFinalRenderDialog::Show(bool fromSequence)
/// <summary>
/// GUI settings wrapper functions, getters only.
/// </summary>
bool FractoriumFinalRenderDialog::EarlyClip() { return ui.FinalRenderEarlyClipCheckBox->isChecked(); }
bool FractoriumFinalRenderDialog::YAxisUp() { return ui.FinalRenderYAxisUpCheckBox->isChecked(); }
bool FractoriumFinalRenderDialog::Transparency() { return ui.FinalRenderTransparencyCheckBox->isChecked(); }
bool FractoriumFinalRenderDialog::OpenCL() { return ui.FinalRenderOpenCLCheckBox->isChecked(); }
bool FractoriumFinalRenderDialog::Double() { return ui.FinalRenderDoublePrecisionCheckBox->isChecked(); }
bool FractoriumFinalRenderDialog::SaveXml() { return ui.FinalRenderSaveXmlCheckBox->isChecked(); }
bool FractoriumFinalRenderDialog::DoAll() { return ui.FinalRenderDoAllCheckBox->isChecked(); }
bool FractoriumFinalRenderDialog::DoSequence() { return ui.FinalRenderDoSequenceCheckBox->isChecked(); }
bool FractoriumFinalRenderDialog::DoAll() { return ui.FinalRenderDoAllCheckBox->isChecked(); }
bool FractoriumFinalRenderDialog::Png16Bit() { return ui.FinalRenderPng16BitCheckBox->isChecked(); }
bool FractoriumFinalRenderDialog::UseNumbers() { return ui.FinalRenderUseNumbersForNames->isChecked(); }
bool FractoriumFinalRenderDialog::KeepAspect() { return ui.FinalRenderKeepAspectCheckBox->isChecked(); }
bool FractoriumFinalRenderDialog::ApplyToAll() { return ui.FinalRenderApplyToAllCheckBox->isChecked(); }
QString FractoriumFinalRenderDialog::Ext() { return m_Tbcw->m_Combo->currentText(); }
@ -332,6 +336,7 @@ void FractoriumFinalRenderDialog::Path(const QString& s) { ui.FinalRenderParamsT
QString FractoriumFinalRenderDialog::Prefix() { return m_PrefixEdit->text(); }
QString FractoriumFinalRenderDialog::Suffix() { return m_SuffixEdit->text(); }
uint FractoriumFinalRenderDialog::Current() { return ui.FinalRenderCurrentSpin->value(); }
uint FractoriumFinalRenderDialog::StartAt() { return ui.FinalRenderStartAtCheckBox->isChecked() ? Current() - 1 : 0; }
uint FractoriumFinalRenderDialog::ThreadCount() { return ui.FinalRenderThreadCountSpin->value(); }
#ifdef _WIN32
int FractoriumFinalRenderDialog::ThreadPriority() { return ui.FinalRenderThreadPriorityComboBox->currentIndex() - 2; }
@ -373,6 +378,8 @@ FinalRenderGuiState FractoriumFinalRenderDialog::State()
state.m_DoSequence = DoSequence();
state.m_Png16Bit = Png16Bit();
state.m_KeepAspect = KeepAspect();
state.m_UseNumbers = UseNumbers();
state.m_StartAt = StartAt();
state.m_Scale = Scale();
state.m_Path = Path();
state.m_Ext = Ext();

View File

@ -60,8 +60,9 @@ public:
bool Double();
bool SaveXml();
bool DoAll();
bool DoSequence();
bool Png16Bit();
bool DoSequence();
bool UseNumbers();
bool KeepAspect();
bool ApplyToAll();
eScaleType Scale();
@ -72,6 +73,7 @@ public:
QString Prefix();
QString Suffix();
uint Current();
uint StartAt();
uint ThreadCount();
int ThreadPriority();
double OpenCLSubBatchPct();

View File

@ -131,28 +131,6 @@
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QSpinBox" name="FinalRenderCurrentSpin">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="prefix">
<string/>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>999999999</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="FinalRenderGridLayout" columnstretch="0,0">
<item row="0" column="0">
@ -228,7 +206,7 @@
<item row="3" column="1">
<widget class="QCheckBox" name="FinalRenderDoSequenceCheckBox">
<property name="toolTip">
<string>Use temporal samples value to achieve motion blur effect between flames</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Use temporal samples value to achieve motion blur effect between flames&lt;/p&gt;&lt;p&gt;This increases rendering time and is usually not needed when rendering at a higher frame rate such as 60fps&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Render as Animation Sequence</string>
@ -245,6 +223,52 @@
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="FinalRenderUseNumbersForNames">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Use the numerical index of the flame in the file for the output filename instead of the specified filename&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Use Numbers for Names</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="2">
<layout class="QGridLayout" name="FinalRenderGridLayout3_2">
<item row="1" column="0">
<widget class="QSpinBox" name="FinalRenderCurrentSpin">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="prefix">
<string/>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>999999999</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="FinalRenderStartAtCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Start rendering at the index specified in the spinner below, rather than starting at the first flame in the file.&lt;/p&gt;&lt;p&gt;This is helpful when resuming a failed/stopped rendering session.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Start at:</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@ -1322,7 +1346,6 @@
<tabstop>FinalRenderOpenCLCheckBox</tabstop>
<tabstop>FinalRenderDoSequenceCheckBox</tabstop>
<tabstop>FinalRenderPng16BitCheckBox</tabstop>
<tabstop>FinalRenderCurrentSpin</tabstop>
<tabstop>FinalRenderThreadCountSpin</tabstop>
<tabstop>FinalRenderThreadPriorityComboBox</tabstop>
<tabstop>FinalRenderOpenCLSubBatchPctSpin</tabstop>

View File

@ -269,6 +269,9 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
if (doAll)
{
m_ImageCount = m_EmberFile.Size();
ostringstream os;
const auto padding = streamsize(std::log10(m_EmberFile.Size())) + 1;
os << setfill('0') << setprecision(0) << fixed;
//Different action required for rendering as animation or not.
if (m_GuiState.m_DoSequence && !m_Renderers.empty())
@ -291,7 +294,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
}
else if (it.m_Time <= prev->m_Time)
{
it.m_Time = prev->m_Time + 1;
it.m_Time = prev->m_Time + 1;
}
it.m_TemporalSamples = m_GuiState.m_TemporalSamples;
@ -303,7 +306,19 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
//even when using double precision, which most cards at the time of this writing already exceed.
m_GuiState.m_Strips = 1;
CopyCont(embers, m_EmberFile.m_Embers);
std::atomic<size_t> atomfTime(0);
if (m_GuiState.m_UseNumbers)
{
auto i = 0;
for (auto& it : embers)
{
it.m_Time = i++;
FormatName(it, os, padding);
}
}
std::atomic<size_t> atomfTime(m_GuiState.m_StartAt);
vector<std::thread> threadVec;
threadVec.reserve(m_Renderers.size());
@ -320,13 +335,28 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
else if (m_Renderer.get())//Make sure a renderer was created and render all images, but not as an animation sequence (without temporal samples motion blur).
{
//Render each image, cancelling if m_Run ever gets set to false.
for (auto& it : m_EmberFile.m_Embers)
auto i = m_GuiState.m_StartAt;
while (auto ember = m_EmberFile.Get(i))
{
if (!m_Run)
break;
Output("Image " + ToString<qulonglong>(m_FinishedImageCount.load() + 1) + ":\n" + ComposePath(QString::fromStdString(it.m_Name)));
RenderSingleEmber(it, true, currentStripForProgress);
std::string oldname;
if (m_GuiState.m_UseNumbers)
{
oldname = ember->m_Name;
ember->m_Time = i;
FormatName(*ember, os, padding);
}
Output("Image " + ToString<qulonglong>(m_FinishedImageCount.load() + 1) + ":\n" + ComposePath(QString::fromStdString(ember->m_Name)));
RenderSingleEmber(*ember, true, currentStripForProgress);
i++;
if (m_GuiState.m_UseNumbers)
ember->m_Name = oldname;
}
}
else
@ -1003,6 +1033,7 @@ void FinalRenderEmberController<T>::RenderComplete(Ember<T>& ember, const EmberS
m_Settings->FinalSaveXml(m_GuiState.m_SaveXml);
m_Settings->FinalDoAll(m_GuiState.m_DoAll);
m_Settings->FinalDoSequence(m_GuiState.m_DoSequence);
m_Settings->FinalUseNumbers(m_GuiState.m_UseNumbers);
m_Settings->FinalPng16Bit(m_GuiState.m_Png16Bit);
m_Settings->FinalKeepAspect(m_GuiState.m_KeepAspect);
m_Settings->FinalScale(uint(m_GuiState.m_Scale));

View File

@ -22,7 +22,6 @@ struct FinalRenderGuiState
{
bool m_EarlyClip;
bool m_YAxisUp;
bool m_AlphaChannel;
bool m_Transparency;
bool m_OpenCL;
bool m_Double;
@ -31,12 +30,14 @@ struct FinalRenderGuiState
bool m_Png16Bit;
bool m_DoSequence;
bool m_KeepAspect;
bool m_UseNumbers;
eScaleType m_Scale;
QString m_Path;
QString m_Ext;
QString m_Prefix;
QString m_Suffix;
QList<QVariant> m_Devices;
uint m_StartAt;
uint m_ThreadCount;
int m_ThreadPriority;
double m_SubBatchPct;

View File

@ -6264,8 +6264,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>144</width>
<height>58</height>
<width>269</width>
<height>650</height>
</rect>
</property>
<property name="sizePolicy">
@ -7485,6 +7485,11 @@
<attribute name="headerMinimumSectionSize">
<number>27</number>
</attribute>
<column>
<property name="text">
<string>Index</string>
</property>
</column>
<column>
<property name="text">
<string>Current Flame File</string>
@ -8215,7 +8220,12 @@
</attribute>
<column>
<property name="text">
<string>Sequence</string>
<string>Index</string>
</property>
</column>
<column>
<property name="text">
<string>Image</string>
</property>
</column>
</widget>

View File

@ -83,7 +83,7 @@ void Fractorium::SelectLibraryItem(size_t index)
if (auto emberItem = dynamic_cast<EmberTreeWidgetItemBase*>(top->child(i)))
{
emberItem->setSelected(i == index);
emberItem->setCheckState(0, i == index ? Qt::Checked : Qt::Unchecked);
emberItem->setCheckState(NAME_COL, i == index ? Qt::Checked : Qt::Unchecked);
}
}
}
@ -111,7 +111,7 @@ vector<pair<size_t, QTreeWidgetItem*>> Fractorium::GetCurrentEmberIndex(bool isC
{
if (isChecked)
{
if (item->checkState(0) == Qt::Checked)
if (item->checkState(NAME_COL) == Qt::Checked)
v.push_back(make_pair(index, item));
}
else
@ -154,19 +154,21 @@ void FractoriumEmberController<T>::SyncLibrary(eLibraryUpdate update)
{
for (int i = 0; i < top->childCount() && it != m_EmberFile.m_Embers.end(); ++i, ++it)//Iterate through all of the children, which will represent the open embers.
{
if (auto item = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(i)))//Cast the child widget to the EmberTreeWidgetItem type.
if (auto emberItem = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(i)))//Cast the child widget to the EmberTreeWidgetItem type.
{
if (static_cast<uint>(update) & static_cast<uint>(eLibraryUpdate::INDEX))
it->m_Index = i;
if (static_cast<uint>(update) & static_cast<uint>(eLibraryUpdate::NAME))
item->setText(0, QString::fromStdString(it->m_Name));
emberItem->setText(NAME_COL, QString::fromStdString(it->m_Name));
if (static_cast<uint>(update) & static_cast<uint>(eLibraryUpdate::POINTER))
item->SetEmberPointer(&(*it));
emberItem->SetEmberPointer(&(*it));
if (item->checkState(0) == Qt::Checked)
m_EmberFilePointer = item->GetEmber();
if (emberItem->checkState(NAME_COL) == Qt::Checked)
m_EmberFilePointer = emberItem->GetEmber();
emberItem->setText(INDEX_COL, ToString(i));
}
}
}
@ -188,21 +190,23 @@ void FractoriumEmberController<T>::FillLibraryTree(int selectIndex)
tree->clear();
auto fileItem = new QTreeWidgetItem(tree);
QFileInfo info(m_EmberFile.m_Filename);
fileItem->setText(0, info.fileName());
fileItem->setToolTip(0, m_EmberFile.m_Filename);
fileItem->setText(NAME_COL, info.fileName());
fileItem->setToolTip(NAME_COL, m_EmberFile.m_Filename);
fileItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled);
uint i = 0;
for (auto& it : m_EmberFile.m_Embers)
{
auto emberItem = new EmberTreeWidgetItem<T>(&it, fileItem);
auto istr = ToString(i++);
emberItem->setText(INDEX_COL, istr);
if (it.m_Name.empty())
emberItem->setText(0, ToString(i++));
emberItem->setText(NAME_COL, istr);
else
emberItem->setText(0, it.m_Name.c_str());
emberItem->setText(NAME_COL, it.m_Name.c_str());
emberItem->setToolTip(0, emberItem->text(0));
emberItem->setToolTip(NAME_COL, emberItem->text(NAME_COL));
emberItem->SetImage(empy_preview, size, size);
}
@ -233,13 +237,15 @@ void FractoriumEmberController<T>::UpdateLibraryTree()
for (auto it = Advance(m_EmberFile.m_Embers.begin(), i); it != m_EmberFile.m_Embers.end(); ++it)
{
auto emberItem = new EmberTreeWidgetItem<T>(&(*it), top);
auto istr = ToString(i++);
emberItem->setText(INDEX_COL, istr);
if (it->m_Name.empty())
emberItem->setText(0, ToString(i++));
emberItem->setText(NAME_COL, istr);
else
emberItem->setText(0, it->m_Name.c_str());
emberItem->setText(NAME_COL, it->m_Name.c_str());
emberItem->setToolTip(0, emberItem->text(0));
emberItem->setToolTip(NAME_COL, emberItem->text(NAME_COL));
emberItem->SetImage(empy_preview, size, size);
}
@ -270,7 +276,7 @@ void FractoriumEmberController<T>::EmberTreeItemChanged(QTreeWidgetItem* item, i
if (auto emberItem = dynamic_cast<EmberTreeWidgetItem<T>*>(item))
{
auto oldName = emberItem->GetEmber()->m_Name;//First preserve the previous name.
auto newName = emberItem->text(0).toStdString();
auto newName = emberItem->text(NAME_COL).toStdString();
//Checking/unchecking other items shouldn't perform the processing below.
//If nothing changed, nothing to do.
@ -296,7 +302,7 @@ void FractoriumEmberController<T>::EmberTreeItemChanged(QTreeWidgetItem* item, i
}
else if (const auto parentItem = dynamic_cast<QTreeWidgetItem*>(item))
{
const auto text = parentItem->text(0);
const auto text = parentItem->text(NAME_COL);
if (text != "")
{
@ -485,12 +491,11 @@ template <typename T>
void FractoriumEmberController<T>::AddAnimationItem()
{
auto fileItem = new QTreeWidgetItem(m_Fractorium->ui.SequenceTree);
fileItem->setText(0, "Rendered Animation");
fileItem->setToolTip(0, "Rendered frames can be animated here");
fileItem->setText(NAME_COL, "Rendered Animation");
fileItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
auto emberItem = new EmberTreeWidgetItemBase(fileItem);
emberItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
emberItem->setToolTip(0, "Animated Frame");
emberItem->setToolTip(INDEX_COL, "Animated Frame");
const uint size = PREVIEW_SIZE;
vector<unsigned char> empy_preview(size * size * 4);
emberItem->SetImage(empy_preview, size, size);
@ -509,34 +514,43 @@ void FractoriumEmberController<T>::FillSequenceTree()
vector<unsigned char> empy_preview(size * size * 4);
const auto tree = m_Fractorium->ui.SequenceTree;
tree->clear();
// Add extra TreeWidget for animation at index 0
//Add extra TreeWidget for animation at index 0.
AddAnimationItem();
m_AnimateTimer->stop();
auto fileItem = new QTreeWidgetItem(tree);
QFileInfo info(m_SequenceFile.m_Filename);
fileItem->setText(0, info.fileName());
fileItem->setToolTip(0, m_SequenceFile.m_Filename);
fileItem->setText(NAME_COL, info.fileName());
fileItem->setToolTip(NAME_COL, m_SequenceFile.m_Filename);
fileItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable);
uint i = 0;
for (auto& it : m_SequenceFile.m_Embers)
{
auto emberItem = new EmberTreeWidgetItemBase(fileItem);
auto istr = ToString(i++);
if (it.m_Name.empty())
emberItem->setText(0, ToString(i));
emberItem->setText(NAME_COL, istr);
else
emberItem->setText(0, it.m_Name.c_str());
emberItem->setText(NAME_COL, it.m_Name.c_str());
i++;
emberItem->setText(INDEX_COL, istr);
emberItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
emberItem->setToolTip(0, emberItem->text(0));
emberItem->setToolTip(NAME_COL, emberItem->text(NAME_COL));
emberItem->SetImage(empy_preview, size, size);
}
tree->expandAll();
// Hide the animation item
//Hide, then show the animation item.
tree->collapseItem(tree->topLevelItem(0));
RenderSequencePreviews(0, uint(m_SequenceFile.Size()));
if (const auto animation = tree->topLevelItem(0))
{
animation->setExpanded(true);
m_AnimateFrame = 0;
m_AnimateTimer->start(1000 / m_Fractorium->ui.SequenceAnimationFpsSpinBox->value());
}
}
/// <summary>
@ -550,7 +564,7 @@ void FractoriumEmberController<T>::SequenceTreeItemChanged(QTreeWidgetItem* item
{
if (item == m_Fractorium->ui.SequenceTree->topLevelItem(1))
{
auto text = item->text(0);
auto text = item->text(NAME_COL);
if (text != "")
m_SequenceFile.m_Filename = text;
@ -598,7 +612,7 @@ void Fractorium::SyncFileCountToSequenceCount()
if (const auto top = ui.LibraryTree->topLevelItem(0))
{
const int count = top->childCount() - 1;
ui.LibraryTree->headerItem()->setText(0, "Current Flame File (" + QString::number(top->childCount()) + ")");
ui.LibraryTree->headerItem()->setText(NAME_COL, "Current Flame File (" + QString::number(top->childCount()) + ")");
ui.SequenceStartFlameSpinBox->setMinimum(0);
ui.SequenceStartFlameSpinBox->setMaximum(count);
ui.SequenceStartFlameSpinBox->setValue(0);
@ -835,7 +849,7 @@ void FractoriumEmberController<T>::SequenceAnimateNextFrame()
else
{
animate->m_Pixmap = QPixmap(nth->m_Pixmap);
animate->setData(0, Qt::DecorationRole, animate->m_Pixmap);
animate->setData(NAME_COL, Qt::DecorationRole, animate->m_Pixmap);
}
}
}
@ -859,7 +873,6 @@ void FractoriumEmberController<T>::SequenceAnimateButtonClicked()
{
animation->setExpanded(true);
m_AnimateFrame = 0;
// TODO look at duration based instead of time
m_AnimateTimer->start(1000 / m_Fractorium->ui.SequenceAnimationFpsSpinBox->value());
}
}

View File

@ -87,9 +87,10 @@ void FractoriumSettings::EnsureDefaults()
if (SaveImageExt() == "")
#ifndef __APPLE__
SaveImageExt(".png");
SaveImageExt(".png");
#else
SaveImageExt("Png (*.png)");
SaveImageExt("Png (*.png)");
#endif
if (FinalExt() != "jpg" && FinalExt() != "png" && FinalExt() != "exr"
@ -308,6 +309,9 @@ void FractoriumSettings::FinalDoAll(bool b) { setValue(FINALDOALL, b);
bool FractoriumSettings::FinalDoSequence() { return value(FINALDOSEQUENCE).toBool(); }
void FractoriumSettings::FinalDoSequence(bool b) { setValue(FINALDOSEQUENCE, b); }
bool FractoriumSettings::FinalUseNumbers() { return value(FINALUSENUMBERS).toBool(); }
void FractoriumSettings::FinalUseNumbers(bool b) { setValue(FINALUSENUMBERS, b); }
bool FractoriumSettings::FinalPng16Bit() { return value(FINALPNG16BIT).toBool(); }
void FractoriumSettings::FinalPng16Bit(bool b) { setValue(FINALPNG16BIT, b); }

View File

@ -74,6 +74,7 @@
#define FINALTEMPORALSAMPLES "finalrender/temporalsamples"
#define FINALSUPERSAMPLE "finalrender/supersample"
#define FINALSTRIPS "finalrender/strips"
#define FINALUSENUMBERS "finalrender/usenumbers"
#define XMLWIDTH "xml/width"
#define XMLHEIGHT "xml/height"
@ -270,6 +271,9 @@ public:
bool FinalDoSequence();
void FinalDoSequence(bool b);
bool FinalUseNumbers();
void FinalUseNumbers(bool b);
bool FinalPng16Bit();
void FinalPng16Bit(bool b);