--User changes

-Remove the Type field from the variations tree and instead just put the type indicator icon next to the variation name.
 -Double clicking to toggle variation parameter spinners now resets the value to the default if there is one, else it uses zero. If it is already using the default, it is toggled to 0.
 -Add a new button to toggle xaos on and off.
 -When duplicating a flame, insert it immediately after the one being duplicated instead of at the end of the file.
 -When switching between flames in a file, keep the same xform index selected rather than resetting it to the first xform each time.
 -Create a threaded writer for the final render and EmberAnimate so the rendering process does not get delayed by file saving which may take a long time.
 -Remove warning which said "Frames per rot cannot be greater than one while Rotations is zero" when generating a sequence.
 -Add the Circle_Rand variation from Chaotica.
 -Add tool tips to clarify the following items:
 --Auto Unique Filenames checkbox in the options dialog.
 --Xaos table headers.

--Bug fixes
 -Generating sequences using the following variations would be done incorrectly: circletrans1, collideoscope, crob, curlsp, glynnsim1, glynnsim2, hypercrop, julian, julian, mobiusn, nblur, waves2, wavesn.
 -Adding/removing nodes from the color curve had accidentally been disabled.
 -The applied xaos weight table was not showing normalized weight values.
 -Changing the size of a flame was not observing the Apply To All checkbox.
 -Do not clamp the Rotate field to +/-180, because this causes the rotation to switch from CW to CCW during sequence generation. Instead, leave it exactly as the user entered it so the rotations proceed in the same direction.
This commit is contained in:
Person
2023-11-21 22:58:22 -07:00
parent 1a1cb8b0f2
commit 745f06d29d
47 changed files with 616 additions and 326 deletions

View File

@ -11,6 +11,9 @@ void Fractorium::InitXaosUI()
int spinHeight = 20;
ui.XaosTableView->verticalHeader()->setSectionsClickable(true);
ui.XaosTableView->horizontalHeader()->setSectionsClickable(true);
auto ttstr = "<html><head/><body><p>Double click to toggle all table spinner values in one row/col.</p><p>If any cell in the row is non zero, set all cells to zero, else 1.</p><p>If shift is held down, reverse the logic.</p><p>If ctrl is held down, set each cell to a random 0 or 1.</p></body></html>";
ui.XaosTableView->horizontalHeader()->setToolTip(ttstr);
ui.XaosTableView->verticalHeader()->setToolTip(ttstr);
m_XaosSpinBox = new DoubleSpinBox(nullptr, spinHeight, 0.1, false);
m_XaosSpinBox->DoubleClick(true);
m_XaosSpinBox->DoubleClickZero(1);
@ -24,6 +27,7 @@ void Fractorium::InitXaosUI()
connect(ui.ClearXaosButton, SIGNAL(clicked(bool)), this, SLOT(OnClearXaosButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.RandomXaosButton, SIGNAL(clicked(bool)), this, SLOT(OnRandomXaosButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.TransposeXaosButton, SIGNAL(clicked(bool)), this, SLOT(OnTransposeXaosButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.ToggleXaosButton, SIGNAL(clicked(bool)), this, SLOT(OnToggleXaosButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.AddLayerButton, SIGNAL(clicked(bool)), this, SLOT(OnAddLayerButtonClicked(bool)), Qt::QueuedConnection);
connect(ui.XaosTableView->verticalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(OnXaosRowDoubleClicked(int)), Qt::QueuedConnection);
connect(ui.XaosTableView->horizontalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(OnXaosColDoubleClicked(int)), Qt::QueuedConnection);
@ -59,22 +63,22 @@ void FractoriumEmberController<T>::FillXaos()
template <typename T>
void FractoriumEmberController<T>::FillAppliedXaos()
{
m_Ember.CalcNormalizedWeights(m_NormalizedWeights);
std::vector<T> weights;
auto ct = int(XformCount());
for (int i = 0, count = int(XformCount()); i < count; i++)//Column.
for (int i = 0, count = ct; i < count; i++)
weights.push_back(m_Ember.GetXform(i)->m_Weight);
for (int i = 0, count = ct; i < count; i++)//Column.
{
if (const auto xform = m_Ember.GetXform(i))
{
T norm = 0;
double start = 0, offset = 0;
auto tempweights = m_NormalizedWeights;
auto tempweights = weights;
for (int j = 0; j < count; j++)//Row.
{
tempweights[j] *= xform->Xaos(j);
QModelIndex index = m_Fractorium->m_AppliedXaosTableModel->index(j, i, QModelIndex());//j and i are intentionally swapped here.
m_Fractorium->m_AppliedXaosTableModel->setData(index, TruncPrecision(xform->Xaos(j) * xform->m_Weight, 4));//Applied xaos is just a read only table for display purposes.
}
QPixmap pixmap(m_Fractorium->ui.XaosAppliedTableView->columnWidth(i) - 8, m_Fractorium->ui.XaosTableView->rowHeight(0) * count);
QPainter painter(&pixmap);
@ -84,6 +88,13 @@ void FractoriumEmberController<T>::FillAppliedXaos()
for (auto& w : tempweights) w = norm == static_cast<T>(0) ? static_cast<T>(0) : w / norm;
for (int j = 0; j < count; j++)//Row.
{
auto normXaosAppliedWeight = tempweights[j];
QModelIndex index = m_Fractorium->m_AppliedXaosTableModel->index(j, i, QModelIndex());//j and i are intentionally swapped here.
m_Fractorium->m_AppliedXaosTableModel->setData(index, TruncPrecision(normXaosAppliedWeight, 4));//Applied xaos is just a read only table for display purposes.
}
if (norm)
{
for (size_t i = 0; i < tempweights.size() && offset <= pixmap.height(); i++)
@ -309,6 +320,48 @@ void FractoriumEmberController<T>::TransposeXaos()
void Fractorium::OnTransposeXaosButtonClicked(bool checked) { m_Controller->TransposeXaos(); }
/// <summary>
/// Toggle whether to use xaos or not by saving/restoring a backup flame.
/// Resets the rendering process.
/// </summary>
template <typename T>
void FractoriumEmberController<T>::ToggleXaos()
{
Update([&]
{
if (m_Ember.XaosPresent())
{
m_XaosToggleEmber = m_Ember;
m_Ember.ClearXaos();
}
else if (m_XaosToggleEmber.XaosPresent())
{
size_t i = 0;
while (auto xform = m_Ember.GetXform(i))
{
auto backupXform = m_XaosToggleEmber.GetXform(i);
if (backupXform)
{
for (size_t j = 0; j < m_Ember.XformCount(); j++)
xform->SetXaos(j, TruncPrecision(backupXform->Xaos(j), XAOS_PREC));
}
else
break;
i++;
}
m_XaosToggleEmber.Clear();
}
});
FillXaos();
FillAppliedXaos();
}
void Fractorium::OnToggleXaosButtonClicked(bool checked) { m_Controller->ToggleXaos(); }
/// <summary>
/// Toggle all xaos values in one row on left mouse button double click and resize all cells to fit their data.
/// Skip toggling and only refit on right mouse button double click.