mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-02-01 18:40:12 -05:00
Merged mfeemster/fractorium into master
This commit is contained in:
commit
575357817c
@ -18,7 +18,11 @@ template EMBER_API class QTIsaac<ISAAC_SIZE, ISAAC_INT>;
|
|||||||
#include "Point.h"
|
#include "Point.h"
|
||||||
#include "VarFuncs.h"
|
#include "VarFuncs.h"
|
||||||
#include "Variation.h"
|
#include "Variation.h"
|
||||||
#include "Variations01.h"
|
#ifdef FLAM3_COMPAT
|
||||||
|
#include "Variations01_flam3_compat.h"//Do this instead if you want full compatibility with flam3.
|
||||||
|
#else
|
||||||
|
#include "Variations01.h"
|
||||||
|
#endif
|
||||||
#include "Variations02.h"
|
#include "Variations02.h"
|
||||||
#include "Variations03.h"
|
#include "Variations03.h"
|
||||||
#include "Variations04.h"
|
#include "Variations04.h"
|
||||||
|
@ -1078,11 +1078,11 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (rand.Rand() & 1)
|
if (rand.Rand() & 1)
|
||||||
sym = symDistrib[rand.Rand() % Vlen(symDistrib)];
|
sym = symDistrib[rand.Rand(Vlen(symDistrib))];
|
||||||
else if (rand.Rand() & 31)
|
else if (rand.Rand() & 31)
|
||||||
sym = intmax_t(rand.Rand() % 13) - 6;
|
sym = intmax_t(rand.Rand(13)) - 6;
|
||||||
else
|
else
|
||||||
sym = intmax_t(rand.Rand() % 51) - 25;
|
sym = intmax_t(rand.Rand(51)) - 25;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym == 1 || sym == 0)
|
if (sym == 1 || sym == 0)
|
||||||
|
@ -38,6 +38,7 @@ static void sincos(float x, float* s, float* c)
|
|||||||
namespace EmberNs
|
namespace EmberNs
|
||||||
{
|
{
|
||||||
#define EMBER_VERSION "1.0.0.17"
|
#define EMBER_VERSION "1.0.0.17"
|
||||||
|
//#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 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.
|
#define EPS std::numeric_limits<T>::epsilon()//Apoplugin.h uses -20, but it's more mathematically correct to do it this way.
|
||||||
#define ISAAC_SIZE 4
|
#define ISAAC_SIZE 4
|
||||||
|
@ -148,9 +148,9 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="upper">A value one greater than the maximum value that will be returned</param>
|
/// <param name="upper">A value one greater than the maximum value that will be returned</param>
|
||||||
/// <returns>A value between 0 and the value passed in minus 1</returns>
|
/// <returns>A value between 0 and the value passed in minus 1</returns>
|
||||||
inline T Rand(T upper)
|
inline T Rand(size_t upper)
|
||||||
{
|
{
|
||||||
return (upper == 0) ? Rand() : Rand() % upper;
|
return (upper == 0) ? Rand() : T(((size_t)Rand() * upper) >> 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -158,7 +158,7 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="upper">A value one greater than the maximum value that will be returned</param>
|
/// <param name="upper">A value one greater than the maximum value that will be returned</param>
|
||||||
/// <returns>A value between 0 and the value passed in minus 1</returns>
|
/// <returns>A value between 0 and the value passed in minus 1</returns>
|
||||||
static inline T LockedRand(T upper)
|
static inline T LockedRand(size_t upper)
|
||||||
{
|
{
|
||||||
rlg l(*s_CS.get());
|
rlg l(*s_CS.get());
|
||||||
T t = GlobalRand->Rand(upper);
|
T t = GlobalRand->Rand(upper);
|
||||||
@ -420,14 +420,14 @@ protected:
|
|||||||
{
|
{
|
||||||
#ifndef __ISAAC64
|
#ifndef __ISAAC64
|
||||||
RngStep((a << 13), a, b, mm, m, m2, r, x, y);
|
RngStep((a << 13), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep((a >> 6) , a, b, mm, m, m2, r, x, y);
|
RngStep((a >> 6), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep((a << 2) , a, b, mm, m, m2, r, x, y);
|
RngStep((a << 2), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep((a >> 16), a, b, mm, m, m2, r, x, y);
|
RngStep((a >> 16), a, b, mm, m, m2, r, x, y);
|
||||||
#else // __ISAAC64
|
#else // __ISAAC64
|
||||||
RngStep(~(a ^ (a << 21)), a, b, mm, m, m2, r, x, y);
|
RngStep(~(a ^ (a << 21)), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep( a ^ (a >> 5) , a, b, mm, m, m2, r, x, y);
|
RngStep( a ^ (a >> 5), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep( a ^ (a << 12) , a, b, mm, m, m2, r, x, y);
|
RngStep( a ^ (a << 12), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep( a ^ (a >> 33) , a, b, mm, m, m2, r, x, y);
|
RngStep( a ^ (a >> 33), a, b, mm, m, m2, r, x, y);
|
||||||
#endif // __ISAAC64
|
#endif // __ISAAC64
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,14 +437,14 @@ protected:
|
|||||||
{
|
{
|
||||||
#ifndef __ISAAC64
|
#ifndef __ISAAC64
|
||||||
RngStep((a << 13), a, b, mm, m, m2, r, x, y);
|
RngStep((a << 13), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep((a >> 6) , a, b, mm, m, m2, r, x, y);
|
RngStep((a >> 6), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep((a << 2) , a, b, mm, m, m2, r, x, y);
|
RngStep((a << 2), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep((a >> 16), a, b, mm, m, m2, r, x, y);
|
RngStep((a >> 16), a, b, mm, m, m2, r, x, y);
|
||||||
#else // __ISAAC64
|
#else // __ISAAC64
|
||||||
RngStep(~(a ^ (a << 21)), a, b, mm, m, m2, r, x, y);
|
RngStep(~(a ^ (a << 21)), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep( a ^ (a >> 5) , a, b, mm, m, m2, r, x, y);
|
RngStep( a ^ (a >> 5), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep( a ^ (a << 12) , a, b, mm, m, m2, r, x, y);
|
RngStep( a ^ (a << 12), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep( a ^ (a >> 33) , a, b, mm, m, m2, r, x, y);
|
RngStep( a ^ (a >> 33), a, b, mm, m, m2, r, x, y);
|
||||||
#endif // __ISAAC64
|
#endif // __ISAAC64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ Palette<T>* PaletteList<T>::GetRandomPalette()
|
|||||||
while (attempts < Size() * 10)
|
while (attempts < Size() * 10)
|
||||||
{
|
{
|
||||||
auto p = s_Palettes.begin();
|
auto p = s_Palettes.begin();
|
||||||
auto paletteFileIndex = QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand() % Size();
|
auto paletteFileIndex = QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand(Size());
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
//Move p forward i elements.
|
//Move p forward i elements.
|
||||||
@ -281,7 +281,7 @@ Palette<T>* PaletteList<T>::GetRandomPalette()
|
|||||||
|
|
||||||
if (i < Size())
|
if (i < Size())
|
||||||
{
|
{
|
||||||
size_t paletteIndex = QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand() % p->second.size();
|
size_t paletteIndex = QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRand(p->second.size());
|
||||||
|
|
||||||
if (paletteIndex < p->second.size() && !p->second[paletteIndex].IsEmpty())
|
if (paletteIndex < p->second.size() && !p->second[paletteIndex].IsEmpty())
|
||||||
return &p->second[paletteIndex];
|
return &p->second[paletteIndex];
|
||||||
|
@ -254,7 +254,7 @@ public:
|
|||||||
//Generate a 2-xform random.
|
//Generate a 2-xform random.
|
||||||
Random(mutation, useVars, sym, 2, maxVars);
|
Random(mutation, useVars, sym, 2, maxVars);
|
||||||
//Which xform to mutate?
|
//Which xform to mutate?
|
||||||
modXform = m_Rand.Rand() % ember.TotalXformCount();
|
modXform = m_Rand.Rand(ember.TotalXformCount());
|
||||||
auto xform1 = ember.GetTotalXform(modXform);
|
auto xform1 = ember.GetTotalXform(modXform);
|
||||||
auto xform2 = mutation.GetTotalXform(0);
|
auto xform2 = mutation.GetTotalXform(0);
|
||||||
os << "mutate xform " << modXform << " coefs";
|
os << "mutate xform " << modXform << " coefs";
|
||||||
@ -280,7 +280,7 @@ public:
|
|||||||
else if (mode == eMutateMode::MUTATE_POST_XFORMS)
|
else if (mode == eMutateMode::MUTATE_POST_XFORMS)
|
||||||
{
|
{
|
||||||
bool same = (m_Rand.Rand() & 3) > 0;//25% chance of using the same post for all of them.
|
bool same = (m_Rand.Rand() & 3) > 0;//25% chance of using the same post for all of them.
|
||||||
size_t b = 1 + m_Rand.Rand() % 6;
|
size_t b = 1 + m_Rand.Rand(6);
|
||||||
os << "mutate post xforms " << b << (same ? " same" : "");
|
os << "mutate post xforms " << b << (same ? " same" : "");
|
||||||
|
|
||||||
for (size_t i = 0; i < ember.TotalXformCount(); i++)
|
for (size_t i = 0; i < ember.TotalXformCount(); i++)
|
||||||
@ -387,7 +387,7 @@ public:
|
|||||||
}
|
}
|
||||||
else if (mode == eMutateMode::MUTATE_DELETE_XFORM)
|
else if (mode == eMutateMode::MUTATE_DELETE_XFORM)
|
||||||
{
|
{
|
||||||
size_t nx = m_Rand.Rand() % ember.TotalXformCount();
|
size_t nx = m_Rand.Rand(ember.TotalXformCount());
|
||||||
os << "mutate delete xform " << nx;
|
os << "mutate delete xform " << nx;
|
||||||
|
|
||||||
if (ember.TotalXformCount() > 1)
|
if (ember.TotalXformCount() > 1)
|
||||||
@ -626,7 +626,7 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ember.AddXforms(xformDistrib[m_Rand.Rand() % Vlen(xformDistrib)]);
|
ember.AddXforms(xformDistrib[m_Rand.Rand(Vlen(xformDistrib))]);
|
||||||
addfinal = m_Rand.Frand01<T>() < T(0.15);//Add a final xform 15% of the time.
|
addfinal = m_Rand.Frand01<T>() < T(0.15);//Add a final xform 15% of the time.
|
||||||
|
|
||||||
if (addfinal)
|
if (addfinal)
|
||||||
@ -639,7 +639,7 @@ public:
|
|||||||
|
|
||||||
//If useVars is empty, randomly choose one to use or decide to use multiple.
|
//If useVars is empty, randomly choose one to use or decide to use multiple.
|
||||||
if (useVars.empty())
|
if (useVars.empty())
|
||||||
var = m_Rand.RandBit() ? m_Rand.Rand() % varCount : -1;
|
var = m_Rand.RandBit() ? m_Rand.Rand(varCount) : -1;
|
||||||
else
|
else
|
||||||
var = -2;
|
var = -2;
|
||||||
|
|
||||||
@ -689,7 +689,7 @@ public:
|
|||||||
else if (multid && var == -1)
|
else if (multid && var == -1)
|
||||||
{
|
{
|
||||||
if (xform->TotalVariationCount() < maxVars)
|
if (xform->TotalVariationCount() < maxVars)
|
||||||
xform->AddVariation(m_VariationList->GetVariation(m_Rand.Rand() % varCount)->Copy());//Choose a random var for this xform.
|
xform->AddVariation(m_VariationList->GetVariation(m_Rand.Rand(varCount))->Copy());//Choose a random var for this xform.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -722,7 +722,7 @@ public:
|
|||||||
if (var != -2)
|
if (var != -2)
|
||||||
{
|
{
|
||||||
//Pick a random variation and use a random weight from 0-1.
|
//Pick a random variation and use a random weight from 0-1.
|
||||||
Variation<T>* v = m_VariationList->GetVariationCopy(static_cast<size_t>(m_Rand.Rand() % varCount), m_Rand.Frand<T>(T(0.001), 1));
|
Variation<T>* v = m_VariationList->GetVariationCopy(static_cast<size_t>(m_Rand.Rand(varCount)), m_Rand.Frand<T>(T(0.001), 1));
|
||||||
|
|
||||||
if (v && !xform->AddVariation(v))
|
if (v && !xform->AddVariation(v))
|
||||||
delete v;//It already existed and therefore was not added.
|
delete v;//It already existed and therefore was not added.
|
||||||
@ -730,7 +730,7 @@ public:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Pick a random variation from the suppled IDs and use a random weight from 0-1.
|
//Pick a random variation from the suppled IDs and use a random weight from 0-1.
|
||||||
Variation<T>* v = m_VariationList->GetVariationCopy(useVars[m_Rand.Rand() % useVars.size()], m_Rand.Frand<T>(T(0.001), 1));
|
Variation<T>* v = m_VariationList->GetVariationCopy(useVars[m_Rand.Rand(useVars.size())], m_Rand.Frand<T>(T(0.001), 1));
|
||||||
|
|
||||||
if (v && !xform->AddVariation(v))
|
if (v && !xform->AddVariation(v))
|
||||||
delete v;
|
delete v;
|
||||||
@ -760,12 +760,12 @@ public:
|
|||||||
if (var != -2)
|
if (var != -2)
|
||||||
{
|
{
|
||||||
//Pick a random variation and use a random weight from 0-1.
|
//Pick a random variation and use a random weight from 0-1.
|
||||||
xform->AddVariation(m_VariationList->GetVariationCopy(static_cast<size_t>(m_Rand.Rand() % varCount), m_Rand.Frand<T>(T(0.001), 1)));
|
xform->AddVariation(m_VariationList->GetVariationCopy(static_cast<size_t>(m_Rand.Rand(varCount)), m_Rand.Frand<T>(T(0.001), 1)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Pick a random variation from the suppled IDs and use a random weight from 0-1.
|
//Pick a random variation from the suppled IDs and use a random weight from 0-1.
|
||||||
xform->AddVariation(m_VariationList->GetVariationCopy(useVars[m_Rand.Rand() % useVars.size()], m_Rand.Frand<T>(T(0.001), 1)));
|
xform->AddVariation(m_VariationList->GetVariationCopy(useVars[m_Rand.Rand(useVars.size())], m_Rand.Frand<T>(T(0.001), 1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -779,7 +779,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Randomly add symmetry (but not if we've already added a final xform).
|
//Randomly add symmetry (but not if we've already added a final xform).
|
||||||
if (sym || (!(m_Rand.Rand() % 4) && !addfinal))
|
if (sym || (!(m_Rand.Rand(4)) && !addfinal))
|
||||||
ember.AddSymmetry(sym, m_Rand);
|
ember.AddSymmetry(sym, m_Rand);
|
||||||
else
|
else
|
||||||
ember.m_Symmetry = 0;
|
ember.m_Symmetry = 0;
|
||||||
@ -932,7 +932,7 @@ public:
|
|||||||
|
|
||||||
while (ntries++ < 100)
|
while (ntries++ < 100)
|
||||||
{
|
{
|
||||||
size_t i = m_Rand.Rand() % ember.TotalXformCount();
|
size_t i = m_Rand.Rand(ember.TotalXformCount());
|
||||||
|
|
||||||
if (i != excluded)
|
if (i != excluded)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
#include "EmberPch.h"
|
#include "EmberPch.h"
|
||||||
#include "VariationList.h"
|
#include "VariationList.h"
|
||||||
#include "Variations01.h"
|
#ifdef FLAM3_COMPAT
|
||||||
|
#include "Variations01_flam3_compat.h"//Do this instead if you want full compatibility with flam3.
|
||||||
|
#else
|
||||||
|
#include "Variations01.h"
|
||||||
|
#endif
|
||||||
#include "Variations02.h"
|
#include "Variations02.h"
|
||||||
#include "Variations03.h"
|
#include "Variations03.h"
|
||||||
#include "Variations04.h"
|
#include "Variations04.h"
|
||||||
|
7094
Source/Ember/Variations01_flam3_compat.h
Normal file
7094
Source/Ember/Variations01_flam3_compat.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1777,7 +1777,7 @@ public:
|
|||||||
T temp = (helper.m_PrecalcAtanyx + M_2PI * rand.Rand(uint(m_AbsN))) / m_N;
|
T temp = (helper.m_PrecalcAtanyx + M_2PI * rand.Rand(uint(m_AbsN))) / m_N;
|
||||||
helper.Out.x = r * std::cos(temp);
|
helper.Out.x = r * std::cos(temp);
|
||||||
helper.Out.y = r * std::sin(temp);
|
helper.Out.y = r * std::sin(temp);
|
||||||
helper.Out.z = r * helper.In.z / (helper.m_PrecalcSqrtSumSquares * m_AbsN);
|
helper.Out.z = r * helper.In.z / Zeps(helper.m_PrecalcSqrtSumSquares * m_AbsN);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual string OpenCLString() const override
|
virtual string OpenCLString() const override
|
||||||
@ -1796,11 +1796,16 @@ public:
|
|||||||
<< "\n"
|
<< "\n"
|
||||||
<< "\t\tvOut.x = r * cos(temp);\n"
|
<< "\t\tvOut.x = r * cos(temp);\n"
|
||||||
<< "\t\tvOut.y = r * sin(temp);\n"
|
<< "\t\tvOut.y = r * sin(temp);\n"
|
||||||
<< "\t\tvOut.z = r * vIn.z / (precalcSqrtSumSquares * " << absn << ");\n"
|
<< "\t\tvOut.z = r * vIn.z / Zeps(precalcSqrtSumSquares * " << absn << ");\n"
|
||||||
<< "\t}\n";
|
<< "\t}\n";
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual vector<string> OpenCLGlobalFuncNames() const override
|
||||||
|
{
|
||||||
|
return vector<string> { "Zeps" };
|
||||||
|
}
|
||||||
|
|
||||||
virtual void Precalc() override
|
virtual void Precalc() override
|
||||||
{
|
{
|
||||||
m_AbsN = std::abs(m_N);
|
m_AbsN = std::abs(m_N);
|
||||||
|
@ -859,7 +859,7 @@ private:
|
|||||||
if (params.ExactCalc == 1)
|
if (params.ExactCalc == 1)
|
||||||
angXY = rand.Frand01<T>() * M_2PI;
|
angXY = rand.Frand01<T>() * M_2PI;
|
||||||
else
|
else
|
||||||
angXY = (std::atan(params.ArcTan1 * (rand.Frand01<T>() - T(0.5))) / params.ArcTan2 + T(0.5) + T(rand.Rand() % glm::uint(params.NumEdges))) * params.MidAngle;
|
angXY = (std::atan(params.ArcTan1 * (rand.Frand01<T>() - T(0.5))) / params.ArcTan2 + T(0.5) + T(rand.Rand(glm::uint(params.NumEdges)))) * params.MidAngle;
|
||||||
|
|
||||||
sincos(angXY, ¶ms.X, ¶ms.Y);
|
sincos(angXY, ¶ms.X, ¶ms.Y);
|
||||||
angMem = angXY;
|
angMem = angXY;
|
||||||
|
@ -174,7 +174,7 @@ static const char* RandFunctionString =
|
|||||||
"\n"
|
"\n"
|
||||||
"inline uint MwcNextRange(uint2* s, uint val)\n"
|
"inline uint MwcNextRange(uint2* s, uint val)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return (val == 0) ? MwcNext(s) : (MwcNext(s) % val);\n"
|
" return (val == 0) ? MwcNext(s) : (uint)(((ulong)MwcNext(s) * (ulong)val) >> 32);\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"\n"
|
"\n"
|
||||||
"inline real_t MwcNext01(uint2* s)\n"
|
"inline real_t MwcNext01(uint2* s)\n"
|
||||||
|
@ -647,7 +647,9 @@ static bool StripsRender(RendererBase* renderer, Ember<T>& ember, vector<v4F>& f
|
|||||||
ember.m_Quality /= strips;
|
ember.m_Quality /= strips;
|
||||||
ember.m_FinalRasH = realHeight;
|
ember.m_FinalRasH = realHeight;
|
||||||
ember.m_CenterY = centerY;
|
ember.m_CenterY = centerY;
|
||||||
renderer->SetEmber(ember);//Further processing will require the dimensions to match the original ember, so re-assign.
|
|
||||||
|
if (strips > 1)
|
||||||
|
renderer->SetEmber(ember);//Further processing will require the dimensions to match the original ember, so re-assign.
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
allStripsFinished(ember);
|
allStripsFinished(ember);
|
||||||
|
@ -625,7 +625,7 @@ bool EmberGenome(int argc, _TCHAR* argv[], EmberOptions& opt)
|
|||||||
if (opt.CloneAction() != "")
|
if (opt.CloneAction() != "")
|
||||||
os << " " << opt.CloneAction();
|
os << " " << opt.CloneAction();
|
||||||
|
|
||||||
selp0 = embers[rand.Rand() % embers.size()];
|
selp0 = embers[rand.Rand(embers.size())];
|
||||||
save = selp0;
|
save = selp0;
|
||||||
aselp0 = &selp0;
|
aselp0 = &selp0;
|
||||||
aselp1 = nullptr;
|
aselp1 = nullptr;
|
||||||
@ -643,7 +643,7 @@ bool EmberGenome(int argc, _TCHAR* argv[], EmberOptions& opt)
|
|||||||
|
|
||||||
if (doMutate)
|
if (doMutate)
|
||||||
{
|
{
|
||||||
selp0 = embers[rand.Rand() % embers.size()];
|
selp0 = embers[rand.Rand(embers.size())];
|
||||||
orig = selp0;
|
orig = selp0;
|
||||||
aselp0 = &selp0;
|
aselp0 = &selp0;
|
||||||
aselp1 = nullptr;
|
aselp1 = nullptr;
|
||||||
@ -685,8 +685,8 @@ bool EmberGenome(int argc, _TCHAR* argv[], EmberOptions& opt)
|
|||||||
}
|
}
|
||||||
else if (doCross0)
|
else if (doCross0)
|
||||||
{
|
{
|
||||||
i0 = rand.Rand() % embers.size();
|
i0 = rand.Rand(embers.size());
|
||||||
i1 = rand.Rand() % embers2.size();
|
i1 = rand.Rand(embers2.size());
|
||||||
selp0 = embers[i0];
|
selp0 = embers[i0];
|
||||||
selp1 = embers2[i1];
|
selp1 = embers2[i1];
|
||||||
aselp0 = &selp0;
|
aselp0 = &selp0;
|
||||||
|
@ -2240,42 +2240,79 @@ int _tmain(int argc, _TCHAR* argv[])
|
|||||||
{
|
{
|
||||||
//int i;
|
//int i;
|
||||||
bool b = true;
|
bool b = true;
|
||||||
|
size_t times = 1'000'000'001;
|
||||||
|
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
|
||||||
|
std::vector<unsigned int> vec(16, 0);
|
||||||
Timing t(4);
|
Timing t(4);
|
||||||
/* vector<Ember<float>> fv;
|
/*
|
||||||
vector<Ember<double>> dv;
|
for (size_t i = 1; i < times; i++)
|
||||||
list<Ember<float>> fl;
|
{
|
||||||
list<Ember<double>> dl;
|
auto res = rand.Rand() % i;
|
||||||
int w = 1000, h = 1000;
|
vec[res & 15]++;
|
||||||
string filename = ".\\testexr.exr";
|
}
|
||||||
vector<Rgba> pixels;
|
|
||||||
pixels.resize(w * h);
|
|
||||||
|
|
||||||
for (auto& pix : pixels)
|
t.Toc("rand mod");
|
||||||
{
|
|
||||||
pix.r = 1.0;
|
|
||||||
pix.b = 0.0;
|
|
||||||
pix.a = 1.0;
|
|
||||||
//pix.r = std::numeric_limits<float>::max();
|
|
||||||
}
|
|
||||||
|
|
||||||
writeRgba1(filename.c_str(), pixels.data(), w, h);
|
for (auto& it : vec)
|
||||||
TestFuncs();
|
{
|
||||||
string line = "title=\"cj_aerie\" smooth=no", delim = " =\"";
|
cout << it / (double)times << endl;
|
||||||
auto vec = Split(line, delim, true);
|
it = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& s : vec) cout << s << endl;
|
cout << "\n\n";
|
||||||
|
t.Tic();
|
||||||
|
|
||||||
line = "index=0 color=2177354", delim = " =";
|
for (size_t i = 1; i < times; i++)
|
||||||
vec = Split(line, delim, true);
|
{
|
||||||
|
//auto res = (uint)(((size_t)rand.Rand() * i) >> 32);
|
||||||
|
auto res = rand.Rand(i);
|
||||||
|
vec[res & 15]++;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& s : vec) cout << s << endl;
|
t.Toc("rand mult shift");
|
||||||
|
|
||||||
|
for (auto& it : vec)
|
||||||
|
{
|
||||||
|
cout << it / (double)times << endl;
|
||||||
|
it = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
vector<Ember<float>> fv;
|
||||||
|
vector<Ember<double>> dv;
|
||||||
|
list<Ember<float>> fl;
|
||||||
|
list<Ember<double>> dl;
|
||||||
|
int w = 1000, h = 1000;
|
||||||
|
string filename = ".\\testexr.exr";
|
||||||
|
vector<Rgba> pixels;
|
||||||
|
pixels.resize(w * h);
|
||||||
|
|
||||||
|
for (auto& pix : pixels)
|
||||||
|
{
|
||||||
|
pix.r = 1.0;
|
||||||
|
pix.b = 0.0;
|
||||||
|
pix.a = 1.0;
|
||||||
|
//pix.r = std::numeric_limits<float>::max();
|
||||||
|
}
|
||||||
|
|
||||||
|
writeRgba1(filename.c_str(), pixels.data(), w, h);
|
||||||
|
TestFuncs();
|
||||||
|
string line = "title=\"cj_aerie\" smooth=no", delim = " =\"";
|
||||||
|
auto vec = Split(line, delim, true);
|
||||||
|
|
||||||
|
for (auto& s : vec) cout << s << endl;
|
||||||
|
|
||||||
|
line = "index=0 color=2177354", delim = " =";
|
||||||
|
vec = Split(line, delim, true);
|
||||||
|
|
||||||
|
for (auto& s : vec) cout << s << endl;
|
||||||
|
|
||||||
|
|
||||||
EmberContainerTester<float>::TestEmberContainer(fv);
|
EmberContainerTester<float>::TestEmberContainer(fv);
|
||||||
EmberContainerTester<double>::TestEmberContainer(dv);
|
EmberContainerTester<double>::TestEmberContainer(dv);
|
||||||
EmberContainerTester<float>::TestEmberContainer(fl);
|
EmberContainerTester<float>::TestEmberContainer(fl);
|
||||||
EmberContainerTester<double>::TestEmberContainer(dl);
|
EmberContainerTester<double>::TestEmberContainer(dl);
|
||||||
CopyCont(fv, fl);
|
CopyCont(fv, fl);
|
||||||
*/
|
*/
|
||||||
//QTIsaac<ISAAC_SIZE, ISAAC_INT> rand(1, 2, 3);
|
//QTIsaac<ISAAC_SIZE, ISAAC_INT> rand(1, 2, 3);
|
||||||
//mt19937 meow(1729);
|
//mt19937 meow(1729);
|
||||||
|
@ -163,6 +163,27 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(QWidget* p, Qt::WindowF
|
|||||||
m_SupersampleSpin->setValue(m_Settings->FinalSupersample());
|
m_SupersampleSpin->setValue(m_Settings->FinalSupersample());
|
||||||
m_StripsSpin->setValue(int(m_Settings->FinalStrips()));
|
m_StripsSpin->setValue(int(m_Settings->FinalStrips()));
|
||||||
Scale(eScaleType(m_Settings->FinalScale()));
|
Scale(eScaleType(m_Settings->FinalScale()));
|
||||||
|
auto menu = new QMenu(this);
|
||||||
|
auto add10 = new QAction("Add 10% quality", this); add10->setProperty("tag", QVariant(0.10));
|
||||||
|
auto add25 = new QAction("Add 25% quality", this); add25->setProperty("tag", QVariant(0.25));
|
||||||
|
auto add50 = new QAction("Add 50% quality", this); add50->setProperty("tag", QVariant(0.50));
|
||||||
|
auto add100 = new QAction("Add 100% quality", this); add100->setProperty("tag", QVariant(1.0));
|
||||||
|
auto add200 = new QAction("Add 200% quality", this); add200->setProperty("tag", QVariant(2.0));
|
||||||
|
menu->addAction(add10);
|
||||||
|
menu->addAction(add25);
|
||||||
|
menu->addAction(add50);
|
||||||
|
menu->addAction(add100);
|
||||||
|
menu->addAction(add200);
|
||||||
|
ui.FinalRenderBumpQualityStartButton->setMenu(menu);
|
||||||
|
ui.FinalRenderBumpQualityStartButton->setProperty("tag", add25->property("tag"));
|
||||||
|
ui.FinalRenderBumpQualityStartButton->setText(add25->text());
|
||||||
|
ui.FinalRenderBumpQualityStartButton->setEnabled(false);
|
||||||
|
connect(ui.FinalRenderBumpQualityStartButton, SIGNAL(clicked()), this, SLOT(OnQualityBumpClicked()));
|
||||||
|
connect(add10, SIGNAL(triggered()), this, SLOT(OnQualityBumpClicked()));
|
||||||
|
connect(add25, SIGNAL(triggered()), this, SLOT(OnQualityBumpClicked()));
|
||||||
|
connect(add50, SIGNAL(triggered()), this, SLOT(OnQualityBumpClicked()));
|
||||||
|
connect(add100, SIGNAL(triggered()), this, SLOT(OnQualityBumpClicked()));
|
||||||
|
connect(add200, SIGNAL(triggered()), this, SLOT(OnQualityBumpClicked()));
|
||||||
int index = 0;
|
int index = 0;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
@ -225,6 +246,7 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(QWidget* p, Qt::WindowF
|
|||||||
w = SetTabOrder(this, w, m_PrefixEdit);
|
w = SetTabOrder(this, w, m_PrefixEdit);
|
||||||
w = SetTabOrder(this, w, m_SuffixEdit);
|
w = SetTabOrder(this, w, m_SuffixEdit);
|
||||||
w = SetTabOrder(this, w, ui.FinalRenderTextOutput);
|
w = SetTabOrder(this, w, ui.FinalRenderTextOutput);
|
||||||
|
w = SetTabOrder(this, w, ui.FinalRenderBumpQualityStartButton);
|
||||||
w = SetTabOrder(this, w, ui.FinalRenderStartButton);
|
w = SetTabOrder(this, w, ui.FinalRenderStartButton);
|
||||||
w = SetTabOrder(this, w, ui.FinalRenderPauseButton);
|
w = SetTabOrder(this, w, ui.FinalRenderPauseButton);
|
||||||
w = SetTabOrder(this, w, ui.FinalRenderStopButton);
|
w = SetTabOrder(this, w, ui.FinalRenderStopButton);
|
||||||
@ -435,6 +457,7 @@ void FractoriumFinalRenderDialog::OnDoAllCheckBoxStateChanged(int state)
|
|||||||
ui.FinalRenderDoSequenceCheckBox->setChecked(false);
|
ui.FinalRenderDoSequenceCheckBox->setChecked(false);
|
||||||
|
|
||||||
ui.FinalRenderDoSequenceCheckBox->setEnabled(ui.FinalRenderDoAllCheckBox->isChecked());
|
ui.FinalRenderDoSequenceCheckBox->setEnabled(ui.FinalRenderDoAllCheckBox->isChecked());
|
||||||
|
ui.FinalRenderBumpQualityStartButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -475,6 +498,8 @@ void FractoriumFinalRenderDialog::OnApplyAllCheckBoxStateChanged(int state)
|
|||||||
{
|
{
|
||||||
if (state && m_Controller.get())
|
if (state && m_Controller.get())
|
||||||
m_Controller->SyncGuiToEmbers();
|
m_Controller->SyncGuiToEmbers();
|
||||||
|
|
||||||
|
ui.FinalRenderBumpQualityStartButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -725,6 +750,32 @@ void FractoriumFinalRenderDialog::OnSuffixChanged(const QString& s)
|
|||||||
Path(m_Controller->ComposePath(m_Controller->Name()));
|
Path(m_Controller->ComposePath(m_Controller->Name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Increase the quality of the last render and start rendering again.
|
||||||
|
/// Note this is only when rendering a single image with no strips.
|
||||||
|
/// </summary>
|
||||||
|
void FractoriumFinalRenderDialog::OnQualityBumpClicked()
|
||||||
|
{
|
||||||
|
auto act = qobject_cast<QAction*>(sender());
|
||||||
|
auto tbtn = qobject_cast<QToolButton*>(sender());
|
||||||
|
|
||||||
|
if (tbtn)
|
||||||
|
{
|
||||||
|
if (m_Controller.get())
|
||||||
|
{
|
||||||
|
double d = tbtn->property("tag").toDouble();
|
||||||
|
m_QualitySpin->SetValueStealth(std::ceil(Quality() + (Quality() * d)));
|
||||||
|
m_Controller->BumpQualityRender(d);
|
||||||
|
tbtn->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (act)
|
||||||
|
{
|
||||||
|
ui.FinalRenderBumpQualityStartButton->setText(act->text());
|
||||||
|
ui.FinalRenderBumpQualityStartButton->setProperty("tag", act->property("tag"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start the render process.
|
/// Start the render process.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -789,7 +840,7 @@ void FractoriumFinalRenderDialog::Pause(bool paused)
|
|||||||
/// <param name="e">The event</param>
|
/// <param name="e">The event</param>
|
||||||
void FractoriumFinalRenderDialog::showEvent(QShowEvent* e)
|
void FractoriumFinalRenderDialog::showEvent(QShowEvent* e)
|
||||||
{
|
{
|
||||||
if (m_Controller.get() && m_Controller->m_Run)//On Linux, this event will be called when the main window minimized/maximized while rendering, so filter it out.
|
if (m_Controller.get())//On Linux, this event will be called when the main window minimized/maximized, so filter it out if the window and controller have already been created.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString firstfile;
|
QString firstfile;
|
||||||
@ -947,6 +998,7 @@ bool FractoriumFinalRenderDialog::SetMemory()
|
|||||||
else
|
else
|
||||||
ui.FinalRenderTextOutput->clear();
|
ui.FinalRenderTextOutput->clear();
|
||||||
|
|
||||||
|
ui.FinalRenderBumpQualityStartButton->setEnabled(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +111,7 @@ public slots:
|
|||||||
void OnExtIndexChanged(int d);
|
void OnExtIndexChanged(int d);
|
||||||
void OnPrefixChanged(const QString& s);
|
void OnPrefixChanged(const QString& s);
|
||||||
void OnSuffixChanged(const QString& s);
|
void OnSuffixChanged(const QString& s);
|
||||||
|
void OnQualityBumpClicked();
|
||||||
void OnRenderClicked(bool checked);
|
void OnRenderClicked(bool checked);
|
||||||
void OnPauseClicked(bool checked);
|
void OnPauseClicked(bool checked);
|
||||||
void OnCancelRenderClicked(bool checked);
|
void OnCancelRenderClicked(bool checked);
|
||||||
|
@ -1192,6 +1192,25 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="FinalRenderBumpQualityStartButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Add Quality</string>
|
||||||
|
</property>
|
||||||
|
<property name="popupMode">
|
||||||
|
<enum>QToolButton::MenuButtonPopup</enum>
|
||||||
|
</property>
|
||||||
|
<property name="toolButtonStyle">
|
||||||
|
<enum>Qt::ToolButtonTextOnly</enum>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="arrowType">
|
||||||
|
<enum>Qt::NoArrow</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="FinalRenderStartButton">
|
<widget class="QPushButton" name="FinalRenderStartButton">
|
||||||
<property name="focusPolicy">
|
<property name="focusPolicy">
|
||||||
|
@ -292,9 +292,10 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
|
|||||||
}
|
}
|
||||||
else if (m_Renderer.get())//Render a single image.
|
else if (m_Renderer.get())//Render a single image.
|
||||||
{
|
{
|
||||||
|
bool isBump = m_IsQualityBump && m_GuiState.m_Strips == 1;//Should never get called with m_IsQualityBump otherwise, but check one last time to be safe.
|
||||||
m_ImageCount = 1;
|
m_ImageCount = 1;
|
||||||
m_Ember->m_TemporalSamples = 1;
|
m_Ember->m_TemporalSamples = 1;
|
||||||
m_Renderer->SetEmber(*m_Ember);
|
m_Renderer->SetEmber(*m_Ember, isBump ? eProcessAction::KEEP_ITERATING : eProcessAction::FULL_RENDER);
|
||||||
m_Renderer->PrepFinalAccumVector(m_FinalImage);//Must manually call this first because it could be erroneously made smaller due to strips if called inside Renderer::Run().
|
m_Renderer->PrepFinalAccumVector(m_FinalImage);//Must manually call this first because it could be erroneously made smaller due to strips if called inside Renderer::Run().
|
||||||
m_Stats.Clear();
|
m_Stats.Clear();
|
||||||
Memset(m_FinalImage);
|
Memset(m_FinalImage);
|
||||||
@ -416,6 +417,35 @@ bool FinalRenderEmberController<T>::Render()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Increase the quality of the last render and start rendering again.
|
||||||
|
/// Note this is only when rendering a single image with no strips.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="d">The amount to increase the quality by, expressed as a decimal percentage. Eg: 0.5 means to increase by 50%.</param>
|
||||||
|
/// <returns>True if nothing went wrong, else false.</returns>
|
||||||
|
template <typename T>
|
||||||
|
bool FinalRenderEmberController<T>::BumpQualityRender(double d)
|
||||||
|
{
|
||||||
|
m_Ember->m_Quality += std::ceil(m_Ember->m_Quality * d);
|
||||||
|
m_Renderer->SetEmber(*m_Ember, eProcessAction::KEEP_ITERATING, true);
|
||||||
|
QString filename = m_FinalRenderDialog->Path();
|
||||||
|
|
||||||
|
if (filename == "")
|
||||||
|
{
|
||||||
|
m_Fractorium->ShowCritical("File Error", "Please enter a valid path and filename for the output.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_IsQualityBump = true;
|
||||||
|
auto iterCount = m_Renderer->TotalIterCount(1);
|
||||||
|
m_FinalRenderDialog->ui.FinalRenderParamsTable->item(m_FinalRenderDialog->m_ItersCellIndex, 1)->setText(ToString<qulonglong>(iterCount));
|
||||||
|
m_FinalRenderDialog->ui.FinalRenderTextOutput->setText("Preparing all parameters.\n");
|
||||||
|
m_Result = QtConcurrent::run(m_FinalRenderFunc);
|
||||||
|
m_Settings->sync();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stop rendering and initialize a new renderer, using the specified type and the options on the final render dialog.
|
/// Stop rendering and initialize a new renderer, using the specified type and the options on the final render dialog.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -803,6 +833,7 @@ template<typename T>
|
|||||||
void FinalRenderEmberController<T>::HandleFinishedProgress()
|
void FinalRenderEmberController<T>::HandleFinishedProgress()
|
||||||
{
|
{
|
||||||
auto finishedCountCached = m_FinishedImageCount.load();//Make sure to use the same value throughout this function even if the atomic is changing.
|
auto finishedCountCached = m_FinishedImageCount.load();//Make sure to use the same value throughout this function even if the atomic is changing.
|
||||||
|
bool doAll = m_GuiState.m_DoAll && m_EmberFile.Size() > 1;
|
||||||
|
|
||||||
if (m_FinishedImageCount.load() != m_ImageCount)
|
if (m_FinishedImageCount.load() != m_ImageCount)
|
||||||
ResetProgress(false);
|
ResetProgress(false);
|
||||||
@ -811,6 +842,7 @@ void FinalRenderEmberController<T>::HandleFinishedProgress()
|
|||||||
|
|
||||||
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderTotalProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int((float(finishedCountCached) / float(m_ImageCount)) * 100)));
|
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderTotalProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int((float(finishedCountCached) / float(m_ImageCount)) * 100)));
|
||||||
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderImageCountLabel, "setText", Qt::QueuedConnection, Q_ARG(const QString&, ToString<qulonglong>(finishedCountCached) + " / " + ToString<qulonglong>(m_ImageCount)));
|
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderImageCountLabel, "setText", Qt::QueuedConnection, Q_ARG(const QString&, ToString<qulonglong>(finishedCountCached) + " / " + ToString<qulonglong>(m_ImageCount)));
|
||||||
|
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderBumpQualityStartButton, "setEnabled", Qt::QueuedConnection, Q_ARG(bool, !doAll && m_Renderer.get() && m_GuiState.m_Strips == 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -69,6 +69,7 @@ public:
|
|||||||
virtual tuple<size_t, size_t, size_t> SyncAndComputeMemory() { return tuple<size_t, size_t, size_t>(0, 0, 0); }
|
virtual tuple<size_t, size_t, size_t> SyncAndComputeMemory() { return tuple<size_t, size_t, size_t>(0, 0, 0); }
|
||||||
virtual double OriginalAspect() { return 1; }
|
virtual double OriginalAspect() { return 1; }
|
||||||
virtual QString ComposePath(const QString& name) { return ""; }
|
virtual QString ComposePath(const QString& name) { return ""; }
|
||||||
|
virtual bool BumpQualityRender(double d) { return false; }
|
||||||
virtual void CancelRender() { }
|
virtual void CancelRender() { }
|
||||||
virtual QString CheckMemory(const tuple<size_t, size_t, size_t>& p) { return ""; }
|
virtual QString CheckMemory(const tuple<size_t, size_t, size_t>& p) { return ""; }
|
||||||
|
|
||||||
@ -78,6 +79,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool m_Run = false;
|
bool m_Run = false;
|
||||||
|
bool m_IsQualityBump = false;
|
||||||
size_t m_ImageCount = 0;
|
size_t m_ImageCount = 0;
|
||||||
std::atomic<size_t> m_FinishedImageCount;
|
std::atomic<size_t> m_FinishedImageCount;
|
||||||
|
|
||||||
@ -114,6 +116,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
virtual void SetEmber(size_t index, bool verbatim) override;
|
virtual void SetEmber(size_t index, bool verbatim) override;
|
||||||
virtual bool Render() override;
|
virtual bool Render() override;
|
||||||
|
virtual bool BumpQualityRender(double d) override;
|
||||||
virtual bool CreateRenderer(eRendererType renderType, const vector<pair<size_t, size_t>>& devices, bool updatePreviews, bool shared = true) override;
|
virtual bool CreateRenderer(eRendererType renderType, const vector<pair<size_t, size_t>>& devices, bool updatePreviews, bool shared = true) override;
|
||||||
virtual int ProgressFunc(Ember<T>& ember, void* foo, double fraction, int stage, double etaMs) override;
|
virtual int ProgressFunc(Ember<T>& ember, void* foo, double fraction, int stage, double etaMs) override;
|
||||||
virtual size_t Index() const override { return m_Ember->m_Index; }
|
virtual size_t Index() const override { return m_Ember->m_Index; }
|
||||||
|
@ -880,6 +880,7 @@ void Fractorium::SetTabOrders()
|
|||||||
w = SetTabOrder(this, w, ui.AddFinalXformButton);
|
w = SetTabOrder(this, w, ui.AddFinalXformButton);
|
||||||
w = SetTabOrder(this, w, m_XformWeightSpin);
|
w = SetTabOrder(this, w, m_XformWeightSpin);
|
||||||
w = SetTabOrder(this, w, m_XformWeightSpinnerButtonWidget->m_Button);
|
w = SetTabOrder(this, w, m_XformWeightSpinnerButtonWidget->m_Button);
|
||||||
|
w = SetTabOrder(this, w, m_XformNameEdit);
|
||||||
w = SetTabOrder(this, m_XformColorIndexSpin, ui.XformColorScroll);//Xforms color.
|
w = SetTabOrder(this, m_XformColorIndexSpin, ui.XformColorScroll);//Xforms color.
|
||||||
w = SetTabOrder(this, w, ui.RandomColorIndicesButton);
|
w = SetTabOrder(this, w, ui.RandomColorIndicesButton);
|
||||||
w = SetTabOrder(this, w, ui.ToggleColorIndicesButton);
|
w = SetTabOrder(this, w, ui.ToggleColorIndicesButton);
|
||||||
|
@ -255,7 +255,7 @@ public slots:
|
|||||||
void OnAddFinalXformButtonClicked(bool checked);
|
void OnAddFinalXformButtonClicked(bool checked);
|
||||||
void OnXformWeightChanged(double d);
|
void OnXformWeightChanged(double d);
|
||||||
void OnEqualWeightButtonClicked(bool checked);
|
void OnEqualWeightButtonClicked(bool checked);
|
||||||
void OnXformNameChanged(int row, int col);
|
void OnXformNameChanged(const QString& s);
|
||||||
void OnXformAnimateCheckBoxStateChanged(int state);
|
void OnXformAnimateCheckBoxStateChanged(int state);
|
||||||
|
|
||||||
//Xforms Affine.
|
//Xforms Affine.
|
||||||
@ -504,6 +504,7 @@ private:
|
|||||||
//Xforms.
|
//Xforms.
|
||||||
DoubleSpinBox* m_XformWeightSpin;
|
DoubleSpinBox* m_XformWeightSpin;
|
||||||
SpinnerLabelButtonWidget* m_XformWeightSpinnerButtonWidget;
|
SpinnerLabelButtonWidget* m_XformWeightSpinnerButtonWidget;
|
||||||
|
QLineEdit* m_XformNameEdit;
|
||||||
QFormLayout* m_XformsSelectionLayout;
|
QFormLayout* m_XformsSelectionLayout;
|
||||||
vector<QCheckBox*> m_XformSelections;
|
vector<QCheckBox*> m_XformSelections;
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ public:
|
|||||||
virtual void CurrentXformComboChanged(int index) { }
|
virtual void CurrentXformComboChanged(int index) { }
|
||||||
virtual void XformWeightChanged(double d) { }
|
virtual void XformWeightChanged(double d) { }
|
||||||
virtual void EqualizeWeights() { }
|
virtual void EqualizeWeights() { }
|
||||||
virtual void XformNameChanged(int row, int col) { }
|
virtual void XformNameChanged(const QString& s) { }
|
||||||
virtual void XformAnimateChanged(int state) { }
|
virtual void XformAnimateChanged(int state) { }
|
||||||
virtual void FillXforms(int index = 0) { }
|
virtual void FillXforms(int index = 0) { }
|
||||||
virtual void UpdateXformName(int index) { }
|
virtual void UpdateXformName(int index) { }
|
||||||
@ -467,7 +467,7 @@ public:
|
|||||||
virtual void CurrentXformComboChanged(int index) override;
|
virtual void CurrentXformComboChanged(int index) override;
|
||||||
virtual void XformWeightChanged(double d) override;
|
virtual void XformWeightChanged(double d) override;
|
||||||
virtual void EqualizeWeights() override;
|
virtual void EqualizeWeights() override;
|
||||||
virtual void XformNameChanged(int row, int col) override;
|
virtual void XformNameChanged(const QString& s) override;
|
||||||
virtual void XformAnimateChanged(int state) override;
|
virtual void XformAnimateChanged(int state) override;
|
||||||
virtual void FillXforms(int index = 0) override;
|
virtual void FillXforms(int index = 0) override;
|
||||||
virtual void UpdateXformName(int index) override;
|
virtual void UpdateXformName(int index) override;
|
||||||
|
@ -613,14 +613,13 @@ void Fractorium::SetPaletteFileComboIndex(const string& filename)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void FractoriumEmberController<T>::ClearColorCurves(int i)
|
void FractoriumEmberController<T>::ClearColorCurves(int i)
|
||||||
{
|
{
|
||||||
Update([&]
|
UpdateAll([&](Ember<T>& ember, bool isMain)
|
||||||
{
|
{
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
m_Ember.m_Curves.Init();
|
ember.m_Curves.Init();
|
||||||
else
|
else
|
||||||
m_Ember.m_Curves.Init(i);
|
ember.m_Curves.Init(i);
|
||||||
|
}, true, m_Renderer->EarlyClip() ? eProcessAction::FILTER_AND_ACCUM : eProcessAction::ACCUM_ONLY, m_Fractorium->ApplyAll());
|
||||||
}, true, m_Renderer->EarlyClip() ? eProcessAction::FILTER_AND_ACCUM : eProcessAction::ACCUM_ONLY);
|
|
||||||
FillCurvesControl();
|
FillCurvesControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +206,10 @@ void Fractorium::FillXaosTable()
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void FractoriumEmberController<T>::ClearXaos()
|
void FractoriumEmberController<T>::ClearXaos()
|
||||||
{
|
{
|
||||||
Update([&] { m_Ember.ClearXaos(); });
|
UpdateAll([&](Ember<T>& ember, bool isMain)
|
||||||
|
{
|
||||||
|
ember.ClearXaos();
|
||||||
|
}, true, eProcessAction::FULL_RENDER, m_Fractorium->ApplyAll());
|
||||||
FillXaos();
|
FillXaos();
|
||||||
FillAppliedXaos();
|
FillAppliedXaos();
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,9 @@ void Fractorium::InitXformsUI()
|
|||||||
m_XformWeightSpinnerButtonWidget->setMaximumWidth(130);
|
m_XformWeightSpinnerButtonWidget->setMaximumWidth(130);
|
||||||
connect(m_XformWeightSpinnerButtonWidget->m_Button, SIGNAL(clicked(bool)), this, SLOT(OnEqualWeightButtonClicked(bool)), Qt::QueuedConnection);
|
connect(m_XformWeightSpinnerButtonWidget->m_Button, SIGNAL(clicked(bool)), this, SLOT(OnEqualWeightButtonClicked(bool)), Qt::QueuedConnection);
|
||||||
ui.XformWeightNameTable->setCellWidget(0, 0, m_XformWeightSpinnerButtonWidget);
|
ui.XformWeightNameTable->setCellWidget(0, 0, m_XformWeightSpinnerButtonWidget);
|
||||||
ui.XformWeightNameTable->setItem(0, 1, new QTableWidgetItem());
|
m_XformNameEdit = new QLineEdit(ui.XformWeightNameTable);
|
||||||
connect(ui.XformWeightNameTable, SIGNAL(cellChanged(int, int)), this, SLOT(OnXformNameChanged(int, int)), Qt::QueuedConnection);
|
ui.XformWeightNameTable->setCellWidget(0, 1, m_XformNameEdit);
|
||||||
|
connect(m_XformNameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(OnXformNameChanged(const QString&)), Qt::QueuedConnection);
|
||||||
ui.CurrentXformCombo->view()->setMinimumWidth(100);
|
ui.CurrentXformCombo->view()->setMinimumWidth(100);
|
||||||
ui.CurrentXformCombo->view()->setMaximumWidth(500);
|
ui.CurrentXformCombo->view()->setMaximumWidth(500);
|
||||||
//ui.CurrentXformCombo->view()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
//ui.CurrentXformCombo->view()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||||
@ -405,24 +406,23 @@ void Fractorium::OnEqualWeightButtonClicked(bool checked) { m_Controller->Equali
|
|||||||
/// Update the corresponding xform checkbox text with the name.
|
/// Update the corresponding xform checkbox text with the name.
|
||||||
/// Called when the user types in the name cell of the table.
|
/// Called when the user types in the name cell of the table.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="row">The row of the cell</param>
|
/// <param name="s">The text of the cell</param>
|
||||||
/// <param name="col">The col of the cell</param>
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void FractoriumEmberController<T>::XformNameChanged(int row, int col)
|
void FractoriumEmberController<T>::XformNameChanged(const QString& s)
|
||||||
{
|
{
|
||||||
bool forceFinal = m_Fractorium->HaveFinal();
|
bool forceFinal = m_Fractorium->HaveFinal();
|
||||||
UpdateXform([&] (Xform<T>* xform, size_t xfindex, size_t selIndex)
|
UpdateXform([&] (Xform<T>* xform, size_t xfindex, size_t selIndex)
|
||||||
{
|
{
|
||||||
xform->m_Name = m_Fractorium->ui.XformWeightNameTable->item(row, col)->text().toStdString();
|
xform->m_Name = s.toStdString();
|
||||||
XformCheckboxAt(int(xfindex), [&](QCheckBox * checkbox) { checkbox->setText(MakeXformCaption(xfindex)); });
|
XformCheckboxAt(int(xfindex), [&](QCheckBox * checkbox) { checkbox->setText(MakeXformCaption(xfindex)); });
|
||||||
}, eXformUpdate::UPDATE_CURRENT, false);
|
}, eXformUpdate::UPDATE_CURRENT, false);
|
||||||
FillSummary();//Manually update because this does not trigger a render, which is where this would normally be called.
|
FillSummary();//Manually update because this does not trigger a render, which is where this would normally be called.
|
||||||
m_Fractorium->FillXaosTable();
|
m_Fractorium->FillXaosTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fractorium::OnXformNameChanged(int row, int col)
|
void Fractorium::OnXformNameChanged(const QString& s)
|
||||||
{
|
{
|
||||||
m_Controller->XformNameChanged(row, col);
|
m_Controller->XformNameChanged(s);
|
||||||
m_Controller->UpdateXformName(ui.CurrentXformCombo->currentIndex());
|
m_Controller->UpdateXformName(ui.CurrentXformCombo->currentIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user