From c0a1395a2b5c909411d5360d6182d887209973d5 Mon Sep 17 00:00:00 2001 From: Person Date: Tue, 14 Jul 2020 17:45:07 -0700 Subject: [PATCH 1/4] --Bug fixes -Add support for Chaotica files which specify xform weight as "Base weight" instead of "base_weight". -Fix bug where Fractorium would crash when a new file was dragged in while previews were still rendering. --This was done by changing the TreeItemChanged() events in the library tab use a direct connection rather than a queued connection. --This obviated the need for QCoreApplication::processEvents() calls in the library tree code. -Fix bug where renaming a flame within a file, then tabbing away did not commit the name change. --Code changes -Clean up some warnings about const variables in the latest version of Visual Studio 2019. -Upgrade installer to latest update of Visual Studio 2019. --- Builds/MSVC/Installer/Product.wxs | 10 +- Source/Ember/Variations07.h | 4 +- Source/Ember/XmlToEmber.cpp | 10 +- Source/Fractorium/Fractorium.cpp | 20 ++-- Source/Fractorium/FractoriumLibrary.cpp | 132 ++++++++++++------------ 5 files changed, 91 insertions(+), 85 deletions(-) diff --git a/Builds/MSVC/Installer/Product.wxs b/Builds/MSVC/Installer/Product.wxs index 804d710..9aceebb 100644 --- a/Builds/MSVC/Installer/Product.wxs +++ b/Builds/MSVC/Installer/Product.wxs @@ -168,19 +168,19 @@ - + - + - + - + - + diff --git a/Source/Ember/Variations07.h b/Source/Ember/Variations07.h index ad7810d..708be70 100644 --- a/Source/Ember/Variations07.h +++ b/Source/Ember/Variations07.h @@ -2395,8 +2395,8 @@ public: { m_Ang = M_2PI / Zeps(m_Divisor); T a = std::atan2((m_D < 0 ? -std::log(-m_D) : std::log(m_D)) * m_R, M_2PI); - m_PrecalcC = std::cos(a) * m_R * std::cos(a) / m_Divisor; - m_PrecalcD = std::cos(a) * m_R * std::sin(a) / m_Divisor; + m_PrecalcC = std::cos(a) * m_R * std::cos(a) / Zeps(m_Divisor); + m_PrecalcD = std::cos(a) * m_R * std::sin(a) / Zeps(m_Divisor); m_HalfC = m_PrecalcC / 2; m_HalfD = m_PrecalcD / 2; m_Coeff = m_PrecalcD == 0 ? 0 : T(-0.095) * m_Spread / m_PrecalcD; diff --git a/Source/Ember/XmlToEmber.cpp b/Source/Ember/XmlToEmber.cpp index eba3c40..fc68e12 100644 --- a/Source/Ember/XmlToEmber.cpp +++ b/Source/Ember/XmlToEmber.cpp @@ -1198,7 +1198,15 @@ bool XmlToEmber::ParseEmberElementFromChaos(xmlNode* emberNode, Ember& cur std::string periterweights; if (auto baseWeightChildNode = GetChildNode(weightsChildNode, "base_weight")) - if (ParseAndAssignContent(baseWeightChildNode, "name", "base_weight", weight)) { xf.m_Weight = weight; } + { + if (ParseAndAssignContent(baseWeightChildNode, "name", "base_weight", weight)) + xf.m_Weight = weight; + } + else if (auto baseWeightChildNode = GetChildNode(weightsChildNode, "Base weight")) + { + if (ParseAndAssignContent(baseWeightChildNode, "name", "Base weight", weight)) + xf.m_Weight = weight; + } if (auto periterweightsChildNode = GetChildNode(weightsChildNode, "per_iterator_weights")) { diff --git a/Source/Fractorium/Fractorium.cpp b/Source/Fractorium/Fractorium.cpp index a669e0e..9d7dddc 100644 --- a/Source/Fractorium/Fractorium.cpp +++ b/Source/Fractorium/Fractorium.cpp @@ -382,8 +382,8 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e) { auto combo = ui.CurrentXformCombo; bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier); - int times = 3; - int ftimes = 2; + const int times = 3; + const int ftimes = 2; if (ke->key() >= Qt::Key_F1 && ke->key() <= Qt::Key_F32) { @@ -391,7 +391,7 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e) if (fcount >= ftimes) { - int val = ke->key() - (int)Qt::Key_F1; + const int val = ke->key() - (int)Qt::Key_F1; if (val < combo->count()) combo->setCurrentIndex(val); @@ -417,10 +417,10 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e) } else if (o == this) { - auto focusedctrlEdit = dynamic_cast(this->focusWidget()); - auto focusedctrlSpin = dynamic_cast(this->focusWidget()); - auto focusedctrlDblSpin = dynamic_cast(this->focusWidget()); - auto focusedctrlCombo = dynamic_cast(this->focusWidget()); + const auto focusedctrlEdit = dynamic_cast(this->focusWidget()); + const auto focusedctrlSpin = dynamic_cast(this->focusWidget()); + const auto focusedctrlDblSpin = dynamic_cast(this->focusWidget()); + const auto focusedctrlCombo = dynamic_cast(this->focusWidget()); if (!focusedctrlEdit && !focusedctrlSpin && @@ -434,11 +434,11 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e) double zoom = 1; double rot = 1; double grow = 0.01; - bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier); - bool ctrl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier); + const bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier); + const bool ctrl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier); bool pre = true; - if (auto r = m_Controller->Renderer()) + if (const auto r = m_Controller->Renderer()) { hdist = std::abs(r->UpperRightX() - r->LowerLeftX()) * 0.01 * m_Controller->AffineScaleLockedToCurrent(); vdist = std::abs(r->UpperRightY() - r->LowerLeftY()) * 0.01 * m_Controller->AffineScaleLockedToCurrent(); diff --git a/Source/Fractorium/FractoriumLibrary.cpp b/Source/Fractorium/FractoriumLibrary.cpp index 2db506e..e2be177 100644 --- a/Source/Fractorium/FractoriumLibrary.cpp +++ b/Source/Fractorium/FractoriumLibrary.cpp @@ -7,10 +7,11 @@ void Fractorium::InitLibraryUI() { ui.LibraryTree->SetMainWindow(this); - connect(ui.LibraryTree, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemChanged(QTreeWidgetItem*, int)), Qt::QueuedConnection); + //Making the TreeItemChanged() events use a direct connection is absolutely critical. + connect(ui.LibraryTree, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemChanged(QTreeWidgetItem*, int)), Qt::DirectConnection); connect(ui.LibraryTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemDoubleClicked(QTreeWidgetItem*, int)), Qt::QueuedConnection); connect(ui.LibraryTree, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(OnEmberTreeItemDoubleClicked(QTreeWidgetItem*, int)), Qt::QueuedConnection); - connect(ui.SequenceTree, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(OnSequenceTreeItemChanged(QTreeWidgetItem*, int)), Qt::QueuedConnection); + connect(ui.SequenceTree, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(OnSequenceTreeItemChanged(QTreeWidgetItem*, int)), Qt::DirectConnection); connect(ui.SequenceStartPreviewsButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceStartPreviewsButtonClicked(bool)), Qt::QueuedConnection); connect(ui.SequenceStopPreviewsButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceStopPreviewsButtonClicked(bool)), Qt::QueuedConnection); connect(ui.SequenceAllButton, SIGNAL(clicked(bool)), this, SLOT(OnSequenceAllButtonClicked(bool)), Qt::QueuedConnection); @@ -68,7 +69,7 @@ void Fractorium::InitLibraryUI() /// The 0-based index of the item in the library tree to select void Fractorium::SelectLibraryItem(size_t index) { - if (auto top = ui.LibraryTree->topLevelItem(0)) + if (const auto top = ui.LibraryTree->topLevelItem(0)) { for (int i = 0; i < top->childCount(); i++) { @@ -89,10 +90,10 @@ vector> Fractorium::GetCurrentEmberIndex() { int index = 0; QTreeWidgetItem* item = nullptr; - auto tree = ui.LibraryTree; + const auto tree = ui.LibraryTree; vector> v; - if (auto top = tree->topLevelItem(0)) + if (const auto top = tree->topLevelItem(0)) { for (int i = 0; i < top->childCount(); i++)//Iterate through all of the children, which will represent the open embers. { @@ -117,7 +118,7 @@ vector> Fractorium::GetCurrentEmberIndex() /// The height of the bitmap void Fractorium::SetLibraryTreeItemData(EmberTreeWidgetItemBase* item, vv4F& v, uint w, uint h) { - m_PreviewVec.resize(w * h * 4); + m_PreviewVec.resize(size_t(w) * size_t(h) * 4); Rgba32ToRgba8(v.data(), m_PreviewVec.data(), w, h, m_Settings->Transparency()); item->SetImage(m_PreviewVec, w, h); } @@ -131,9 +132,9 @@ template void FractoriumEmberController::SyncLibrary(eLibraryUpdate update) { auto it = m_EmberFile.m_Embers.begin(); - auto tree = m_Fractorium->ui.LibraryTree; + const auto tree = m_Fractorium->ui.LibraryTree; - if (auto top = tree->topLevelItem(0)) + if (const auto top = tree->topLevelItem(0)) { 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. { @@ -166,11 +167,10 @@ void FractoriumEmberController::FillLibraryTree(int selectIndex) { uint size = 64; uint i = 0; - auto tree = m_Fractorium->ui.LibraryTree; + const auto tree = m_Fractorium->ui.LibraryTree; vector v(size * size * 4); StopAllPreviewRenderers(); tree->clear(); - QCoreApplication::processEvents(); auto fileItem = new QTreeWidgetItem(tree); QFileInfo info(m_EmberFile.m_Filename); fileItem->setText(0, info.fileName()); @@ -205,13 +205,13 @@ void FractoriumEmberController::FillLibraryTree(int selectIndex) template void FractoriumEmberController::UpdateLibraryTree() { - uint size = 64; + const uint size = 64; vector v(size * size * 4); - auto tree = m_Fractorium->ui.LibraryTree; + const auto tree = m_Fractorium->ui.LibraryTree; if (auto top = tree->topLevelItem(0)) { - int origChildCount = top->childCount(); + const int origChildCount = top->childCount(); int i = origChildCount; for (auto it = Advance(m_EmberFile.m_Embers.begin(), i); it != m_EmberFile.m_Embers.end(); ++it) @@ -249,25 +249,24 @@ void FractoriumEmberController::EmberTreeItemChanged(QTreeWidgetItem* item, i { try { - auto tree = m_Fractorium->ui.LibraryTree; + const auto tree = m_Fractorium->ui.LibraryTree; if (auto emberItem = dynamic_cast*>(item)) { - if (!emberItem->isSelected())//Checking/unchecking other items shouldn't perform the processing below. + auto oldName = emberItem->GetEmber()->m_Name;//First preserve the previous name. + auto newName = emberItem->text(0).toStdString(); + + //Checking/unchecking other items shouldn't perform the processing below. + //If nothing changed, nothing to do. + if (!emberItem->isSelected() && newName == oldName) return; - if (emberItem->text(0).isEmpty())//Prevent empty string. + if (newName.empty())//Prevent empty string. { emberItem->UpdateEditText(); return; } - string oldName = emberItem->GetEmber()->m_Name;//First preserve the previous name. - string newName = emberItem->text(0).toStdString(); - - if (oldName == newName)//If nothing changed, nothing to do. - return; - emberItem->UpdateEmberName();//Copy edit text to the ember's name variable. m_EmberFile.MakeNamesUnique();//Ensure all names remain unique. SyncLibrary(eLibraryUpdate::NAME);//Copy all ember names to the tree items since some might have changed to be made unique. @@ -281,7 +280,7 @@ void FractoriumEmberController::EmberTreeItemChanged(QTreeWidgetItem* item, i } else if (auto parentItem = dynamic_cast(item)) { - QString text = parentItem->text(0); + auto text = parentItem->text(0); if (text != "") { @@ -298,7 +297,7 @@ void FractoriumEmberController::EmberTreeItemChanged(QTreeWidgetItem* item, i void Fractorium::OnEmberTreeItemChanged(QTreeWidgetItem* item, int col) { - if (ui.LibraryTree->topLevelItemCount())//This can sometimes be spurriously called even when the tree is empty. + if (item && ui.LibraryTree->topLevelItemCount())//This can sometimes be spurriously called even when the tree is empty. m_Controller->EmberTreeItemChanged(item, col); } @@ -334,9 +333,9 @@ template void FractoriumEmberController::MoveLibraryItems(const QModelIndexList& items, int destRow) { int i = 0; - auto startRow = items[0].row(); - auto tree = m_Fractorium->ui.LibraryTree; - auto top = tree->topLevelItem(0); + const auto startRow = items[0].row(); + const auto tree = m_Fractorium->ui.LibraryTree; + const auto top = tree->topLevelItem(0); list names; for (auto& item : items) @@ -344,7 +343,7 @@ void FractoriumEmberController::MoveLibraryItems(const QModelIndexList& items names.push_back(temp->m_Name); auto b = m_EmberFile.m_Embers.begin(); - auto result = Gather(b, m_EmberFile.m_Embers.end(), Advance(b, destRow), [&](const Ember& ember) + const auto result = Gather(b, m_EmberFile.m_Embers.end(), Advance(b, destRow), [&](const Ember& ember) { auto position = std::find(names.begin(), names.end(), ember.m_Name); @@ -387,7 +386,7 @@ void FractoriumEmberController::Delete(const vectorui.LibraryTree->topLevelItem(0)) + if (const auto top = m_Fractorium->ui.LibraryTree->topLevelItem(0)) { last = std::min(top->childCount() - 1, last); @@ -421,9 +420,9 @@ void FractoriumEmberController::RenderPreviews(QTreeWidget* tree, TreePreview if (start == UINT_MAX && end == UINT_MAX) { - if (auto top = tree->topLevelItem(0)) + if (const auto top = tree->topLevelItem(0)) { - int childCount = top->childCount(); + const auto childCount = top->childCount(); vector emptyPreview(PREVIEW_SIZE * PREVIEW_SIZE * 4); for (int i = 0; i < childCount; i++) @@ -469,13 +468,12 @@ void FractoriumEmberController::StopAllPreviewRenderers() template void FractoriumEmberController::FillSequenceTree() { - uint size = 64; + const uint size = 64; uint i = 0; - auto tree = m_Fractorium->ui.SequenceTree; + const auto tree = m_Fractorium->ui.SequenceTree; vector v(size * size * 4); m_SequencePreviewRenderer->Stop(); tree->clear(); - QCoreApplication::processEvents();//Having to flush events is usually a sign of poor design. However, in this case, it's critical to have this here, else rapid button clicks will crash. auto fileItem = new QTreeWidgetItem(tree); QFileInfo info(m_SequenceFile.m_Filename); fileItem->setText(0, info.fileName()); @@ -512,7 +510,7 @@ void FractoriumEmberController::SequenceTreeItemChanged(QTreeWidgetItem* item { if (item == m_Fractorium->ui.SequenceTree->topLevelItem(0)) { - QString text = item->text(0); + auto text = item->text(0); if (text != "") m_SequenceFile.m_Filename = text; @@ -521,7 +519,7 @@ void FractoriumEmberController::SequenceTreeItemChanged(QTreeWidgetItem* item void Fractorium::OnSequenceTreeItemChanged(QTreeWidgetItem* item, int col) { - if (ui.SequenceTree->topLevelItemCount()) + if (item && ui.SequenceTree->topLevelItemCount()) m_Controller->SequenceTreeItemChanged(item, col); } @@ -549,9 +547,9 @@ void Fractorium::OnSequenceStopPreviewsButtonClicked(bool checked) { m_Controlle /// void Fractorium::SyncFileCountToSequenceCount() { - if (auto top = ui.LibraryTree->topLevelItem(0)) + if (const auto top = ui.LibraryTree->topLevelItem(0)) { - int count = top->childCount() - 1; + const int count = top->childCount() - 1; ui.LibraryTree->headerItem()->setText(0, "Current Flame File (" + QString::number(top->childCount()) + ")"); ui.SequenceStartFlameSpinBox->setMinimum(0); ui.SequenceStartFlameSpinBox->setMaximum(count); @@ -581,33 +579,33 @@ void FractoriumEmberController::SequenceGenerateButtonClicked() auto& ui = m_Fractorium->ui; auto s = m_Fractorium->m_Settings; //Bools for determining whether to use hard coded vs. random values. - bool randStagger = ui.SequenceRandomizeStaggerCheckBox->isChecked(); - bool randFramesRot = ui.SequenceRandomizeFramesPerRotCheckBox->isChecked(); - bool randRot = ui.SequenceRandomizeRotationsCheckBox->isChecked(); - bool randBlend = ui.SequenceRandomizeBlendFramesCheckBox->isChecked(); - bool randBlendRot = ui.SequenceRandomizeRotationsPerBlendCheckBox->isChecked(); + const bool randStagger = ui.SequenceRandomizeStaggerCheckBox->isChecked(); + const bool randFramesRot = ui.SequenceRandomizeFramesPerRotCheckBox->isChecked(); + const bool randRot = ui.SequenceRandomizeRotationsCheckBox->isChecked(); + const bool randBlend = ui.SequenceRandomizeBlendFramesCheckBox->isChecked(); + const bool randBlendRot = ui.SequenceRandomizeRotationsPerBlendCheckBox->isChecked(); //The direction to rotate the loops. - bool loopsCw = ui.SequenceRotationsCWCheckBox->isChecked(); - bool loopsBlendCw = ui.SequenceRotationsPerBlendCWCheckBox->isChecked(); + const bool loopsCw = ui.SequenceRotationsCWCheckBox->isChecked(); + const bool loopsBlendCw = ui.SequenceRotationsPerBlendCWCheckBox->isChecked(); //Whether to stagger, default is 1 which means no stagger. - double stagger = ui.SequenceStaggerSpinBox->value(); - double staggerMax = ui.SequenceRandomStaggerMaxSpinBox->value(); + const double stagger = ui.SequenceStaggerSpinBox->value(); + const double staggerMax = ui.SequenceRandomStaggerMaxSpinBox->value(); //Rotations on keyframes. - double rots = ui.SequenceRotationsSpinBox->value(); - double rotsMax = ui.SequenceRandomRotationsMaxSpinBox->value(); + const double rots = ui.SequenceRotationsSpinBox->value(); + const double rotsMax = ui.SequenceRandomRotationsMaxSpinBox->value(); //Number of frames it takes to rotate a keyframe. - int framesPerRot = ui.SequenceFramesPerRotSpinBox->value(); - int framesPerRotMax = ui.SequenceRandomFramesPerRotMaxSpinBox->value(); + const int framesPerRot = ui.SequenceFramesPerRotSpinBox->value(); + const int framesPerRotMax = ui.SequenceRandomFramesPerRotMaxSpinBox->value(); //Number of frames it takes to interpolate. - int framesBlend = ui.SequenceBlendFramesSpinBox->value(); - int framesBlendMax = ui.SequenceRandomBlendMaxFramesSpinBox->value(); + const int framesBlend = ui.SequenceBlendFramesSpinBox->value(); + const int framesBlendMax = ui.SequenceRandomBlendMaxFramesSpinBox->value(); //Number of rotations performed during interpolation. - int rotsPerBlend = ui.SequenceRotationsPerBlendSpinBox->value(); - int rotsPerBlendMax = ui.SequenceRotationsPerBlendMaxSpinBox->value(); - size_t start = ui.SequenceStartFlameSpinBox->value(); - size_t stop = ui.SequenceStopFlameSpinBox->value(); - size_t startCount = ui.SequenceStartCountSpinBox->value(); - size_t keyFrames = (stop - start) + 1; + const int rotsPerBlend = ui.SequenceRotationsPerBlendSpinBox->value(); + const int rotsPerBlendMax = ui.SequenceRotationsPerBlendMaxSpinBox->value(); + const size_t start = ui.SequenceStartFlameSpinBox->value(); + const size_t stop = ui.SequenceStopFlameSpinBox->value(); + const size_t startCount = ui.SequenceStartCountSpinBox->value(); + const size_t keyFrames = (stop - start) + 1; size_t frameCount = 0; double frames = 0; vector> devices;//Dummy. @@ -674,18 +672,18 @@ void FractoriumEmberController::SequenceGenerateButtonClicked() double blend; size_t frame; Ember embers[2];//Spin needs contiguous array below, and this will also get modified, so a copy is needed to avoid modifying the embers in the original file. - auto padding = streamsize(std::log10(frames)) + 1; + const auto padding = streamsize(std::log10(frames)) + 1; auto it = Advance(m_EmberFile.m_Embers.begin(), start); for (size_t i = start; i <= stop && it != m_EmberFile.m_Embers.end(); i++, ++it) { - double rotations = randRot ? m_Rand.Frand(rots, rotsMax) : rots; + const auto rotations = randRot ? m_Rand.Frand(rots, rotsMax) : rots; embers[0] = *it; if (rotations > 0) { - double rotFrames = randFramesRot ? m_Rand.Frand(framesPerRot, framesPerRotMax) : framesPerRot; - size_t roundFrames = size_t(std::round(rotFrames * rotations)); + const auto rotFrames = randFramesRot ? m_Rand.Frand(framesPerRot, framesPerRotMax) : framesPerRot; + const auto roundFrames = size_t(std::round(rotFrames * rotations)); for (frame = 0; frame < roundFrames; frame++) { @@ -711,9 +709,9 @@ void FractoriumEmberController::SequenceGenerateButtonClicked() auto it2 = it;//Need a quick temporary to avoid modifying it which is used in the loop. embers[1] = *(++it2);//Get the next ember to be used with blending below. - size_t blendFrames = randBlend ? m_Rand.Frand(framesBlend, framesBlendMax) : framesBlend; - double d = randBlendRot ? m_Rand.Frand(rotsPerBlend, rotsPerBlendMax) : double(rotsPerBlend); - size_t rpb = size_t(std::round(d)); + const auto blendFrames = randBlend ? m_Rand.Frand(framesBlend, framesBlendMax) : framesBlend; + const auto d = randBlendRot ? m_Rand.Frand(rotsPerBlend, rotsPerBlendMax) : double(rotsPerBlend); + const auto rpb = size_t(std::round(d)); if (randStagger) tools.Stagger(m_Rand.Frand(stagger, staggerMax)); @@ -722,7 +720,7 @@ void FractoriumEmberController::SequenceGenerateButtonClicked() { //if (frame == 43) // cout << frame << endl; - bool seqFlag = frame == 0 || (frame == blendFrames - 1); + const auto seqFlag = frame == 0 || (frame == blendFrames - 1); blend = frame / double(blendFrames); result.Clear(); tools.SpinInter(&embers[0], nullptr, result, startCount + frameCount++, seqFlag, blend, rpb, loopsBlendCw); From 54610ab73d03b399981689add2a50ff264c47bf7 Mon Sep 17 00:00:00 2001 From: Person Date: Tue, 21 Jul 2020 06:49:49 -0700 Subject: [PATCH 2/4] --User changes -Make tooltip for the show/hide affine toolbar buttons show the keyboard shortcut. --- Source/Fractorium/Fractorium.ui | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Fractorium/Fractorium.ui b/Source/Fractorium/Fractorium.ui index 21d82c9..4c35769 100644 --- a/Source/Fractorium/Fractorium.ui +++ b/Source/Fractorium/Fractorium.ui @@ -8745,7 +8745,7 @@ Pre - Show/Hide Pre Affines + Show/Hide Pre Affines (P) @@ -8756,7 +8756,7 @@ All - Show All Pre Affines + Show All Pre Affines (L) @@ -8767,7 +8767,7 @@ Post - Show/Hide Post Affines + Show/Hide Post Affines (Shift + P) @@ -8778,7 +8778,7 @@ All - Show All Post Affines + Show All Post Affines (Shift + L) From 99cc597abc5eaedc23f15fbc3a720aa0bd37fb54 Mon Sep 17 00:00:00 2001 From: Person Date: Thu, 30 Jul 2020 19:55:37 -0700 Subject: [PATCH 3/4] --Code changes -Add vignette variation. --- .../Installer/FractoriumInstaller.wixproj | 2 +- Builds/MSVC/Installer/Product.wxs | 4 +- Builds/MSVC/VS2019/Ember.rc | Bin 4522 -> 4522 bytes Builds/MSVC/VS2019/EmberAnimate.rc | 8 +- Builds/MSVC/VS2019/EmberCL.rc | Bin 4548 -> 4548 bytes Builds/MSVC/VS2019/EmberGenome.rc | 8 +- Builds/MSVC/VS2019/EmberRender.rc | 8 +- Builds/MSVC/VS2019/Fractorium.rc | Bin 4490 -> 4490 bytes Data/Version History.txt | 2 +- Source/Ember/Ember.cpp | 1 + Source/Ember/EmberDefines.h | 2 +- Source/Ember/Variation.h | 3 + Source/Ember/VariationList.cpp | 1 + Source/Ember/Variations07.h | 194 ++++++++++++++++++ Source/Fractorium/AboutDialog.ui | 2 +- 15 files changed, 217 insertions(+), 18 deletions(-) diff --git a/Builds/MSVC/Installer/FractoriumInstaller.wixproj b/Builds/MSVC/Installer/FractoriumInstaller.wixproj index 1036aa8..fb456da 100644 --- a/Builds/MSVC/Installer/FractoriumInstaller.wixproj +++ b/Builds/MSVC/Installer/FractoriumInstaller.wixproj @@ -6,7 +6,7 @@ 3.7 {c8096c47-e358-438c-a520-146d46b0637d} 2.0 - Fractorium_1.0.0.20 + Fractorium_1.0.0.21 Package $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets diff --git a/Builds/MSVC/Installer/Product.wxs b/Builds/MSVC/Installer/Product.wxs index 9aceebb..f8693f9 100644 --- a/Builds/MSVC/Installer/Product.wxs +++ b/Builds/MSVC/Installer/Product.wxs @@ -1,6 +1,6 @@ - + @@ -13,7 +13,7 @@ - + dIsgCw diff --git a/Builds/MSVC/VS2019/EmberAnimate.rc b/Builds/MSVC/VS2019/EmberAnimate.rc index 9873293..8d4bbfd 100644 --- a/Builds/MSVC/VS2019/EmberAnimate.rc +++ b/Builds/MSVC/VS2019/EmberAnimate.rc @@ -49,8 +49,8 @@ // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1, 0, 0, 20 - PRODUCTVERSION 1, 0, 0, 20 + FILEVERSION 1, 0, 0, 21 + PRODUCTVERSION 1, 0, 0, 21 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", "1, 0, 0, 20" + VALUE "FileVersion", "1, 0, 0, 21" VALUE "InternalName", "EmberAnimate.exe" VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2020, GPL v3" VALUE "OriginalFilename", "EmberAnimate.exe" VALUE "ProductName", "Ember Animate" - VALUE "ProductVersion", "1, 0, 0, 20" + VALUE "ProductVersion", "1, 0, 0, 21" END END BLOCK "VarFileInfo" diff --git a/Builds/MSVC/VS2019/EmberCL.rc b/Builds/MSVC/VS2019/EmberCL.rc index ec61563d132505f13753033315093498ac010482..0021d942d978d725128aacd48eac7f55724fa4a0 100644 GIT binary patch delta 44 zcmX@2d_;M}7Y;_l$zM4v84WkwH(%o3#>i;6xs#WX1pqvX B4B7wy delta 46 zcmeBD?o!@xj)T!)@_7zRRs#lJ2Cm8doT8hRIA<^c1q->wH(%o3#>i-}xs#WX1pquP B4AuYu diff --git a/Data/Version History.txt b/Data/Version History.txt index 6172a3f..0fab215 100644 --- a/Data/Version History.txt +++ b/Data/Version History.txt @@ -1,4 +1,4 @@ -1.0.0.20 4/11/2020 +1.0.0.21 4/11/2020 --Bug fixes -ETA time was wrong with incremental final renders after waiting for a period of time. -Fix possible OpenCL bugs in cubic3D, cubicLattice_3D, dc_cube, falloff, falloff2, falloff3, waffle. diff --git a/Source/Ember/Ember.cpp b/Source/Ember/Ember.cpp index 6e22e18..41beacf 100644 --- a/Source/Ember/Ember.cpp +++ b/Source/Ember/Ember.cpp @@ -496,6 +496,7 @@ uint Timing::m_ProcessorCount; EXPORTPREPOSTREGVAR(Gnarly, T) \ EXPORTPREPOSTREGVAR(Inkdrop, T) \ EXPORTPREPOSTREGVAR(HexModulus, T) \ + EXPORTPREPOSTREGVAR(Vignette, T) \ template EMBER_API class VariationList; \ template EMBER_API class SpatialFilter; \ template EMBER_API class GaussianFilter; \ diff --git a/Source/Ember/EmberDefines.h b/Source/Ember/EmberDefines.h index 13544cd..e50087c 100644 --- a/Source/Ember/EmberDefines.h +++ b/Source/Ember/EmberDefines.h @@ -37,7 +37,7 @@ static void sincos(float x, float* s, float* c) namespace EmberNs { -#define EMBER_VERSION "1.0.0.20" +#define EMBER_VERSION "1.0.0.21" //#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::epsilon()//Apoplugin.h uses -20, but it's more mathematically correct to do it this way. diff --git a/Source/Ember/Variation.h b/Source/Ember/Variation.h index 5c1e4c0..aeae69a 100644 --- a/Source/Ember/Variation.h +++ b/Source/Ember/Variation.h @@ -433,6 +433,7 @@ enum class eVariationId : glm::uint VAR_UNPOLAR , VAR_VIBRATION, VAR_VIBRATION2, + VAR_VIGNETTE, VAR_VORON, VAR_W , VAR_WAFFLE, @@ -849,6 +850,7 @@ enum class eVariationId : glm::uint VAR_PRE_UNPOLAR, VAR_PRE_VIBRATION, VAR_PRE_VIBRATION2, + VAR_PRE_VIGNETTE, VAR_PRE_VORON, VAR_PRE_W, VAR_PRE_WAFFLE, @@ -1265,6 +1267,7 @@ enum class eVariationId : glm::uint VAR_POST_UNPOLAR, VAR_POST_VIBRATION, VAR_POST_VIBRATION2, + VAR_POST_VIGNETTE, VAR_POST_VORON, VAR_POST_W, VAR_POST_WAFFLE, diff --git a/Source/Ember/VariationList.cpp b/Source/Ember/VariationList.cpp index 18dfd34..5a0067f 100644 --- a/Source/Ember/VariationList.cpp +++ b/Source/Ember/VariationList.cpp @@ -439,6 +439,7 @@ VariationList::VariationList() ADDPREPOSTREGVAR(Gnarly) ADDPREPOSTREGVAR(Inkdrop) ADDPREPOSTREGVAR(HexModulus) + ADDPREPOSTREGVAR(Vignette) //ADDPREPOSTREGVAR(LinearXZ) //ADDPREPOSTREGVAR(LinearYZ) //DC are special. diff --git a/Source/Ember/Variations07.h b/Source/Ember/Variations07.h index 708be70..f1946ed 100644 --- a/Source/Ember/Variations07.h +++ b/Source/Ember/Variations07.h @@ -7564,6 +7564,199 @@ private: T m_Yfact001;//Precalc. }; +/// +/// vignette by Bezo97. +/// +template +class VignetteVariation : public ParametricVariation +{ +public: + VignetteVariation(T weight = 1.0) : ParametricVariation("vignette", eVariationId::VAR_VIGNETTE, weight) + { + Init(); + } + + PARVARCOPY(VignetteVariation) + + virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override + { + T px = helper.In.x; + T py = helper.In.y; + T dist = std::sqrt((px - m_Posx) * (px - m_Posx) + (py - m_Posy) * (py - m_Posy)); + + if (dist < m_InnerabsPrecalc) + { + helper.Out.z = DefaultZ(helper); + + //middle part + if (m_Innerradius < 0.0) + { + helper.Out.x = 0; + helper.Out.y = 0; + return; + } + + helper.Out.x = px * m_Weight; + helper.Out.y = py * m_Weight; + return; + } + + //map to 0-1 + dist = (dist - m_InnerabsPrecalc) / m_FadeabsPrecalc; + T fade = T(1.0) - std::pow(rand.Frand01(), m_PowerhelperPrecalc); + T blur_r = m_Blur * std::pow(dist * rand.Frand01(), T(2.0)); + T blur_a = rand.Frand01() * M_2PI; + + if (m_Faderadius > 0) + { + //vignette + if (fade < dist) + { + px = 0; + py = 0; + } + else + { + px += blur_r * std::cos(blur_a); + py += blur_r * std::sin(blur_a); + } + } + else + { + //inverse vignette + if (1 - fade > dist) + { + px = 0; + py = 0; + } + else + { + px += blur_r * std::cos(blur_a); + py += blur_r * std::sin(blur_a); + } + } + + helper.Out.x = px * m_Weight; + helper.Out.y = py * m_Weight; + helper.Out.z = DefaultZ(helper); + } + + virtual string OpenCLString() const override + { + ostringstream ss, ss2; + intmax_t i = 0, varIndex = IndexInXform(); + ss2 << "_" << XformIndexInEmber() << "]"; + string index = ss2.str(); + string weight = WeightDefineString(); + string posx = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string posy = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string innerradius = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string faderadius = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string power = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string blur = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string innerabsprecalc = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string fadeabsprecalc = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string powerhelperprecalc = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + ss << "\t{\n" + << "\t\treal_t px = vIn.x;\n" + << "\t\treal_t py = vIn.y;\n" + << "\t\treal_t dist = sqrt((px - " << posx << ") * (px - " << posx << ") + (py - " << posy << ") * (py - " << posy << "));\n" + << "\n" + << "\t\tif (dist < " << innerabsprecalc << ")\n" + << "\t\t{\n" + << "\t\t\tvOut.z = " << DefaultZCl() + << "\n" + << "\t\t\tif (" << innerradius << " < (real_t)(0.0))\n" + << "\t\t\t{\n" + << "\t\t\t\tvOut.x = (real_t)(0.0);\n" + << "\t\t\t\tvOut.y = (real_t)(0.0);\n" + << "\t\t\t\treturn;\n" + << "\t\t\t}\n" + << "\n" + << "\t\t\tvOut.x = px * " << weight << ";\n" + << "\t\t\tvOut.y = py * " << weight << ";\n" + << "\t\t}\n" + << "\n" + << "\t\tdist = (dist - " << innerabsprecalc << ") / " << fadeabsprecalc << ";\n" + << "\n" + << "\t\treal_t fade = (real_t)(1.0) - pow(MwcNext01(mwc), " << powerhelperprecalc << ");\n" + << "\t\treal_t blur_r = " << blur << " * pow(dist * MwcNext01(mwc), (real_t)(2.0));\n" + << "\t\treal_t blur_a = MwcNext01(mwc) * M_2PI;\n" + << "\n" + << "\t\tif (" << faderadius << " > 0.0)\n" + << "\t\t{\n" + << "\t\t\tif (fade < dist)\n" + << "\t\t\t{\n" + << "\t\t\t\tpx = (real_t)(0.0);\n" + << "\t\t\t\tpy = (real_t)(0.0);\n" + << "\t\t\t}\n" + << "\t\t\telse\n" + << "\t\t\t{\n" + << "\t\t\t\tpx += blur_r * cos(blur_a);\n" + << "\t\t\t\tpy += blur_r * sin(blur_a);\n" + << "\t\t\t}\n" + << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t\tif (1 - fade > dist)\n" + << "\t\t\t{\n" + << "\t\t\t\tpx = (real_t)(0.0);\n" + << "\t\t\t\tpy = (real_t)(0.0);\n" + << "\t\t\t}\n" + << "\t\t\telse\n" + << "\t\t\t{\n" + << "\t\t\t\tpx += blur_r * cos(blur_a);\n" + << "\t\t\t\tpy += blur_r * sin(blur_a);\n" + << "\t\t\t}\n" + << "\t\t}\n" + << "\n" + << "\t\tvOut.x = px * " << weight << ";\n" + << "\t\tvOut.y = py * " << weight << ";\n" + << "\t\tvOut.z = " << DefaultZCl() + << "\t}\n"; + return ss.str(); + } + + virtual void Precalc() override + { + m_InnerabsPrecalc = std::abs(m_Innerradius); + m_FadeabsPrecalc = std::abs(m_Faderadius); + m_PowerhelperPrecalc = T(1.0) / std::abs(m_Power); + } + + virtual vector OpenCLGlobalFuncNames() const override + { + return vector { "Zeps" }; + } + +protected: + void Init() + { + string prefix = Prefix(); + m_Params.clear(); + m_Params.push_back(ParamWithName(&m_Posx, prefix + "vignette_posx")); + m_Params.push_back(ParamWithName(&m_Posy, prefix + "vignette_posy")); + m_Params.push_back(ParamWithName(&m_Innerradius, prefix + "vignette_inner_radius", T(0.5))); + m_Params.push_back(ParamWithName(&m_Faderadius, prefix + "vignette_fade_radius", T(0.5), eParamType::REAL_NONZERO)); + m_Params.push_back(ParamWithName(&m_Power, prefix + "vignette_power", T(4.0), eParamType::REAL_NONZERO)); + m_Params.push_back(ParamWithName(&m_Blur, prefix + "vignette_blur", T(1.0))); + m_Params.push_back(ParamWithName(true, &m_InnerabsPrecalc, prefix + "vignette_inner_abs_precalc"));//Precalc. + m_Params.push_back(ParamWithName(true, &m_FadeabsPrecalc, prefix + "vignette_fade_abs_precalc")); + m_Params.push_back(ParamWithName(true, &m_PowerhelperPrecalc, prefix + "vignette_power_helper_precalc")); + } + +private: + T m_Posx; + T m_Posy; + T m_Innerradius; + T m_Faderadius; + T m_Power; + T m_Blur; + T m_InnerabsPrecalc;//Precalc. + T m_FadeabsPrecalc; + T m_PowerhelperPrecalc; +}; + MAKEPREPOSTPARVAR(Splits3D, splits3D, SPLITS3D) MAKEPREPOSTPARVAR(Waves2B, waves2b, WAVES2B) MAKEPREPOSTPARVAR(JacCn, jac_cn, JAC_CN) @@ -7634,4 +7827,5 @@ MAKEPREPOSTPARVAR(Waves23, waves23, WAVES23) MAKEPREPOSTPARVAR(Waves42, waves42, WAVES42) MAKEPREPOSTPARVAR(Waves3, waves3, WAVES3) MAKEPREPOSTPARVAR(Waves4, waves4, WAVES4) +MAKEPREPOSTPARVAR(Vignette, vignette, VIGNETTE) } diff --git a/Source/Fractorium/AboutDialog.ui b/Source/Fractorium/AboutDialog.ui index 1c40021..3bf07b0 100644 --- a/Source/Fractorium/AboutDialog.ui +++ b/Source/Fractorium/AboutDialog.ui @@ -58,7 +58,7 @@ QFrame::NoFrame - <html><head/><body><p align="center"><span style=" font-size:10pt;">Fractorium 1.0.0.20</span></p><p align="center"><span style=" font-size:10pt;">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.</span></p><p align="center"><a href="http://fractorium.com"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">fractorium.com</span></a></p></body></html> + <html><head/><body><p align="center"><span style=" font-size:10pt;">Fractorium 1.0.0.21</span></p><p align="center"><span style=" font-size:10pt;">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.</span></p><p align="center"><a href="http://fractorium.com"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">fractorium.com</span></a></p></body></html> Qt::RichText From 36b71278ec3053132f56dbfb62f1c1cc26d2ce81 Mon Sep 17 00:00:00 2001 From: Person Date: Sat, 1 Aug 2020 18:05:14 -0700 Subject: [PATCH 4/4] --Bug fixes -Fix bug in previous vignette variation. --- Source/Ember/Variations07.h | 86 ++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/Source/Ember/Variations07.h b/Source/Ember/Variations07.h index f1946ed..b94b311 100644 --- a/Source/Ember/Variations07.h +++ b/Source/Ember/Variations07.h @@ -7583,11 +7583,10 @@ public: T px = helper.In.x; T py = helper.In.y; T dist = std::sqrt((px - m_Posx) * (px - m_Posx) + (py - m_Posy) * (py - m_Posy)); + helper.Out.z = DefaultZ(helper); if (dist < m_InnerabsPrecalc) { - helper.Out.z = DefaultZ(helper); - //middle part if (m_Innerradius < 0.0) { @@ -7638,7 +7637,6 @@ public: helper.Out.x = px * m_Weight; helper.Out.y = py * m_Weight; - helper.Out.z = DefaultZ(helper); } virtual string OpenCLString() const override @@ -7662,57 +7660,59 @@ public: << "\t\treal_t py = vIn.y;\n" << "\t\treal_t dist = sqrt((px - " << posx << ") * (px - " << posx << ") + (py - " << posy << ") * (py - " << posy << "));\n" << "\n" + << "\t\tvOut.z = " << DefaultZCl() + << "\n" << "\t\tif (dist < " << innerabsprecalc << ")\n" << "\t\t{\n" - << "\t\t\tvOut.z = " << DefaultZCl() - << "\n" << "\t\t\tif (" << innerradius << " < (real_t)(0.0))\n" << "\t\t\t{\n" << "\t\t\t\tvOut.x = (real_t)(0.0);\n" << "\t\t\t\tvOut.y = (real_t)(0.0);\n" - << "\t\t\t\treturn;\n" + << "\t\t\t}\n" + << "\t\t\telse\n" + << "\t\t\t{\n" + << "\t\t\t\tvOut.x = px * " << weight << ";\n" + << "\t\t\t\tvOut.y = py * " << weight << ";\n" + << "\t\t\t}\n" + << "\t\t}\n" + << "\t\telse\n" + << "\t\t{\n" + << "\t\t\tdist = (dist - " << innerabsprecalc << ") / " << fadeabsprecalc << ";\n" + << "\n" + << "\t\t\treal_t fade = (real_t)(1.0) - pow(MwcNext01(mwc), " << powerhelperprecalc << ");\n" + << "\t\t\treal_t blur_r = " << blur << " * pow(dist * MwcNext01(mwc), (real_t)(2.0));\n" + << "\t\t\treal_t blur_a = MwcNext01(mwc) * M_2PI;\n" + << "\n" + << "\t\t\tif (" << faderadius << " > 0.0)\n" + << "\t\t\t{\n" + << "\t\t\t\tif (fade < dist)\n" + << "\t\t\t\t{\n" + << "\t\t\t\t\tpx = (real_t)(0.0);\n" + << "\t\t\t\t\tpy = (real_t)(0.0);\n" + << "\t\t\t\t}\n" + << "\t\t\t\telse\n" + << "\t\t\t\t{\n" + << "\t\t\t\t\tpx += blur_r * cos(blur_a);\n" + << "\t\t\t\t\tpy += blur_r * sin(blur_a);\n" + << "\t\t\t\t}\n" + << "\t\t\t}\n" + << "\t\t\telse\n" + << "\t\t\t{\n" + << "\t\t\t\tif (1 - fade > dist)\n" + << "\t\t\t\t{\n" + << "\t\t\t\t\tpx = (real_t)(0.0);\n" + << "\t\t\t\t\tpy = (real_t)(0.0);\n" + << "\t\t\t\t}\n" + << "\t\t\t\telse\n" + << "\t\t\t\t{\n" + << "\t\t\t\t\tpx += blur_r * cos(blur_a);\n" + << "\t\t\t\t\tpy += blur_r * sin(blur_a);\n" + << "\t\t\t\t}\n" << "\t\t\t}\n" << "\n" << "\t\t\tvOut.x = px * " << weight << ";\n" << "\t\t\tvOut.y = py * " << weight << ";\n" << "\t\t}\n" - << "\n" - << "\t\tdist = (dist - " << innerabsprecalc << ") / " << fadeabsprecalc << ";\n" - << "\n" - << "\t\treal_t fade = (real_t)(1.0) - pow(MwcNext01(mwc), " << powerhelperprecalc << ");\n" - << "\t\treal_t blur_r = " << blur << " * pow(dist * MwcNext01(mwc), (real_t)(2.0));\n" - << "\t\treal_t blur_a = MwcNext01(mwc) * M_2PI;\n" - << "\n" - << "\t\tif (" << faderadius << " > 0.0)\n" - << "\t\t{\n" - << "\t\t\tif (fade < dist)\n" - << "\t\t\t{\n" - << "\t\t\t\tpx = (real_t)(0.0);\n" - << "\t\t\t\tpy = (real_t)(0.0);\n" - << "\t\t\t}\n" - << "\t\t\telse\n" - << "\t\t\t{\n" - << "\t\t\t\tpx += blur_r * cos(blur_a);\n" - << "\t\t\t\tpy += blur_r * sin(blur_a);\n" - << "\t\t\t}\n" - << "\t\t}\n" - << "\t\telse\n" - << "\t\t{\n" - << "\t\t\tif (1 - fade > dist)\n" - << "\t\t\t{\n" - << "\t\t\t\tpx = (real_t)(0.0);\n" - << "\t\t\t\tpy = (real_t)(0.0);\n" - << "\t\t\t}\n" - << "\t\t\telse\n" - << "\t\t\t{\n" - << "\t\t\t\tpx += blur_r * cos(blur_a);\n" - << "\t\t\t\tpy += blur_r * sin(blur_a);\n" - << "\t\t\t}\n" - << "\t\t}\n" - << "\n" - << "\t\tvOut.x = px * " << weight << ";\n" - << "\t\tvOut.y = py * " << weight << ";\n" - << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); }