Numerous fixes

0.4.0.5 Beta 07/18/2014
--User Changes
Allow for vibrancy values > 1.
Add flatten and unflatten menu items.
Automatically flatten like Apophysis does.
Add plugin and new_linear tags to Xml to be compatible with Apophysis.

--Bug Fixes
Fix blur, blur3d, bubble, cropn, cross, curl, curl3d, epispiral, ho,
julia3d, julia3dz, loonie, mirror_x, mirror_y, mirror_z, rotate_x,
sinusoidal, spherical, spherical3d, stripes.
Unique filename on final render was completely broken.
Two severe OpenCL bugs. Random seeds were biased and fusing was being
reset too often leading to results that differ from the CPU.
Subtle, but sometimes severe bug in the setup of the xaos weights.
Use properly defined epsilon by getting the value from
std::numeric_limits, rather than hard coding 1e-6 or 1e-10.
Omit incorrect usage of epsilon everywhere. It should not be
automatically added to denominators. Rather, it should only be used if
the denominator is zero.
Force final render progress bars to 100 on completion. Sometimes they
didn't seem to make it there.
Make variation name and params comparisons be case insensitive.

--Code Changes
Make ForEach and FindIf wrappers around std::for_each and std::find_if.
This commit is contained in:
mfeemster
2014-07-18 23:33:18 -07:00
parent 1884934b9d
commit e3b207c562
53 changed files with 1611 additions and 778 deletions

View File

@ -52,7 +52,7 @@
</font>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;br/&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Fractorium 0.4.0.4 Beta&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;&lt;br/&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;span style=&quot; font-size:10pt;&quot;&gt;Matt Feemster&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;&lt;br/&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Fractorium 0.4.0.5 Beta&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;&lt;br/&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;span style=&quot; font-size:10pt;&quot;&gt;Matt Feemster&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>

View File

@ -117,12 +117,13 @@ public:
int counter = 2;
QString newPath;
QFileInfo original(filename);
QString path = original.absolutePath() + QDir::separator();
QString base = original.completeBaseName();
QString extension = original.suffix();
do
{
newPath = base + "_" + QString::number(counter++) + "." + extension;
newPath = path + base + "_" + QString::number(counter++) + "." + extension;
}
while (QFile::exists(newPath));

View File

@ -345,6 +345,9 @@ int FinalRenderEmberController<T>::ProgressFunc(Ember<T>& ember, void* foo, doub
}
m_FinishedImageCount++;
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderIterationProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int(100)));//Just to be safe.
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderFilteringProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int(100)));
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderAccumProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int(100)));
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderTotalProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int(((float)m_FinishedImageCount / (float)m_ImageCount) * 100)));
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderImageCountLabel, "setText", Qt::QueuedConnection, Q_ARG(QString, QString::number(m_FinishedImageCount) + " / " + QString::number(m_ImageCount)));

View File

@ -325,7 +325,7 @@ void Fractorium::dropEvent(QDropEvent* e)
void Fractorium::SetupCombo(QTableWidget* table, const QObject* receiver, int& row, int col, StealthComboBox*& comboBox, vector<string>& vals, const char* signal, const char* slot, Qt::ConnectionType connectionType)
{
comboBox = new StealthComboBox(table);
std::for_each(vals.begin(), vals.end(), [&](string s) { comboBox->addItem(s.c_str()); });
ForEach(vals, [&](string s) { comboBox->addItem(s.c_str()); });
table->setCellWidget(row, col, comboBox);
connect(comboBox, signal, receiver, slot, connectionType);
row++;

View File

@ -109,6 +109,8 @@ public slots:
void OnActionAddReflectiveSymmetry(bool checked);//Tools.
void OnActionAddRotationalSymmetry(bool checked);
void OnActionAddBothSymmetry(bool checked);
void OnActionFlatten(bool checked);
void OnActionUnflatten(bool checked);
void OnActionClearFlame(bool checked);
void OnActionRenderPreviews(bool checked);
void OnActionStopRenderingPreviews(bool checked);

View File

@ -1,44 +1,46 @@
<RCC>
<qresource prefix="/Fractorium">
<file>Icons/arrow-undo.png</file>
<file>Icons/arrow-redo.png</file>
<file>Icons/stop.png</file>
<file>Icons/application_side_boxes.png</file>
<file>Icons/page_copy.png</file>
<file>Icons/page_paste.png</file>
<file>Icons/window-close.png</file>
<file>Icons/068123-3d-transparent-glass-icon-alphanumeric-question-mark3.png</file>
<file>Icons/layer--plus.png</file>
<file>Icons/layers.png</file>
<file>Icons/layers-stack.png</file>
<file>Icons/monitor.png</file>
<file>Icons/016938-3d-transparent-glass-icon-symbols-shapes-shape-square-clear-16.png</file>
<file>Icons/document-hf-insert.png</file>
<file>Icons/010425-3d-transparent-glass-icon-animals-spiderweb2.png</file>
<file>Icons/database-medium.png</file>
<file>Icons/databases.png</file>
<file>Icons/drive-harddisk-5.png</file>
<file>Icons/folder-visiting-4.png</file>
<file>Icons/display-brightness-off.png</file>
<file>Icons/cog.png</file>
<file>Icons/proxy.png</file>
<file>Icons/shape_flip_horizontal.png</file>
<file>Icons/shape_flip_vertical.png</file>
<file>Icons/arrow_down.png</file>
<file>Icons/arrow_in.png</file>
<file>Icons/arrow_left.png</file>
<file>Icons/arrow_out.png</file>
<file>Icons/arrow_right.png</file>
<file>Icons/arrow_rotate_anticlockwise.png</file>
<file>Icons/arrow_rotate_clockwise.png</file>
<file>Icons/arrow_turn_left.png</file>
<file>Icons/arrow_turn_right.png</file>
<file>Icons/arrow_up.png</file>
<file>Icons/configure.png</file>
<file>Icons/infomation.png</file>
<file>Icons/del.png</file>
<file>Icons/add.png</file>
<file>Icons/eraser.png</file>
<file>Icons/editraise.png</file>
</qresource>
<qresource prefix="/Fractorium">
<file>Icons/arrow-undo.png</file>
<file>Icons/arrow-redo.png</file>
<file>Icons/stop.png</file>
<file>Icons/application_side_boxes.png</file>
<file>Icons/page_copy.png</file>
<file>Icons/page_paste.png</file>
<file>Icons/window-close.png</file>
<file>Icons/068123-3d-transparent-glass-icon-alphanumeric-question-mark3.png</file>
<file>Icons/layer--plus.png</file>
<file>Icons/layers.png</file>
<file>Icons/layers-stack.png</file>
<file>Icons/monitor.png</file>
<file>Icons/016938-3d-transparent-glass-icon-symbols-shapes-shape-square-clear-16.png</file>
<file>Icons/document-hf-insert.png</file>
<file>Icons/010425-3d-transparent-glass-icon-animals-spiderweb2.png</file>
<file>Icons/database-medium.png</file>
<file>Icons/databases.png</file>
<file>Icons/drive-harddisk-5.png</file>
<file>Icons/folder-visiting-4.png</file>
<file>Icons/display-brightness-off.png</file>
<file>Icons/cog.png</file>
<file>Icons/proxy.png</file>
<file>Icons/shape_flip_horizontal.png</file>
<file>Icons/shape_flip_vertical.png</file>
<file>Icons/arrow_down.png</file>
<file>Icons/arrow_in.png</file>
<file>Icons/arrow_left.png</file>
<file>Icons/arrow_out.png</file>
<file>Icons/arrow_right.png</file>
<file>Icons/arrow_rotate_anticlockwise.png</file>
<file>Icons/arrow_rotate_clockwise.png</file>
<file>Icons/arrow_turn_left.png</file>
<file>Icons/arrow_turn_right.png</file>
<file>Icons/arrow_up.png</file>
<file>Icons/configure.png</file>
<file>Icons/infomation.png</file>
<file>Icons/del.png</file>
<file>Icons/add.png</file>
<file>Icons/eraser.png</file>
<file>Icons/editraise.png</file>
<file>Icons/square.png</file>
<file>Icons/cube.png</file>
</qresource>
</RCC>

Binary file not shown.

View File

@ -174,6 +174,9 @@
<addaction name="ActionAddRotationalSymmetry"/>
<addaction name="ActionAddBothSymmetry"/>
<addaction name="separator"/>
<addaction name="ActionFlatten"/>
<addaction name="ActionUnflatten"/>
<addaction name="separator"/>
<addaction name="ActionClearFlame"/>
<addaction name="separator"/>
<addaction name="ActionRenderPreviews"/>
@ -5282,6 +5285,30 @@ SpinBox
<string>Ctrl+V</string>
</property>
</action>
<action name="ActionFlatten">
<property name="icon">
<iconset resource="Fractorium.qrc">
<normaloff>:/Fractorium/Icons/square.png</normaloff>:/Fractorium/Icons/square.png</iconset>
</property>
<property name="text">
<string>&amp;Flatten</string>
</property>
<property name="toolTip">
<string>Add the Flatten variation to each xform</string>
</property>
</action>
<action name="ActionUnflatten">
<property name="icon">
<iconset resource="Fractorium.qrc">
<normaloff>:/Fractorium/Icons/cube.png</normaloff>:/Fractorium/Icons/cube.png</iconset>
</property>
<property name="text">
<string>&amp;Unflatten</string>
</property>
<property name="toolTip">
<string>Remove the Flatten variation from each xform</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View File

@ -91,6 +91,8 @@ public:
virtual void AddReflectiveSymmetry() { }//Tools.
virtual void AddRotationalSymmetry() { }
virtual void AddBothSymmetry() { }
virtual void Flatten() { }
virtual void Unflatten() { }
virtual void ClearFlame() { }
//Toolbar.
@ -298,6 +300,8 @@ public:
virtual void AddReflectiveSymmetry();
virtual void AddRotationalSymmetry();
virtual void AddBothSymmetry();
virtual void Flatten();
virtual void Unflatten();
virtual void ClearFlame();
//Toolbar.

View File

@ -31,6 +31,8 @@ void Fractorium::InitMenusUI()
connect(ui.ActionAddRotationalSymmetry, SIGNAL(triggered(bool)), this, SLOT(OnActionAddRotationalSymmetry(bool)), Qt::QueuedConnection);
connect(ui.ActionAddBothSymmetry, SIGNAL(triggered(bool)), this, SLOT(OnActionAddBothSymmetry(bool)), Qt::QueuedConnection);
connect(ui.ActionClearFlame, SIGNAL(triggered(bool)), this, SLOT(OnActionClearFlame(bool)), Qt::QueuedConnection);
connect(ui.ActionFlatten, SIGNAL(triggered(bool)), this, SLOT(OnActionFlatten(bool)), Qt::QueuedConnection);
connect(ui.ActionUnflatten, SIGNAL(triggered(bool)), this, SLOT(OnActionUnflatten(bool)), Qt::QueuedConnection);
connect(ui.ActionStopRenderingPreviews, SIGNAL(triggered(bool)), this, SLOT(OnActionStopRenderingPreviews(bool)), Qt::QueuedConnection);
connect(ui.ActionRenderPreviews, SIGNAL(triggered(bool)), this, SLOT(OnActionRenderPreviews(bool)), Qt::QueuedConnection);
connect(ui.ActionFinalRender, SIGNAL(triggered(bool)), this, SLOT(OnActionFinalRender(bool)), Qt::QueuedConnection);
@ -659,6 +661,22 @@ void FractoriumEmberController<T>::AddBothSymmetry()
void Fractorium::OnActionAddBothSymmetry(bool checked) { m_Controller->AddBothSymmetry(); }
/// <summary>
/// Adds a FlattenVariation to every xform in the current ember.
/// Resets the rendering process.
/// </summary>
template <typename T>
void FractoriumEmberController<T>::Flatten() { UpdateCurrentXform([&] (Xform<T>* xform) { m_Ember.Flatten(XmlToEmber<T>::m_FlattenNames); FillVariationTreeWithXform(xform); }); }
void Fractorium::OnActionFlatten(bool checked) { m_Controller->Flatten(); }
/// <summary>
/// Removes pre/reg/post FlattenVariation from every xform in the current ember.
/// Resets the rendering process.
/// </summary>
template <typename T>
void FractoriumEmberController<T>::Unflatten() { UpdateCurrentXform([&] (Xform<T>* xform) { m_Ember.Unflatten(); FillVariationTreeWithXform(xform); }); }
void Fractorium::OnActionUnflatten(bool checked) { m_Controller->Unflatten(); }
/// <summary>
/// Delete all but one xform in the current ember.
/// Clear that xform's variations.

View File

@ -22,12 +22,13 @@ void Fractorium::InitParamsUI()
SetFixedTableHeader(ui.IterationTableHeader->horizontalHeader());
//Color.
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_BrightnessSpin, spinHeight, 0.05, 100, 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.1, SIGNAL(valueChanged(double)), SLOT(OnGammaThresholdChanged(double)), true, 0.1, 0.1, 0.1);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_VibrancySpin, spinHeight, 0, 1, 0.01, SIGNAL(valueChanged(double)), SLOT(OnVibrancyChanged(double)), true, 1.0, 1.0, 1.0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_HighlightSpin, spinHeight, -1.0, 2.0, 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, 100, 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, 2.0, 0.1, SIGNAL(valueChanged(double)), SLOT(OnHighlightPowerChanged(double)), true, -1.0, -1.0, -1.0);
m_GammaThresholdSpin->setDecimals(4);
m_BackgroundColorButton = new QPushButton("...", table);
m_BackgroundColorButton->setMinimumWidth(21);
m_BackgroundColorButton->setMaximumWidth(21);
@ -47,7 +48,7 @@ void Fractorium::InitParamsUI()
SetupSpinner<SpinBox, int> (table, this, row, 1, m_HeightSpin, spinHeight, 10, 100000, 50, SIGNAL(valueChanged(int)), SLOT(OnHeightChanged(int)));
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_CenterXSpin, spinHeight, -10, 10, 0.05, SIGNAL(valueChanged(double)), SLOT(OnCenterXChanged(double)), true, 0, 0, 0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_CenterYSpin, spinHeight, -10, 10, 0.05, SIGNAL(valueChanged(double)), SLOT(OnCenterYChanged(double)), true, 0, 0, 0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_ScaleSpin, spinHeight, 10, 3000, 20, SIGNAL(valueChanged(double)), SLOT(OnScaleChanged(double)), true, 240, 240, 240);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_ScaleSpin, spinHeight, 10, 5000, 20, SIGNAL(valueChanged(double)), SLOT(OnScaleChanged(double)), true, 240, 240, 240);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_ZoomSpin, spinHeight, 0, 5, 0.2, SIGNAL(valueChanged(double)), SLOT(OnZoomChanged(double)), true, 0, 0, 0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_RotateSpin, spinHeight, -180, 180, 10, SIGNAL(valueChanged(double)), SLOT(OnRotateChanged(double)), true, 0, 0, 0);
SetupSpinner<DoubleSpinBox, double>(table, this, row, 1, m_ZPosSpin, spinHeight, -1000, 1000, 1, SIGNAL(valueChanged(double)), SLOT(OnZPosChanged(double)), true, 0, 1, 0);

View File

@ -55,6 +55,7 @@ void FractoriumEmberController<T>::SetupVariationTree()
spinBox->DoubleClickZero(1);
spinBox->DoubleClickNonZero(0);
spinBox->SmallStep(0.001);
spinBox->setDecimals(4);
tree->setItemWidget(item, 1, spinBox);
m_Fractorium->connect(spinBox, SIGNAL(valueChanged(double)), SLOT(OnVariationSpinBoxValueChanged(double)), Qt::QueuedConnection);
@ -85,6 +86,10 @@ void FractoriumEmberController<T>::SetupVariationTree()
varSpinBox->Step(1);
varSpinBox->SmallStep(1);
}
else
{
varSpinBox->setDecimals(4);
}
tree->setItemWidget(paramWidget, 1, varSpinBox);
m_Fractorium->connect(varSpinBox, SIGNAL(valueChanged(double)), SLOT(OnVariationSpinBoxValueChanged(double)), Qt::QueuedConnection);
@ -138,7 +143,7 @@ void FractoriumEmberController<T>::VariationSpinBoxValueChanged(double d)
{
Variation<T>* var = sender->GetVariation();//The variation attached to the sender, for reference only.
ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var);//The parametric cast of that variation.
Variation<T>* xformVar = xform->GetVariationByName(var->Name());//The corresponding variation in the currently selected xform.
Variation<T>* xformVar = xform->GetVariationById(var->VariationId());//The corresponding variation in the currently selected xform.
QList<QTreeWidgetItem*> items = tree->findItems(QString::fromStdString(var->Name()), Qt::MatchExactly);
bool isParam = parVar && sender->IsParam();
@ -222,6 +227,8 @@ void FractoriumEmberController<T>::FillVariationTreeWithXform(Xform<T>* xform)
{
QTreeWidget* tree = m_Fractorium->ui.VariationsTree;
tree->blockSignals(true);
for (unsigned int i = 0; i < tree->topLevelItemCount(); i++)
{
QTreeWidgetItem* item = tree->topLevelItem(i);
@ -263,6 +270,7 @@ void FractoriumEmberController<T>::FillVariationTreeWithXform(Xform<T>* xform)
}
}
tree->blockSignals(false);
m_Fractorium->OnTreeHeaderSectionClicked(m_Fractorium->m_VarSortMode);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

View File

@ -16,6 +16,12 @@ int main(int argc, char *argv[])
QMessageBox::critical(QApplication::desktop(), "Error", "Fractorium cannot be run in test mode, undefine TEST_CL first.");
return 1;
#endif
#ifdef ISAAC_FLAM3_DEBUG
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.
_putenv_s("GPU_MAX_ALLOC_PERCENT", "100");