--User changes

-Optimization and correction for hexaplay3D and hexnix3D.
 -Major optimization on the GPU for flames which only have one xform, by skipping all random xform selection code.
 -Changes to how xaos is "preserved" when adding new xforms, copying xforms and duplicating xforms.
 --Duplicating xforms when no xaos is present in the flame now maintains not using xaos, and keeps all values as one.
 --Duplicating xforms when xaos is present, will result in xaos rows and columns that are the same as the xforms being duplicated, with the new row and column area having values of 1.
 --Duplicating xforms when xaos is present, while Control is pressed, will result in xaos rows and columns that have values of 0, with the new row and column area having values of 1.
 ---Copying xforms has the same behavior as duplicating with Control pressed.

--Bug fixes
 -hexaplay3D, hexnix3D and post_smartcrop were wrong on the GPU because they are the rare variations which preserve state between iterations.
 -Changing the sub batch size would improperly wrong the wrong number of iterations.

--Code changes
 -Some functions in Affine2D made const.
 -Change in the index at which points and variation state are preserved between kernel calls.
 -Some arguments in some member functions of GLEmberController made const.
This commit is contained in:
Person
2020-01-25 11:12:49 -08:00
parent 207ace6c67
commit 3b261124b2
19 changed files with 531 additions and 387 deletions

View File

@ -3212,7 +3212,7 @@
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Duplicate selected xforms.&lt;/p&gt;&lt;p&gt;If xaos is present in the flame, the duplicated xforms will be added with existing xaos preserved, else they'll just be added normally.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Duplicate selected xforms.&lt;/p&gt;&lt;p&gt;If xaos is present in the flame, the duplicated xforms will be added with existing xaos preserved, or as a layer if Ctrl is pressed, else they'll just be added normally.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
@ -8571,7 +8571,7 @@
<string>Paste selected x&amp;forms</string>
</property>
<property name="toolTip">
<string>Paste copied xforms into the current flame</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Paste copied xforms as a layer into the current flame&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="shortcut">
<string>Ctrl+X, Ctrl+V</string>

View File

@ -596,7 +596,7 @@ private:
EmberFile<T> m_EmberFile;
EmberFile<T> m_SequenceFile;
deque<Ember<T>> m_UndoList;
vector<Xform<T>> m_CopiedXforms;
vector<std::pair<Xform<T>, size_t>> m_CopiedXforms;
Xform<T> m_CopiedFinalXform;
Affine2D<T> m_CopiedAffine;
shared_ptr<VariationList<T>> m_VariationList;

View File

@ -686,7 +686,7 @@ void FractoriumEmberController<T>::CopySelectedXforms()
if (m_Ember.IsFinalXform(xform))
m_CopiedFinalXform = *xform;
else
m_CopiedXforms.push_back(*xform);
m_CopiedXforms.emplace_back(*xform, xfindex);
}, eXformUpdate::UPDATE_SELECTED, false);
m_Fractorium->ui.ActionPasteSelectedXforms->setEnabled(true);
}

View File

@ -264,7 +264,7 @@ void FractoriumEmberController<T>::AddLayer(int xforms)
{
Update([&]
{
std::vector<Xform<T>> vec(xforms);
std::vector<std::pair<Xform<T>, size_t>> vec(xforms);
AddXformsWithXaos(m_Ember, vec, false);
});

View File

@ -209,6 +209,7 @@ void Fractorium::OnAddLinkedXformButtonClicked(bool checked) { m_Controller->Add
/// <summary>
/// Duplicate the specified xforms in the current ember, and set the last one as the current xform.
/// If xaos is present in the ember, the duplicated xforms will be added with xaos preserved, else they'll just be added normally.
/// The manner in which xaos is preserved is altered when ctrl is pressed.
/// Called when the duplicate xform button is clicked.
/// Resets the rendering process.
/// </summary>
@ -217,19 +218,45 @@ template <typename T>
void FractoriumEmberController<T>::DuplicateXform()
{
bool forceFinal = m_Fractorium->HaveFinal();
vector<Xform<T>> vec;
bool ctrl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier);
vector<std::pair<Xform<T>, size_t>> vec;
vec.reserve(m_Ember.XformCount());
UpdateXform([&](Xform<T>* xform, size_t xfindex, size_t selIndex)
{
vec.push_back(*xform);
vec.emplace_back(*xform, xfindex);
}, eXformUpdate::UPDATE_SELECTED_EXCEPT_FINAL, false);
Update([&]()
{
if (m_Ember.XaosPresent())
AddXformsWithXaos(m_Ember, vec, true);
{
if (!ctrl)
{
auto oldxfcount = m_Ember.XformCount();
for (auto& it : vec)
{
m_Ember.AddXform(it.first);
auto newxfcount = m_Ember.XformCount() - 1;
auto* newxform = m_Ember.GetXform(newxfcount);
for (size_t i = 0; i < oldxfcount; i++)
{
if (auto xform = m_Ember.GetXform(i))
{
newxform->SetXaos(i, it.first.Xaos(i));
xform->SetXaos(newxfcount, xform->Xaos(it.second));
}
}
}
}
else
{
AddXformsWithXaos(m_Ember, vec, true);
}
}
else
for (auto& it : vec)
m_Ember.AddXform(it);
m_Ember.AddXform(it.first);
int index = int(m_Ember.TotalXformCount(forceFinal) - (forceFinal ? 2 : 1));//Set index to the last item before final.
FillXforms(index);//Handles xaos.

View File

@ -119,9 +119,9 @@ public:
void CalcDragTranslation();
void SetSelectedXform(Xform<T>* xform);
void DrawGrid();
void DrawAffine(Xform<T>* xform, bool pre, bool selected, bool hovered);
int UpdateHover(v3T& glCoords);
bool CheckXformHover(Xform<T>* xform, v3T& glCoords, T& bestDist, bool pre, bool post);
void DrawAffine(const Xform<T>* xform, bool pre, bool selected, bool hovered);
int UpdateHover(const v3T& glCoords);
bool CheckXformHover(const Xform<T>* xform, const v3T& glCoords, T& bestDist, bool pre, bool post);
private:
v2T SnapToGrid(v2T& vec);

View File

@ -1519,7 +1519,7 @@ void GLEmberController<T>::DrawGrid()
/// <param name="selected">True if selected (draw enclosing circle), else false (only draw axes).</param>
/// <param name="hovered">True if the xform is being hovered over (draw tansparent disc), else false (no disc).</param>
template <typename T>
void GLEmberController<T>::DrawAffine(Xform<T>* xform, bool pre, bool selected, bool hovered)
void GLEmberController<T>::DrawAffine(const Xform<T>* xform, bool pre, bool selected, bool hovered)
{
auto ember = m_FractoriumEmberController->CurrentEmber();
auto final = ember->IsFinalXform(xform);
@ -1755,7 +1755,7 @@ void GLWidget::DrawAffineHelper(int index, float circleWidth, float lineWidth, b
/// <param name="glCoords">The mouse raster coordinates to check</param>
/// <returns>The index of the xform being hovered over, else -1 if no hover.</returns>
template <typename T>
int GLEmberController<T>::UpdateHover(v3T& glCoords)
int GLEmberController<T>::UpdateHover(const v3T& glCoords)
{
bool pre = m_Fractorium->ui.PreAffineGroupBox->isChecked();
bool post = m_Fractorium->ui.PostAffineGroupBox->isChecked();
@ -1838,7 +1838,7 @@ int GLEmberController<T>::UpdateHover(v3T& glCoords)
/// <param name="post">True to check post affine, else don't.</param>
/// <returns>True if hovering and the distance is smaller than the bestDist parameter</returns>
template <typename T>
bool GLEmberController<T>::CheckXformHover(Xform<T>* xform, v3T& glCoords, T& bestDist, bool pre, bool post)
bool GLEmberController<T>::CheckXformHover(const Xform<T>* xform, const v3T& glCoords, T& bestDist, bool pre, bool post)
{
bool preFound = false, postFound = false;
T dist = 0, scale = m_FractoriumEmberController->AffineScaleCurrentToLocked();