--User changes

-Edits will not save back to the file in memory on render completion when preview renderer is running.

--Bug fixes
 -dc_perlin was crashing on Nvidia when using SP.
 -Duplicate images were randomly getting added to the file in memory.
 -Crash when opening an Xml with less than 2 flames in it.

--Code changes
 -Use raw array of floats in OpenCL for perlin noise, rather than float3/double3.
 -Add some default cases to dc_perlin.
 -Redo singleton pattern yet again. Deriving from a templated Singleton<T> class was creating a separate instance per module. Now only one instance of each type will ever be created and it will be wrapped in a shared_ptr which guarantees its deletion as main() exits.
This commit is contained in:
mfeemster 2016-04-13 20:59:57 -07:00
parent 7715910362
commit 0fbea60026
29 changed files with 264 additions and 220 deletions

View File

@ -239,7 +239,7 @@ public:
ember.m_FinalXform.m_ColorSpeed = 0; ember.m_FinalXform.m_ColorSpeed = 0;
ember.m_FinalXform.m_Motion.clear(); ember.m_FinalXform.m_Motion.clear();
ember.m_FinalXform.ClearAndDeleteVariations(); ember.m_FinalXform.ClearAndDeleteVariations();
ember.m_FinalXform.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR, 0));//Do this so it doesn't appear empty. ember.m_FinalXform.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR, 0));//Do this so it doesn't appear empty.
} }
} }
@ -1036,7 +1036,7 @@ public:
m_Xforms[i].m_Affine.D(0); m_Xforms[i].m_Affine.D(0);
m_Xforms[i].m_Affine.E(1); m_Xforms[i].m_Affine.E(1);
m_Xforms[i].m_Affine.F(0); m_Xforms[i].m_Affine.F(0);
m_Xforms[i].AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR)); m_Xforms[i].AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR));
result++; result++;
sym = -sym; sym = -sym;
} }
@ -1058,7 +1058,7 @@ public:
m_Xforms[i].m_Affine.E(m_Xforms[i].m_Affine.A()); m_Xforms[i].m_Affine.E(m_Xforms[i].m_Affine.A());
m_Xforms[i].m_Affine.C(0); m_Xforms[i].m_Affine.C(0);
m_Xforms[i].m_Affine.F(0); m_Xforms[i].m_Affine.F(0);
m_Xforms[i].AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR)); m_Xforms[i].AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR));
result++; result++;
} }
@ -1688,7 +1688,7 @@ private:
Xform<T> m_FinalXform; Xform<T> m_FinalXform;
//Single global reference to create variations with. //Single global reference to create variations with.
VariationList<T>& m_VariationList = VariationList<T>::Instance(); shared_ptr<VariationList<T>> m_VariationList = VariationList<T>::Instance();
/// <summary> /// <summary>
/// Interpolation function that takes the address of a member variable of type T as a template parameter. /// Interpolation function that takes the address of a member variable of type T as a template parameter.

View File

@ -44,7 +44,7 @@ public:
bool currentFinal, final = sourceEmbers[0].UseFinalXform(); bool currentFinal, final = sourceEmbers[0].UseFinalXform();
size_t i, xf, currentCount, maxCount = sourceEmbers[0].XformCount(); size_t i, xf, currentCount, maxCount = sourceEmbers[0].XformCount();
Xform<T>* destOtherXform; Xform<T>* destOtherXform;
VariationList<T>& variationList(VariationList<T>::Instance()); auto variationList = VariationList<T>::Instance();
//Determine the max number of xforms present in sourceEmbers. //Determine the max number of xforms present in sourceEmbers.
//Also check if final xforms are used in any of them. //Also check if final xforms are used in any of them.
@ -138,7 +138,7 @@ public:
destOtherXform->GetVariationById(eVariationId::VAR_WEDGE_SPH) || destOtherXform->GetVariationById(eVariationId::VAR_WEDGE_SPH) ||
destOtherXform->GetVariationById(eVariationId::VAR_WEDGE_JULIA)) destOtherXform->GetVariationById(eVariationId::VAR_WEDGE_JULIA))
{ {
destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_LINEAR, -1)); destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_LINEAR, -1));
//Set the coefs appropriately. //Set the coefs appropriately.
destXform->m_Affine.A(-1); destXform->m_Affine.A(-1);
destXform->m_Affine.D(0); destXform->m_Affine.D(0);
@ -167,7 +167,7 @@ public:
if (destOtherXform->GetVariationById(eVariationId::VAR_RECTANGLES)) if (destOtherXform->GetVariationById(eVariationId::VAR_RECTANGLES))
{ {
if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_RECTANGLES)) if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_RECTANGLES))
{ {
var->SetParamVal("rectangles_x", 0); var->SetParamVal("rectangles_x", 0);
var->SetParamVal("rectangles_y", 0); var->SetParamVal("rectangles_y", 0);
@ -179,7 +179,7 @@ public:
if (destOtherXform->GetVariationById(eVariationId::VAR_RINGS2)) if (destOtherXform->GetVariationById(eVariationId::VAR_RINGS2))
{ {
if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_RINGS2)) if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_RINGS2))
{ {
var->SetParamVal("rings2_val", 0); var->SetParamVal("rings2_val", 0);
destXform->AddVariation(var); destXform->AddVariation(var);
@ -190,13 +190,13 @@ public:
if (destOtherXform->GetVariationById(eVariationId::VAR_FAN2)) if (destOtherXform->GetVariationById(eVariationId::VAR_FAN2))
{ {
destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_FAN2)); destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_FAN2));
found++; found++;
} }
if (destOtherXform->GetVariationById(eVariationId::VAR_BLOB)) if (destOtherXform->GetVariationById(eVariationId::VAR_BLOB))
{ {
if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_BLOB)) if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_BLOB))
{ {
var->SetParamVal("blob_low", 1); var->SetParamVal("blob_low", 1);
destXform->AddVariation(var); destXform->AddVariation(var);
@ -207,13 +207,13 @@ public:
if (destOtherXform->GetVariationById(eVariationId::VAR_PERSPECTIVE)) if (destOtherXform->GetVariationById(eVariationId::VAR_PERSPECTIVE))
{ {
destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_PERSPECTIVE)); destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_PERSPECTIVE));
found++; found++;
} }
if (destOtherXform->GetVariationById(eVariationId::VAR_CURL)) if (destOtherXform->GetVariationById(eVariationId::VAR_CURL))
{ {
if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_CURL)) if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_CURL))
{ {
var->SetParamVal("curl_c1", 0); var->SetParamVal("curl_c1", 0);
destXform->AddVariation(var); destXform->AddVariation(var);
@ -224,7 +224,7 @@ public:
if (destOtherXform->GetVariationById(eVariationId::VAR_SUPER_SHAPE)) if (destOtherXform->GetVariationById(eVariationId::VAR_SUPER_SHAPE))
{ {
if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_SUPER_SHAPE)) if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_SUPER_SHAPE))
{ {
var->SetParamVal("super_shape_n1", 2); var->SetParamVal("super_shape_n1", 2);
var->SetParamVal("super_shape_n2", 2); var->SetParamVal("super_shape_n2", 2);
@ -254,13 +254,13 @@ public:
if (destOtherXform->GetVariationById(eVariationId::VAR_FAN)) if (destOtherXform->GetVariationById(eVariationId::VAR_FAN))
{ {
destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_FAN)); destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_FAN));
found++; found++;
} }
if (destOtherXform->GetVariationById(eVariationId::VAR_RINGS)) if (destOtherXform->GetVariationById(eVariationId::VAR_RINGS))
{ {
destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_RINGS)); destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_RINGS));
found++; found++;
} }
} }
@ -280,7 +280,7 @@ public:
//If there still are no matches, switch back to linear. //If there still are no matches, switch back to linear.
if (found == 0) if (found == 0)
{ {
destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_LINEAR)); destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_LINEAR));
} }
else if (found > 0) else if (found > 0)
{ {

View File

@ -83,9 +83,9 @@ public:
Xform<T> xform1(T(0.25), T(1), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(0.5), T(0.25)); Xform<T> xform1(T(0.25), T(1), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(0.5), T(0.25));
Xform<T> xform2(T(0.25), T(0.66), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(-0.5), T(0.25)); Xform<T> xform2(T(0.25), T(0.66), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(-0.5), T(0.25));
Xform<T> xform3(T(0.25), T(0.33), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(0.0), T(-0.5)); Xform<T> xform3(T(0.25), T(0.33), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(0.0), T(-0.5));
xform1.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR)); xform1.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR));
xform2.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR)); xform2.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR));
xform3.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR)); xform3.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR));
ember.AddXform(xform1); ember.AddXform(xform1);
ember.AddXform(xform2); ember.AddXform(xform2);
ember.AddXform(xform3); ember.AddXform(xform3);
@ -599,7 +599,7 @@ public:
bool postid, addfinal = false; bool postid, addfinal = false;
int var, samed, multid, samepost; int var, samed, multid, samepost;
glm::length_t i, j, k, n; glm::length_t i, j, k, n;
size_t varCount = m_VariationList.Size(); size_t varCount = m_VariationList->Size();
Palette<T> palette; Palette<T> palette;
static size_t xformDistrib[] = static size_t xformDistrib[] =
{ {
@ -683,12 +683,12 @@ public:
if (var > -1) if (var > -1)
{ {
if (xform->TotalVariationCount() < maxVars) if (xform->TotalVariationCount() < maxVars)
xform->AddVariation(m_VariationList.GetVariation(var)->Copy());//Use only one variation specified for all xforms. xform->AddVariation(m_VariationList->GetVariation(var)->Copy());//Use only one variation specified for all xforms.
} }
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
{ {
@ -721,7 +721,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.
@ -729,7 +729,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;
@ -759,12 +759,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)));
} }
} }
} }
@ -1345,6 +1345,6 @@ private:
unique_ptr<Renderer<T, bucketT>> m_Renderer; unique_ptr<Renderer<T, bucketT>> m_Renderer;
QTIsaac<ISAAC_SIZE, ISAAC_INT> m_Rand; QTIsaac<ISAAC_SIZE, ISAAC_INT> m_Rand;
PaletteList<T> m_PaletteList; PaletteList<T> m_PaletteList;
VariationList<T>& m_VariationList; shared_ptr<VariationList<T>> m_VariationList;
}; };
} }

View File

@ -193,13 +193,16 @@ private:
/// member variables cannot be exported across module boundaries. /// member variables cannot be exported across module boundaries.
/// Derived classes should inherit from this using the CRTP, and declare a friend to it. /// Derived classes should inherit from this using the CRTP, and declare a friend to it.
/// They also should make their constructors private and destructors public. /// They also should make their constructors private and destructors public.
/// This has a severe flaw in that it cannot be used across module boundaries, else
/// every module will have its own copy. This makes it function as a per-module
/// singleton, which is unlikely to ever be desired.
/// Attribution: This class is a combination of /// Attribution: This class is a combination of
/// http://btorpey.github.io/blog/2014/02/12/shared-singletons/ /// http://btorpey.github.io/blog/2014/02/12/shared-singletons/
/// and /// and
/// http://enki-tech.blogspot.com/2012/08/c11-generic-singleton.html /// http://enki-tech.blogspot.com/2012/08/c11-generic-singleton.html
/// </summary> /// </summary>
template <class T> template <class T>
class Singleton class EMBER_API Singleton
{ {
public: public:
/// <summary> /// <summary>
@ -243,6 +246,28 @@ public:
x(const x& other) = delete; \ x(const x& other) = delete; \
const x& operator=(const x& other) = delete const x& operator=(const x& other) = delete
//Use this if not deriving from the Singleton class and are declaring Instance() in a header and implementing it in a cpp file.
#define SINGLETON_INSTANCE_DECL(x) \
static std::shared_ptr<x> Instance(); \
x(const x& other) = delete; \
const x& operator=(const x& other) = delete//Semicolon deliberately omitted to force it on the caller.
//Use this if not deriving from the Singleton class and are implementing Instance() in a cpp file.
#define SINGLETON_INSTANCE_IMPL(x) \
std::shared_ptr<x> x::Instance() \
{ \
static weak_ptr<x> staticInstance; \
auto temp = staticInstance.lock(); \
\
if (!temp) \
{ \
temp.reset(new x()); \
staticInstance = temp; \
} \
\
return temp; \
}
/// <summary> /// <summary>
/// Open a file in binary mode and read its entire contents into a vector of bytes. Optionally null terminate. /// Open a file in binary mode and read its entire contents into a vector of bytes. Optionally null terminate.
/// </summary> /// </summary>

View File

@ -13,7 +13,7 @@ namespace EmberNs
/// This class is a singleton since all of its data is shared and read-only. /// This class is a singleton since all of its data is shared and read-only.
/// </summary> /// </summary>
template <typename T> template <typename T>
class EMBER_API VarFuncs : public Singleton<VarFuncs<T>> class EMBER_API VarFuncs
{ {
public: public:
/// <summary> /// <summary>
@ -542,7 +542,7 @@ public:
} }
} }
SINGLETON_DERIVED_IMPL(VarFuncs<T>); SINGLETON_INSTANCE_DECL(VarFuncs);//Implemented in VariationList.cpp
private: private:
/// <summary> /// <summary>

View File

@ -17,14 +17,12 @@ namespace EmberNs
m_Variations.push_back(new Post##varName##Variation<T>()); m_Variations.push_back(new Post##varName##Variation<T>());
/// <summary> /// <summary>
/// Singleton pattern, return a reference to the only instance of this object in existence. /// Singleton patterns, return a reference to the only instance of this object in existence.
/// </summary> /// </summary>
template <typename T> template <typename T>
VariationList<T>& VariationList<T>::Instance() SINGLETON_INSTANCE_IMPL(VarFuncs<T>)
{ template <typename T>
static VariationList<T> v; SINGLETON_INSTANCE_IMPL(VariationList<T>)
return v;
}
/// <summary> /// <summary>
/// Constructor which initializes all of the variation objects and stores them in the list. /// Constructor which initializes all of the variation objects and stores them in the list.

View File

@ -21,10 +21,7 @@ template <typename T>
class EMBER_API VariationList class EMBER_API VariationList
{ {
public: public:
static VariationList<T>& Instance();
~VariationList(); ~VariationList();
VariationList<T>(const VariationList<T>& varList) = delete;
VariationList<T>& operator = (const VariationList<T>& varList) = delete;
const Variation<T>* GetVariation(size_t index) const; const Variation<T>* GetVariation(size_t index) const;
const Variation<T>* GetVariation(size_t index, eVariationType varType) const; const Variation<T>* GetVariation(size_t index, eVariationType varType) const;
Variation<T>* GetVariationCopy(size_t index, T weight = 1) const; Variation<T>* GetVariationCopy(size_t index, T weight = 1) const;
@ -48,6 +45,8 @@ public:
const vector<Variation<T>*>& PreVars() const; const vector<Variation<T>*>& PreVars() const;
const vector<Variation<T>*>& PostVars() const; const vector<Variation<T>*>& PostVars() const;
SINGLETON_INSTANCE_DECL(VariationList);//Implemented in VariationList.cpp
private: private:
VariationList(); VariationList();
Variation<T>* MakeCopyWithWeight(const Variation<T>* var, T weight) const; Variation<T>* MakeCopyWithWeight(const Variation<T>* var, T weight) const;

View File

@ -281,7 +281,6 @@ protected:
m_Params.push_back(ParamWithName<T>(&m_Scale, prefix + "hexes_scale", 1)); m_Params.push_back(ParamWithName<T>(&m_Scale, prefix + "hexes_scale", 1));
m_Params.push_back(ParamWithName<T>(true, &m_RotSin, prefix + "hexes_rotsin"));//Precalc. m_Params.push_back(ParamWithName<T>(true, &m_RotSin, prefix + "hexes_rotsin"));//Precalc.
m_Params.push_back(ParamWithName<T>(true, &m_RotCos, prefix + "hexes_rotcos")); m_Params.push_back(ParamWithName<T>(true, &m_RotCos, prefix + "hexes_rotcos"));
m_VarFuncs = VarFuncs<T>::Instance();
} }
private: private:
@ -291,7 +290,7 @@ private:
T m_Scale; T m_Scale;
T m_RotSin;//Precalc. T m_RotSin;//Precalc.
T m_RotCos; T m_RotCos;
std::shared_ptr<VarFuncs<T>> m_VarFuncs; shared_ptr<VarFuncs<T>> m_VarFuncs = VarFuncs<T>::Instance();
}; };
/// <summary> /// <summary>
@ -3774,7 +3773,7 @@ public:
//No possible solution was found, so it is unused here. //No possible solution was found, so it is unused here.
//The full calculation is recomputed for every point. //The full calculation is recomputed for every point.
return return
"static void Position(__global real_t* p, __global real3* grad, int x, int y, real_t z, real_t s, real_t d, real2* v)\n" "static void Position(__global real_t* p, __global real_t* grad, int x, int y, real_t z, real_t s, real_t d, real2* v)\n"
"{\n" "{\n"
" real3 e, f;\n" " real3 e, f;\n"
" e.x = x * 2.5;\n" " e.x = x * 2.5;\n"
@ -3823,7 +3822,7 @@ public:
<< "\t\t{\n" << "\t\t{\n"
<< "\t\t for (dj = -1; dj < 2; dj++)\n" << "\t\t for (dj = -1; dj < 2; dj++)\n"
<< "\t\t {\n" << "\t\t {\n"
<< "\t\t Position(globalShared + NOISE_INDEX, (__global real3*)(globalShared + NOISE_POINTS), cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]);\n" << "\t\t Position(globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]);\n"
<< "\t\t i++;\n" << "\t\t i++;\n"
<< "\t\t }\n" << "\t\t }\n"
<< "\t\t}\n" << "\t\t}\n"
@ -3839,7 +3838,7 @@ public:
<< "\t\t{\n" << "\t\t{\n"
<< "\t\t for (dj = -1; dj < 2; dj++)\n" << "\t\t for (dj = -1; dj < 2; dj++)\n"
<< "\t\t {\n" << "\t\t {\n"
<< "\t\t Position(globalShared + NOISE_INDEX, (__global real3*)(globalShared + NOISE_POINTS), cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]);\n" << "\t\t Position(globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]);\n"
<< "\t\t i++;\n" << "\t\t i++;\n"
<< "\t\t }\n" << "\t\t }\n"
<< "\t\t}\n" << "\t\t}\n"
@ -3870,7 +3869,6 @@ protected:
void Init() void Init()
{ {
string prefix = Prefix(); string prefix = Prefix();
m_VarFuncs = VarFuncs<T>::Instance();
m_Params.clear(); m_Params.clear();
m_Params.reserve(8); m_Params.reserve(8);
m_Params.push_back(ParamWithName<T>(&m_CellSize, prefix + "crackle_cellsize", 1)); m_Params.push_back(ParamWithName<T>(&m_CellSize, prefix + "crackle_cellsize", 1));
@ -3912,7 +3910,7 @@ private:
T m_Z; T m_Z;
T m_HalfCellSize;//Precalc T m_HalfCellSize;//Precalc
v2T m_C[CACHE_WIDTH][CACHE_WIDTH];//Not kept as a precalc because it crashes Nvidia GPUs. v2T m_C[CACHE_WIDTH][CACHE_WIDTH];//Not kept as a precalc because it crashes Nvidia GPUs.
std::shared_ptr<VarFuncs<T>> m_VarFuncs; shared_ptr<VarFuncs<T>> m_VarFuncs = VarFuncs<T>::Instance();
}; };
/// <summary> /// <summary>

View File

@ -1314,6 +1314,7 @@ public:
<< "\t\t break; \n" << "\t\t break; \n"
<< "\n" << "\n"
<< "\t\t case " << SHAPE_BLUR << ": \n" << "\t\t case " << SHAPE_BLUR << ": \n"
<< "\t\t default: \n"
<< "\t\t r = (1 + " << edge << ") * MwcNext01(mwc); \n" << "\t\t r = (1 + " << edge << ") * MwcNext01(mwc); \n"
<< "\n" << "\n"
<< "\t\t if (r > 1 - " << edge << ")\n" << "\t\t if (r > 1 - " << edge << ")\n"
@ -1369,6 +1370,7 @@ public:
<< "\t\t break; \n" << "\t\t break; \n"
<< "\n" << "\n"
<< "\t\t case " << MAP_BUBBLE2 << ": \n" << "\t\t case " << MAP_BUBBLE2 << ": \n"
<< "\t\t default: \n"
<< "\t\t r = 0.25 - (SQR(vx) + SQR(vy)); \n" << "\t\t r = 0.25 - (SQR(vx) + SQR(vy)); \n"
<< "\n" << "\n"
<< "\t\t if (r < 0)\n" << "\t\t if (r < 0)\n"
@ -1382,13 +1384,13 @@ public:
<< "\t\t break; \n" << "\t\t break; \n"
<< "\t\t }\n" << "\t\t }\n"
<< "\n" << "\n"
<< "\t\t p = PerlinNoise3D(&v, globalShared + NOISE_INDEX, (__global real3*)(globalShared + NOISE_POINTS), " << amps << ", " << freqs << ", iOctaves); \n" << "\t\t p = PerlinNoise3D(&v, globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, " << amps << ", " << freqs << ", iOctaves); \n"
<< "\n" << "\n"
<< "\t\t if (p > 0)\n" << "\t\t if (p > 0)\n"
<< "\t\t e = p * (1 + e * e * 20) + 2 * e; \n" << "\t\t e = p * (1 + e * e * 20) + 2 * e; \n"
<< "\t\t else\n" << "\t\t else\n"
<< "\t\t e = p * (1 + e * e * 20) - 2 * e; \n" << "\t\t e = p * (1 + e * e * 20) - 2 * e; \n"
<< "}\n" << "\t\t}\n"
<< "\t\twhile ((e < " << notchBottom << " || e > " << notchTop << ") && t++ < iBailout); \n" << "\t\twhile ((e < " << notchBottom << " || e > " << notchTop << ") && t++ < iBailout); \n"
<< "\n" << "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * vx; \n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * vx; \n"
@ -1413,7 +1415,6 @@ protected:
void Init() void Init()
{ {
string prefix = Prefix(); string prefix = Prefix();
m_VarFuncs = VarFuncs<T>::Instance();
m_Params.clear(); m_Params.clear();
m_Params.reserve(15); m_Params.reserve(15);
m_Params.push_back(ParamWithName<T>(&m_Shape, prefix + "dc_perlin_shape", 0, eParamType::INTEGER, 0, 2));//Params. m_Params.push_back(ParamWithName<T>(&m_Shape, prefix + "dc_perlin_shape", 0, eParamType::INTEGER, 0, 2));//Params.
@ -1448,7 +1449,7 @@ private:
T m_SelectBailout; T m_SelectBailout;
T m_NotchBottom;//Precalc. T m_NotchBottom;//Precalc.
T m_NotchTop; T m_NotchTop;
shared_ptr<VarFuncs<T>> m_VarFuncs; shared_ptr<VarFuncs<T>> m_VarFuncs = VarFuncs<T>::Instance();
}; };
MAKEPREPOSTPARVAR(DCBubble, dc_bubble, DC_BUBBLE) MAKEPREPOSTPARVAR(DCBubble, dc_bubble, DC_BUBBLE)

View File

@ -879,7 +879,7 @@ public:
bool Flatten(vector<string>& names) bool Flatten(vector<string>& names)
{ {
bool shouldFlatten = true; bool shouldFlatten = true;
VariationList<T>& vl(VariationList<T>::Instance()); auto vl = VariationList<T>::Instance();
if (GetVariationById(eVariationId::VAR_FLATTEN) == nullptr) if (GetVariationById(eVariationId::VAR_FLATTEN) == nullptr)
{ {
@ -898,7 +898,7 @@ public:
} }
//Now traverse the parameters for this variation. //Now traverse the parameters for this variation.
if (ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var))//If any parametric variation parameter is present and non-zero, don't flatten. if (auto parVar = dynamic_cast<ParametricVariation<T>*>(var))//If any parametric variation parameter is present and non-zero, don't flatten.
{ {
for (auto& s : names) for (auto& s : names)
{ {
@ -915,7 +915,7 @@ public:
if (shouldFlatten)//Flatten was not present and neither was any variation name or parameter in the list. if (shouldFlatten)//Flatten was not present and neither was any variation name or parameter in the list.
{ {
auto var = vl.GetVariationCopy(eVariationId::VAR_FLATTEN); auto var = vl->GetVariationCopy(eVariationId::VAR_FLATTEN);
if (AddVariation(var)) if (AddVariation(var))
{ {

View File

@ -337,8 +337,8 @@ public:
ScanForEmberNodes(rootnode, bn, embers, useDefaults); ScanForEmberNodes(rootnode, bn, embers, useDefaults);
xmlFreeDoc(doc); xmlFreeDoc(doc);
emberSize = embers.size(); emberSize = embers.size();
auto b = embers.begin(); auto first = embers.begin();
auto secondToLast = Advance(embers.begin(), emberSize - 2);
//t.Toc("ScanForEmberNodes"); //t.Toc("ScanForEmberNodes");
//Check to see if the first control point or the second-to-last //Check to see if the first control point or the second-to-last
@ -346,12 +346,17 @@ public:
//and should be reset to linear (with a warning). //and should be reset to linear (with a warning).
if (emberSize > 0) if (emberSize > 0)
{ {
if (b->m_Interp == eInterp::EMBER_INTERP_SMOOTH) if (first->m_Interp == eInterp::EMBER_INTERP_SMOOTH)
b->m_Interp = eInterp::EMBER_INTERP_LINEAR; first->m_Interp = eInterp::EMBER_INTERP_LINEAR;
if (emberSize >= 2 && secondToLast->m_Interp == eInterp::EMBER_INTERP_SMOOTH) if (emberSize >= 2)
{
auto secondToLast = Advance(embers.begin(), emberSize - 2);
if (secondToLast->m_Interp == eInterp::EMBER_INTERP_SMOOTH)
secondToLast->m_Interp = eInterp::EMBER_INTERP_LINEAR; secondToLast->m_Interp = eInterp::EMBER_INTERP_LINEAR;
} }
}
//Finally, ensure that consecutive 'rotate' parameters never exceed //Finally, ensure that consecutive 'rotate' parameters never exceed
//a difference of more than 180 degrees (+/-) for interpolation. //a difference of more than 180 degrees (+/-) for interpolation.
@ -1263,7 +1268,7 @@ private:
//Only correct names if it came from an outside source. Names originating from this library are always considered correct. //Only correct names if it came from an outside source. Names originating from this library are always considered correct.
string s = fromEmber ? string(CCX(curAtt->name)) : GetCorrectedVariationName(m_BadVariationNames, curAtt); string s = fromEmber ? string(CCX(curAtt->name)) : GetCorrectedVariationName(m_BadVariationNames, curAtt);
if (auto var = m_VariationList.GetVariation(s)) if (auto var = m_VariationList->GetVariation(s))
{ {
T weight = 0; T weight = 0;
Aton(attStr, weight); Aton(attStr, weight);
@ -1543,7 +1548,7 @@ private:
static bool m_Init; static bool m_Init;
static unordered_map<string, string> m_BadParamNames; static unordered_map<string, string> m_BadParamNames;
static vector<pair<pair<string, string>, vector<string>>> m_BadVariationNames; static vector<pair<pair<string, string>, vector<string>>> m_BadVariationNames;
VariationList<T>& m_VariationList;//The variation list used to make copies of variations to populate the embers with. shared_ptr<VariationList<T>> m_VariationList;//The variation list used to make copies of variations to populate the embers with.
PaletteList<T> m_PaletteList; PaletteList<T> m_PaletteList;
}; };
} }

View File

@ -176,7 +176,7 @@ FunctionMapper::FunctionMapper()
" return ratiomax;\n" " return ratiomax;\n"
"}\n"; "}\n";
s_GlobalMap["SimplexNoise3D"] = s_GlobalMap["SimplexNoise3D"] =
"inline real_t SimplexNoise3D(real3* v, __global real_t* p, __global real3* grad)\n" "inline real_t SimplexNoise3D(real3* v, __global real_t* p, __global real_t* grad)\n"
"{\n" "{\n"
" real3 c[4];\n" " real3 c[4];\n"
" real_t n = 0;\n" " real_t n = 0;\n"
@ -195,6 +195,7 @@ FunctionMapper::FunctionMapper()
" c[0].z = (*v).z - z0;\n" " c[0].z = (*v).z - z0;\n"
" int i1, j1, k1;\n" " int i1, j1, k1;\n"
" int i2, j2, k2;\n" " int i2, j2, k2;\n"
" real3 u;\n"
"\n" "\n"
" if (c[0].x >= c[0].y)\n" " if (c[0].x >= c[0].y)\n"
" {\n" " {\n"
@ -249,25 +250,28 @@ FunctionMapper::FunctionMapper()
" gi[1] = (int)p[ii + i1 + (int)p[jj + j1 + (int)p[kk + k1]]];\n" " gi[1] = (int)p[ii + i1 + (int)p[jj + j1 + (int)p[kk + k1]]];\n"
" gi[2] = (int)p[ii + i2 + (int)p[jj + j2 + (int)p[kk + k2]]];\n" " gi[2] = (int)p[ii + i2 + (int)p[jj + j2 + (int)p[kk + k2]]];\n"
" gi[3] = (int)p[ii + 1 + (int)p[jj + 1 + (int)p[kk + 1]]];\n" " gi[3] = (int)p[ii + 1 + (int)p[jj + 1 + (int)p[kk + 1]]];\n"
"\n"
" for (uint corner = 0; corner < 4; corner++)\n" " for (uint corner = 0; corner < 4; corner++)\n"
" {\n" " {\n"
" t = 0.6 - Sqr(c[corner].x) - Sqr(c[corner].y) - Sqr(c[corner].z);\n" " t = 0.6 - Sqr(c[corner].x) - Sqr(c[corner].y) - Sqr(c[corner].z);\n"
"\n" "\n"
" if (t > 0)\n" " if (t > 0)\n"
" {\n" " {\n"
" real3 u = grad[gi[corner]];\n" " u.x = grad[(gi[corner] * 3)];\n"
" u.y = grad[(gi[corner] * 3) + 1];\n"
" u.z = grad[(gi[corner] * 3) + 2];\n"
" t *= t;\n" " t *= t;\n"
" n += t * t * (u.x * c[corner].x + u.y * c[corner].y + u.z * c[corner].z);\n" " n += t * t * (u.x * c[corner].x + u.y * c[corner].y + u.z * c[corner].z);\n"
" }\n" " }\n"
" }\n" " }\n"
"\n" "\n"
" return 32 * n;\n" " return 32.0 * n;\n"
"}\n"; "}\n";
s_GlobalMap["PerlinNoise3D"] = s_GlobalMap["PerlinNoise3D"] =
"inline real_t PerlinNoise3D(real3* v, __global real_t* p, __global real3* grad, real_t aScale, real_t fScale, int octaves)\n" "inline real_t PerlinNoise3D(real3* v, __global real_t* p, __global real_t* grad, real_t aScale, real_t fScale, int octaves)\n"
"{\n" "{\n"
" int i;\n" " int i;\n"
" real_t n = 0, a = 1;\n" " real_t n = 0.0, a = 1.0;\n"
" real3 u = *v;\n" " real3 u = *v;\n"
"\n" "\n"
" for (i = 0; i < octaves; i++)\n" " for (i = 0; i < octaves; i++)\n"

View File

@ -68,6 +68,8 @@ OpenCLInfo::OpenCLInfo()
} }
} }
SINGLETON_INSTANCE_IMPL(OpenCLInfo)
/// <summary> /// <summary>
/// Get a const reference to the vector of available platforms. /// Get a const reference to the vector of available platforms.
/// </summary> /// </summary>

View File

@ -17,7 +17,7 @@ namespace EmberCLns
/// This class derives from EmberReport, so the caller is able /// This class derives from EmberReport, so the caller is able
/// to retrieve a text dump of error information if any errors occur. /// to retrieve a text dump of error information if any errors occur.
/// </summary> /// </summary>
class EMBERCL_API OpenCLInfo : public EmberReport, public Singleton<OpenCLInfo> class EMBERCL_API OpenCLInfo : public EmberReport
{ {
public: public:
const vector<cl::Platform>& Platforms() const; const vector<cl::Platform>& Platforms() const;
@ -54,7 +54,7 @@ public:
return val; return val;
} }
SINGLETON_DERIVED_IMPL(OpenCLInfo); SINGLETON_INSTANCE_DECL(OpenCLInfo);
private: private:
OpenCLInfo(); OpenCLInfo();

View File

@ -64,13 +64,13 @@ bool EmberGenome(EmberOptions& opt)
return true; return true;
} }
VariationList<T>& varList(VariationList<T>::Instance()); auto varList = VariationList<T>::Instance();
if (opt.AllVars() || opt.RegVars() || opt.PreVars() || opt.PostVars()) if (opt.AllVars() || opt.RegVars() || opt.PreVars() || opt.PostVars())
{ {
if (opt.AllVars()) if (opt.AllVars())
{ {
auto& vars = varList.AllVars(); auto& vars = varList->AllVars();
for (auto& v : vars) for (auto& v : vars)
cout << v->Name() << "\n"; cout << v->Name() << "\n";
@ -82,13 +82,13 @@ bool EmberGenome(EmberOptions& opt)
vector<Variation<T>*> vars; vector<Variation<T>*> vars;
if (opt.RegVars()) if (opt.RegVars())
vars.insert(vars.end(), varList.RegVars().begin(), varList.RegVars().end()); vars.insert(vars.end(), varList->RegVars().begin(), varList->RegVars().end());
if (opt.PreVars()) if (opt.PreVars())
vars.insert(vars.end(), varList.PreVars().begin(), varList.PreVars().end()); vars.insert(vars.end(), varList->PreVars().begin(), varList->PreVars().end());
if (opt.PostVars()) if (opt.PostVars())
vars.insert(vars.end(), varList.PostVars().begin(), varList.PostVars().end()); vars.insert(vars.end(), varList->PostVars().begin(), varList->PostVars().end());
for (auto& v : vars) for (auto& v : vars)
cout << v->Name() << "\n"; cout << v->Name() << "\n";
@ -192,16 +192,16 @@ bool EmberGenome(EmberOptions& opt)
noVars.push_back(eVariationId::VAR_SPLITS); noVars.push_back(eVariationId::VAR_SPLITS);
//Loop over the novars and set ivars to the complement. //Loop over the novars and set ivars to the complement.
for (i = 0; i < varList.Size(); i++) for (i = 0; i < varList->Size(); i++)
{ {
for (j = 0; j < noVars.size(); j++) for (j = 0; j < noVars.size(); j++)
{ {
if (noVars[j] == varList.GetVariation(i)->VariationId()) if (noVars[j] == varList->GetVariation(i)->VariationId())
break; break;
} }
if (j == noVars.size()) if (j == noVars.size())
vars.push_back(varList.GetVariation(i)->VariationId()); vars.push_back(varList->GetVariation(i)->VariationId());
} }
} }
else else
@ -214,7 +214,7 @@ bool EmberGenome(EmberOptions& opt)
{ {
if (parser.Aton(token.c_str(), val)) if (parser.Aton(token.c_str(), val))
{ {
if (val < varList.Size()) if (val < varList->Size())
vars.push_back(static_cast<eVariationId>(val)); vars.push_back(static_cast<eVariationId>(val));
} }
} }
@ -227,22 +227,22 @@ bool EmberGenome(EmberOptions& opt)
{ {
if (parser.Aton(token.c_str(), val)) if (parser.Aton(token.c_str(), val))
{ {
if (val < varList.Size()) if (val < varList->Size())
noVars.push_back(static_cast<eVariationId>(val)); noVars.push_back(static_cast<eVariationId>(val));
} }
} }
//Loop over the novars and set ivars to the complement. //Loop over the novars and set ivars to the complement.
for (i = 0; i < varList.Size(); i++) for (i = 0; i < varList->Size(); i++)
{ {
for (j = 0; j < noVars.size(); j++) for (j = 0; j < noVars.size(); j++)
{ {
if (noVars[j] == varList.GetVariation(i)->VariationId()) if (noVars[j] == varList->GetVariation(i)->VariationId())
break; break;
} }
if (j == noVars.size()) if (j == noVars.size())
vars.push_back(varList.GetVariation(i)->VariationId()); vars.push_back(varList->GetVariation(i)->VariationId());
} }
} }
} }

View File

@ -89,7 +89,7 @@ void MakeTestAllVarsRegPrePost(vector<Ember<T>>& embers)
{ {
uint index = 0; uint index = 0;
ostringstream ss; ostringstream ss;
VariationList<T>& varList(VariationList<T>::Instance()); auto varList = VariationList<T>::Instance();
PaletteList<T> paletteList; PaletteList<T> paletteList;
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand; QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
paletteList.Add("flam3-palettes.xml"); paletteList.Add("flam3-palettes.xml");
@ -118,7 +118,7 @@ void MakeTestAllVarsRegPrePost(vector<Ember<T>>& embers)
emberNoVars.m_Palette = *paletteList.GetPalette(paletteList.m_DefaultFilename, 0); emberNoVars.m_Palette = *paletteList.GetPalette(paletteList.m_DefaultFilename, 0);
embers.push_back(emberNoVars); embers.push_back(emberNoVars);
while (index < varList.RegSize()) while (index < varList->RegSize())
{ {
/* if (index != eVariationId::VAR_SYNTH) /* if (index != eVariationId::VAR_SYNTH)
{ {
@ -127,9 +127,9 @@ void MakeTestAllVarsRegPrePost(vector<Ember<T>>& embers)
} }
*/ */
Ember<T> ember1; Ember<T> ember1;
unique_ptr<Variation<T>> regVar(varList.GetVariationCopy(index, eVariationType::VARTYPE_REG)); unique_ptr<Variation<T>> regVar(varList->GetVariationCopy(index, eVariationType::VARTYPE_REG));
unique_ptr<Variation<T>> preVar(varList.GetVariationCopy("pre_" + regVar->Name())); unique_ptr<Variation<T>> preVar(varList->GetVariationCopy("pre_" + regVar->Name()));
unique_ptr<Variation<T>> postVar(varList.GetVariationCopy("post_" + regVar->Name())); unique_ptr<Variation<T>> postVar(varList->GetVariationCopy("post_" + regVar->Name()));
ember1.m_FinalRasW = 640; ember1.m_FinalRasW = 640;
ember1.m_FinalRasH = 480; ember1.m_FinalRasH = 480;
ember1.m_Quality = 100; ember1.m_Quality = 100;
@ -337,12 +337,12 @@ template <typename T>
static vector<Variation<T>*> FindVarsWith(vector<string>& stringVec, bool findAll = true) static vector<Variation<T>*> FindVarsWith(vector<string>& stringVec, bool findAll = true)
{ {
int index = 0; int index = 0;
VariationList<T>& vl(VariationList<T>::Instance()); auto vl = VariationList<T>::Instance();
vector<Variation<T>*> vec; vector<Variation<T>*> vec;
while (index < vl.RegSize()) while (index < vl->RegSize())
{ {
auto regVar = vl.GetVariation(index, eVariationType::VARTYPE_REG); auto regVar = vl->GetVariation(index, eVariationType::VARTYPE_REG);
if (SearchVar(regVar, stringVec, false)) if (SearchVar(regVar, stringVec, false))
{ {
@ -360,10 +360,10 @@ static vector<Variation<T>*> FindVarsWith(vector<string>& stringVec, bool findAl
bool TestVarCounts() bool TestVarCounts()
{ {
VariationList<float>& vlf(VariationList<float>::Instance()); auto vlf(VariationList<float>::Instance());
#ifdef DO_DOUBLE #ifdef DO_DOUBLE
VariationList<double>& vld(VariationList<double>::Instance()); auto vld(VariationList<double>::Instance());
bool success((vlf.Size() == vld.Size()) && (vlf.Size() == size_t(eVariationId::LAST_VAR))); bool success((vlf->Size() == vld->Size()) && (vlf->Size() == size_t(eVariationId::LAST_VAR)));
#else #else
bool success = true; bool success = true;
#endif #endif
@ -371,12 +371,12 @@ bool TestVarCounts()
if (!success) if (!success)
{ {
cout << "Variation list size " << vlf.Size() << " does not equal the max var ID enum " << et(eVariationId::LAST_VAR) << "." << endl; cout << "Variation list size " << vlf->Size() << " does not equal the max var ID enum " << et(eVariationId::LAST_VAR) << "." << endl;
} }
for (; start < et(eVariationId::LAST_VAR); start++) for (; start < et(eVariationId::LAST_VAR); start++)
{ {
auto var = vlf.GetVariation((eVariationId)start); auto var = vlf->GetVariation((eVariationId)start);
if (!var) if (!var)
{ {
@ -392,15 +392,15 @@ template <typename T>
bool TestVarUnique() bool TestVarUnique()
{ {
bool success = true; bool success = true;
VariationList<T>& vl(VariationList<T>::Instance()); auto vl = VariationList<T>::Instance();
vector<eVariationId> ids; vector<eVariationId> ids;
vector<string> names; vector<string> names;
ids.reserve(vl.Size()); ids.reserve(vl->Size());
names.reserve(vl.Size()); names.reserve(vl->Size());
for (size_t i = 0; i < vl.Size(); i++) for (size_t i = 0; i < vl->Size(); i++)
{ {
auto var = vl.GetVariation(i); auto var = vl->GetVariation(i);
if (std::find(ids.begin(), ids.end(), var->VariationId()) != ids.end()) if (std::find(ids.begin(), ids.end(), var->VariationId()) != ids.end())
{ {
@ -580,11 +580,11 @@ bool TestVarEqual(const Variation<sT>* var1, const Variation<dT>* var2)
bool TestVarPrePostNames() bool TestVarPrePostNames()
{ {
bool success = true; bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance()); auto vlf(VariationList<float>::Instance());
for (size_t i = 0; i < vlf.Size(); i++) for (size_t i = 0; i < vlf->Size(); i++)
{ {
auto var = vlf.GetVariation(i); auto var = vlf->GetVariation(i);
string name = var->Name(); string name = var->Name();
if (var->VarType() == eVariationType::VARTYPE_REG) if (var->VarType() == eVariationType::VARTYPE_REG)
@ -646,11 +646,11 @@ template <typename sT, typename dT>
bool TestVarCopy() bool TestVarCopy()
{ {
bool success = true; bool success = true;
VariationList<sT>& vlf(VariationList<sT>::Instance()); auto vlf(VariationList<sT>::Instance());
for (size_t i = 0; i < vlf.Size(); i++) for (size_t i = 0; i < vlf->Size(); i++)
{ {
auto var = vlf.GetVariation(i); auto var = vlf->GetVariation(i);
Variation<dT>* destVar = NULL; Variation<dT>* destVar = NULL;
unique_ptr<Variation<sT>> copyVar(var->Copy());//Test Copy(). unique_ptr<Variation<sT>> copyVar(var->Copy());//Test Copy().
@ -676,11 +676,11 @@ bool TestVarCopy()
bool TestParVars() bool TestParVars()
{ {
bool success = true; bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance()); auto vlf(VariationList<float>::Instance());
for (size_t i = 0; i < vlf.ParametricSize(); i++) for (size_t i = 0; i < vlf->ParametricSize(); i++)
{ {
if (auto parVar = vlf.GetParametricVariation(i)) if (auto parVar = vlf->GetParametricVariation(i))
{ {
if (parVar->ParamCount() < 1) if (parVar->ParamCount() < 1)
{ {
@ -730,19 +730,19 @@ bool TestParVars()
bool TestVarRegPrePost() bool TestVarRegPrePost()
{ {
bool success = true; bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance()); auto vlf(VariationList<float>::Instance());
for (size_t i = 0; i < vlf.RegSize(); i++) for (size_t i = 0; i < vlf->RegSize(); i++)
{ {
auto regVar = vlf.GetVariation(i, eVariationType::VARTYPE_REG); auto regVar = vlf->GetVariation(i, eVariationType::VARTYPE_REG);
if (regVar) if (regVar)
{ {
if (regVar->Name().find("dc_") != 0) if (regVar->Name().find("dc_") != 0)
{ {
string name = regVar->Name(); string name = regVar->Name();
auto preVar = vlf.GetVariation("pre_" + name); auto preVar = vlf->GetVariation("pre_" + name);
auto postVar = vlf.GetVariation("post_" + name); auto postVar = vlf->GetVariation("post_" + name);
if (!preVar) if (!preVar)
{ {
@ -782,11 +782,11 @@ bool TestVarRegPrePost()
bool TestVarPrecalcUsedCL() bool TestVarPrecalcUsedCL()
{ {
bool success = true; bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance()); auto vlf(VariationList<float>::Instance());
for (size_t i = 0; i < vlf.Size(); i++) for (size_t i = 0; i < vlf->Size(); i++)
{ {
auto var = vlf.GetVariation(i); auto var = vlf->GetVariation(i);
string s = var->OpenCLString(); string s = var->OpenCLString();
if (var->NeedPrecalcAngles()) if (var->NeedPrecalcAngles())
@ -951,7 +951,7 @@ bool TestVarPrecalcUsedCL()
bool TestVarAssignTypes() bool TestVarAssignTypes()
{ {
bool success = true; bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance()); auto vlf(VariationList<float>::Instance());
vector<string> vset, vsum; vector<string> vset, vsum;
vset.push_back("vIn.x"); vset.push_back("vIn.x");
vset.push_back("vIn.y"); vset.push_back("vIn.y");
@ -972,9 +972,9 @@ bool TestVarAssignTypes()
vsum.push_back("precalcAtanxy"); vsum.push_back("precalcAtanxy");
vsum.push_back("precalcAtanyx"); vsum.push_back("precalcAtanyx");
for (size_t i = 0; i < vlf.Size(); i++) for (size_t i = 0; i < vlf->Size(); i++)
{ {
auto var = vlf.GetVariation(i); auto var = vlf->GetVariation(i);
string s = var->OpenCLString(); string s = var->OpenCLString();
//Only test pre and post. The assign type for regular is ignored, and will always be summed. //Only test pre and post. The assign type for regular is ignored, and will always be summed.
@ -1009,7 +1009,7 @@ bool TestVarAssignTypes()
bool TestVarAssignVals() bool TestVarAssignVals()
{ {
bool success = true; bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance()); auto vlf(VariationList<float>::Instance());
vector<string> xout, yout, zout; vector<string> xout, yout, zout;
xout.push_back("vOut.x ="); xout.push_back("vOut.x =");
xout.push_back("vOut.x +="); xout.push_back("vOut.x +=");
@ -1027,9 +1027,9 @@ bool TestVarAssignVals()
zout.push_back("vOut.z *="); zout.push_back("vOut.z *=");
zout.push_back("vOut.z /="); zout.push_back("vOut.z /=");
for (size_t i = 0; i < vlf.Size(); i++) for (size_t i = 0; i < vlf->Size(); i++)
{ {
auto var = vlf.GetVariation(i); auto var = vlf->GetVariation(i);
if (!SearchVar(var, xout, false)) if (!SearchVar(var, xout, false))
{ {
@ -1056,13 +1056,13 @@ bool TestVarAssignVals()
bool TestZepsFloor() bool TestZepsFloor()
{ {
bool success = true; bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance()); auto vlf(VariationList<float>::Instance());
vector<string> zeps; vector<string> zeps;
zeps.push_back("Zeps(floor"); zeps.push_back("Zeps(floor");
for (size_t i = 0; i < vlf.Size(); i++) for (size_t i = 0; i < vlf->Size(); i++)
{ {
auto var = vlf.GetVariation(i); auto var = vlf->GetVariation(i);
if (SearchVar(var, zeps, false)) if (SearchVar(var, zeps, false))
{ {
@ -1077,16 +1077,16 @@ bool TestZepsFloor()
bool TestConstants() bool TestConstants()
{ {
bool success = true; bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance()); auto vlf(VariationList<float>::Instance());
vector<string> stringVec; vector<string> stringVec;
stringVec.push_back("2 * M_PI"); stringVec.push_back("2 * M_PI");
stringVec.push_back("2*M_PI"); stringVec.push_back("2*M_PI");
stringVec.push_back("M_PI*2"); stringVec.push_back("M_PI*2");
stringVec.push_back("M_PI * 2"); stringVec.push_back("M_PI * 2");
for (size_t i = 0; i < vlf.Size(); i++) for (size_t i = 0; i < vlf->Size(); i++)
{ {
auto var = vlf.GetVariation(i); auto var = vlf->GetVariation(i);
if (SearchVar(var, stringVec, false)) if (SearchVar(var, stringVec, false))
{ {
@ -1101,13 +1101,13 @@ bool TestConstants()
bool TestGlobalFuncs() bool TestGlobalFuncs()
{ {
bool success = true; bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance()); auto vlf(VariationList<float>::Instance());
vector<string> funcs; vector<string> funcs;
FunctionMapper mapper; FunctionMapper mapper;
for (size_t i = 0; i < vlf.Size(); i++) for (size_t i = 0; i < vlf->Size(); i++)
{ {
auto var = vlf.GetVariation(i); auto var = vlf->GetVariation(i);
funcs = var->OpenCLGlobalFuncNames(); funcs = var->OpenCLGlobalFuncNames();
for (auto& func : funcs) for (auto& func : funcs)
@ -1130,30 +1130,30 @@ bool TestGlobalFuncs()
void PrintAllVars() void PrintAllVars()
{ {
uint i = 0; uint i = 0;
VariationList<float>& vlf(VariationList<float>::Instance()); auto vlf(VariationList<float>::Instance());
while (auto var = vlf.GetVariation(i++)) while (auto var = vlf->GetVariation(i++))
cout << var->Name() << endl; cout << var->Name() << endl;
} }
void TestXformsInOutPoints() void TestXformsInOutPoints()
{ {
uint index = 0; uint index = 0;
VariationList<float>& varList(VariationList<float>::Instance()); auto varList(VariationList<float>::Instance());
PaletteList<float> paletteList; PaletteList<float> paletteList;
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand; QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
paletteList.Add("flam3-palettes.xml"); paletteList.Add("flam3-palettes.xml");
while (index < varList.RegSize()) while (index < varList->RegSize())
{ {
vector<Xform<float>> xforms; vector<Xform<float>> xforms;
unique_ptr<Variation<float>> regVar(varList.GetVariationCopy(index, eVariationType::VARTYPE_REG)); unique_ptr<Variation<float>> regVar(varList->GetVariationCopy(index, eVariationType::VARTYPE_REG));
string s = regVar->OpenCLString() + regVar->OpenCLFuncsString(); string s = regVar->OpenCLString() + regVar->OpenCLFuncsString();
if (s.find("MwcNext") == string::npos) if (s.find("MwcNext") == string::npos)
{ {
unique_ptr<Variation<float>> preVar(varList.GetVariationCopy("pre_" + regVar->Name())); unique_ptr<Variation<float>> preVar(varList->GetVariationCopy("pre_" + regVar->Name()));
unique_ptr<Variation<float>> postVar(varList.GetVariationCopy("post_" + regVar->Name())); unique_ptr<Variation<float>> postVar(varList->GetVariationCopy("post_" + regVar->Name()));
Xform<float> xform0(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<float> xform0(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>());
Xform<float> xform1(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<float> xform1(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>());
Xform<float> xform2(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<float> xform2(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>());
@ -1257,13 +1257,13 @@ void TestVarTime()
IteratorHelper<T> helper; IteratorHelper<T> helper;
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand; QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
vector<pair<string, double>> times; vector<pair<string, double>> times;
times.reserve(vlf.RegSize()); times.reserve(vlf->RegSize());
while (i < vlf.RegSize()) while (i < vlf->RegSize())
{ {
double sum = 0; double sum = 0;
Xform<T> xform; Xform<T> xform;
Variation<T>* var = vlf.GetVariationCopy(i, eVariationType::VARTYPE_REG); Variation<T>* var = vlf->GetVariationCopy(i, eVariationType::VARTYPE_REG);
xform.AddVariation(var); xform.AddVariation(var);
for (int iter = 0; iter < iters; iter++) for (int iter = 0; iter < iters; iter++)
@ -1365,18 +1365,18 @@ void TestVarsSimilar()
IteratorHelper<T> helper; IteratorHelper<T> helper;
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand; QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
vector<pair<string, double>> diffs; vector<pair<string, double>> diffs;
diffs.reserve(vlf.RegSize()); diffs.reserve(vlf->RegSize());
while (i < vlf.RegSize()) while (i < vlf->RegSize())
{ {
double diff = 0, highest = TMAX; double diff = 0, highest = TMAX;
Xform<T> xform; Xform<T> xform;
Variation<T>* var = vlf.GetVariationCopy(i, eVariationType::VARTYPE_REG); Variation<T>* var = vlf->GetVariationCopy(i, eVariationType::VARTYPE_REG);
pair<string, double> match("", TMAX); pair<string, double> match("", TMAX);
compIndex = 0; compIndex = 0;
xform.AddVariation(var); xform.AddVariation(var);
while (compIndex < vlf.RegSize()) while (compIndex < vlf->RegSize())
{ {
if (compIndex == i) if (compIndex == i)
{ {
@ -1386,7 +1386,7 @@ void TestVarsSimilar()
double sum = 0, xdiff = 0, ydiff = 0, zdiff = 0; double sum = 0, xdiff = 0, ydiff = 0, zdiff = 0;
Xform<T> xformComp; Xform<T> xformComp;
Variation<T>* varComp = vlf.GetVariationCopy(compIndex, eVariationType::VARTYPE_REG); Variation<T>* varComp = vlf->GetVariationCopy(compIndex, eVariationType::VARTYPE_REG);
xformComp.AddVariation(varComp); xformComp.AddVariation(varComp);
ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var); ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var);
ParametricVariation<T>* parVarComp = dynamic_cast<ParametricVariation<T>*>(varComp); ParametricVariation<T>* parVarComp = dynamic_cast<ParametricVariation<T>*>(varComp);
@ -1536,11 +1536,11 @@ void TestCpuGpuResults(size_t platform, size_t device)
RendererCL<T, float> renderer(devices); RendererCL<T, float> renderer(devices);
points.resize(renderer.TotalIterKernelCount()); points.resize(renderer.TotalIterKernelCount());
while (i < vlf.RegSize()) while (i < vlf->RegSize())
{ {
bool bad = false; bool bad = false;
double sum = 0; double sum = 0;
Variation<T>* var = vlf.GetVariation(i, eVariationType::VARTYPE_REG); Variation<T>* var = vlf->GetVariation(i, eVariationType::VARTYPE_REG);
string s = var->OpenCLString() + var->OpenCLFuncsString(); string s = var->OpenCLString() + var->OpenCLFuncsString();
if (s.find("MwcNext") != string::npos) if (s.find("MwcNext") != string::npos)
@ -1631,7 +1631,7 @@ void TestGpuVectorRead(size_t platform, size_t device)
vector<pair<size_t, size_t>> devices{ std::make_pair(platform, device) }; vector<pair<size_t, size_t>> devices{ std::make_pair(platform, device) };
RendererCL<T, float> renderer(devices); RendererCL<T, float> renderer(devices);
points.resize(renderer.TotalIterKernelCount()); points.resize(renderer.TotalIterKernelCount());
Variation<T>* var = vlf.GetVariation(eVariationId::VAR_LINEAR); Variation<T>* var = vlf->GetVariation(eVariationId::VAR_LINEAR);
bool newAlloc = false; bool newAlloc = false;
Point<T> p, p2; Point<T> p, p2;
Ember<T> ember; Ember<T> ember;
@ -2132,12 +2132,12 @@ int _tmain(int argc, _TCHAR* argv[])
TestCasting(); TestCasting();
t.Toc("TestCasting()"); t.Toc("TestCasting()");
t.Tic(); t.Tic();
VariationList<float>& vlf(VariationList<float>::Instance()); auto vlf(VariationList<float>::Instance());
t.Toc("Creating VariationList<float>"); t.Toc("Creating VariationList<float>");
cout << "There are " << vlf.Size() << " variations present." << endl; cout << "There are " << vlf->Size() << " variations present." << endl;
#ifdef DO_DOUBLE #ifdef DO_DOUBLE
t.Tic(); t.Tic();
VariationList<double>& vld(VariationList<double>::Instance()); auto vld(VariationList<double>::Instance());
t.Toc("Creating VariationList<double>"); t.Toc("Creating VariationList<double>");
#endif #endif
t.Tic(); t.Tic();

View File

@ -400,7 +400,7 @@ void FractoriumFinalRenderDialog::OnDoSequenceCheckBoxStateChanged(int state)
/// <param name="d">Ignored</param> /// <param name="d">Ignored</param>
void FractoriumFinalRenderDialog::OnCurrentSpinChanged(int d) void FractoriumFinalRenderDialog::OnCurrentSpinChanged(int d)
{ {
m_Controller->SetEmber(d - 1); m_Controller->SetEmber(d - 1, false);
m_Controller->SyncCurrentToGui(); m_Controller->SyncCurrentToGui();
SetMemory(); SetMemory();
} }
@ -743,7 +743,7 @@ bool FractoriumFinalRenderDialog::CreateControllerFromGUI(bool createRenderer)
if (m_Controller.get()) if (m_Controller.get())
{ {
m_Controller->SetEmberFile(efd);//Convert float to double or set double verbatim; m_Controller->SetEmberFile(efd);//Convert float to double or set double verbatim;
m_Controller->SetEmber(index); m_Controller->SetEmber(index, false);
} }
} }

View File

@ -406,7 +406,7 @@ template <typename T> void FinalRenderEmberController<T>::CopyEmberFile(EmberFil
/// </summary> /// </summary>
/// <param name="index">The index in the file from which to retrieve the ember</param> /// <param name="index">The index in the file from which to retrieve the ember</param>
template <typename T> template <typename T>
void FinalRenderEmberController<T>::SetEmber(size_t index) void FinalRenderEmberController<T>::SetEmber(size_t index, bool verbatim)
{ {
if (index < m_EmberFile.Size()) if (index < m_EmberFile.Size())
{ {

View File

@ -109,7 +109,7 @@ public:
virtual void SetEmberFile(const EmberFile<double>& emberFile) override; virtual void SetEmberFile(const EmberFile<double>& emberFile) override;
virtual void CopyEmberFile(EmberFile<double>& emberFile, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) override; virtual void CopyEmberFile(EmberFile<double>& emberFile, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) override;
#endif #endif
virtual void SetEmber(size_t index) override; virtual void SetEmber(size_t index, bool verbatim) override;
virtual bool Render() override; virtual bool Render() override;
virtual bool CreateRenderer(eRendererType renderType, const vector<pair<size_t, size_t>>& devices, bool shared = true) override; virtual bool CreateRenderer(eRendererType renderType, const vector<pair<size_t, size_t>>& devices, 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;

View File

@ -134,7 +134,7 @@ FractoriumEmberController<T>::~FractoriumEmberController() { }
/// These are used to preserve the current ember/file when switching between renderers. /// These are used to preserve the current ember/file when switching between renderers.
/// Note that some precision will be lost when going from double to float. /// Note that some precision will be lost when going from double to float.
/// </summary> /// </summary>
template <typename T> void FractoriumEmberController<T>::SetEmber(const Ember<float>& ember, bool verbatim) { SetEmberPrivate<float>(ember, verbatim); } template <typename T> void FractoriumEmberController<T>::SetEmber(const Ember<float>& ember, bool verbatim, bool updatePointer) { SetEmberPrivate<float>(ember, verbatim, updatePointer); }
template <typename T> void FractoriumEmberController<T>::CopyEmber(Ember<float>& ember, std::function<void(Ember<float>& ember)> perEmberOperation) { ember = m_Ember; perEmberOperation(ember); } template <typename T> void FractoriumEmberController<T>::CopyEmber(Ember<float>& ember, std::function<void(Ember<float>& ember)> perEmberOperation) { ember = m_Ember; perEmberOperation(ember); }
template <typename T> void FractoriumEmberController<T>::SetEmberFile(const EmberFile<float>& emberFile) { m_EmberFile = emberFile; } template <typename T> void FractoriumEmberController<T>::SetEmberFile(const EmberFile<float>& emberFile) { m_EmberFile = emberFile; }
template <typename T> void FractoriumEmberController<T>::CopyEmberFile(EmberFile<float>& emberFile, std::function<void(Ember<float>& ember)> perEmberOperation) template <typename T> void FractoriumEmberController<T>::CopyEmberFile(EmberFile<float>& emberFile, std::function<void(Ember<float>& ember)> perEmberOperation)
@ -146,7 +146,7 @@ template <typename T> void FractoriumEmberController<T>::CopyEmberFile(EmberFile
template <typename T> void FractoriumEmberController<T>::SetTempPalette(const Palette<float>& palette) { m_TempPalette = palette; } template <typename T> void FractoriumEmberController<T>::SetTempPalette(const Palette<float>& palette) { m_TempPalette = palette; }
template <typename T> void FractoriumEmberController<T>::CopyTempPalette(Palette<float>& palette) { palette = m_TempPalette; } template <typename T> void FractoriumEmberController<T>::CopyTempPalette(Palette<float>& palette) { palette = m_TempPalette; }
#ifdef DO_DOUBLE #ifdef DO_DOUBLE
template <typename T> void FractoriumEmberController<T>::SetEmber(const Ember<double>& ember, bool verbatim) { SetEmberPrivate<double>(ember, verbatim); } template <typename T> void FractoriumEmberController<T>::SetEmber(const Ember<double>& ember, bool verbatim, bool updatePointer) { SetEmberPrivate<double>(ember, verbatim, updatePointer); }
template <typename T> void FractoriumEmberController<T>::CopyEmber(Ember<double>& ember, std::function<void(Ember<double>& ember)> perEmberOperation) { ember = m_Ember; perEmberOperation(ember); } template <typename T> void FractoriumEmberController<T>::CopyEmber(Ember<double>& ember, std::function<void(Ember<double>& ember)> perEmberOperation) { ember = m_Ember; perEmberOperation(ember); }
template <typename T> void FractoriumEmberController<T>::SetEmberFile(const EmberFile<double>& emberFile) { m_EmberFile = emberFile; } template <typename T> void FractoriumEmberController<T>::SetEmberFile(const EmberFile<double>& emberFile) { m_EmberFile = emberFile; }
template <typename T> void FractoriumEmberController<T>::CopyEmberFile(EmberFile<double>& emberFile, std::function<void(Ember<double>& ember)> perEmberOperation) template <typename T> void FractoriumEmberController<T>::CopyEmberFile(EmberFile<double>& emberFile, std::function<void(Ember<double>& ember)> perEmberOperation)
@ -173,8 +173,9 @@ void FractoriumEmberController<T>::ConstrainDimensions(Ember<T>& ember)
/// Resets the rendering process. /// Resets the rendering process.
/// </summary> /// </summary>
/// <param name="index">The index in the file from which to retrieve the ember</param> /// <param name="index">The index in the file from which to retrieve the ember</param>
/// <param name="verbatim">If true, do not overwrite temporal samples, quality or supersample value, else overwrite.</param>
template <typename T> template <typename T>
void FractoriumEmberController<T>::SetEmber(size_t index) void FractoriumEmberController<T>::SetEmber(size_t index, bool verbatim)
{ {
if (index < m_EmberFile.Size()) if (index < m_EmberFile.Size())
{ {
@ -188,7 +189,7 @@ void FractoriumEmberController<T>::SetEmber(size_t index)
} }
ClearUndo(); ClearUndo();
SetEmber(*m_EmberFile.Get(index)); SetEmber(*m_EmberFile.Get(index), verbatim, true);
} }
} }
@ -318,9 +319,10 @@ void FractoriumEmberController<T>::UpdateXform(std::function<void(Xform<T>*)> fu
/// </summary> /// </summary>
/// <param name="ember">The ember to set as the current</param> /// <param name="ember">The ember to set as the current</param>
/// <param name="verbatim">If true, do not overwrite temporal samples, quality or supersample value, else overwrite.</param> /// <param name="verbatim">If true, do not overwrite temporal samples, quality or supersample value, else overwrite.</param>
/// <param name="updatePointer">If true, update the current ember pointer to the address of the one passed in.</param>
template <typename T> template <typename T>
template <typename U> template <typename U>
void FractoriumEmberController<T>::SetEmberPrivate(const Ember<U>& ember, bool verbatim) void FractoriumEmberController<T>::SetEmberPrivate(const Ember<U>& ember, bool verbatim, bool updatePointer)
{ {
if (ember.m_Name != m_Ember.m_Name) if (ember.m_Name != m_Ember.m_Name)
m_LastSaveCurrent = ""; m_LastSaveCurrent = "";
@ -328,6 +330,8 @@ void FractoriumEmberController<T>::SetEmberPrivate(const Ember<U>& ember, bool v
size_t w = m_Ember.m_FinalRasW;//Cache values for use below. size_t w = m_Ember.m_FinalRasW;//Cache values for use below.
size_t h = m_Ember.m_FinalRasH; size_t h = m_Ember.m_FinalRasH;
m_Ember = ember; m_Ember = ember;
if (updatePointer)
m_EmberFilePointer = &ember; m_EmberFilePointer = &ember;
if (!verbatim) if (!verbatim)

View File

@ -52,21 +52,21 @@ public:
virtual ~FractoriumEmberControllerBase(); virtual ~FractoriumEmberControllerBase();
//Embers. //Embers.
virtual void SetEmber(const Ember<float>& ember, bool verbatim = false) { } virtual void SetEmber(const Ember<float>& ember, bool verbatim, bool updatePointer) { }
virtual void CopyEmber(Ember<float>& ember, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) { }//Uncomment default lambdas once LLVM fixes a crash in their compiler with default lambda parameters.//TODO virtual void CopyEmber(Ember<float>& ember, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) { }//Uncomment default lambdas once LLVM fixes a crash in their compiler with default lambda parameters.//TODO
virtual void SetEmberFile(const EmberFile<float>& emberFile) { } virtual void SetEmberFile(const EmberFile<float>& emberFile) { }
virtual void CopyEmberFile(EmberFile<float>& emberFile, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) { } virtual void CopyEmberFile(EmberFile<float>& emberFile, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) { }
virtual void SetTempPalette(const Palette<float>& palette) { } virtual void SetTempPalette(const Palette<float>& palette) { }
virtual void CopyTempPalette(Palette<float>& palette) { } virtual void CopyTempPalette(Palette<float>& palette) { }
#ifdef DO_DOUBLE #ifdef DO_DOUBLE
virtual void SetEmber(const Ember<double>& ember, bool verbatim = false) { } virtual void SetEmber(const Ember<double>& ember, bool verbatim, bool updatePointer) { }
virtual void CopyEmber(Ember<double>& ember, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) { } virtual void CopyEmber(Ember<double>& ember, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) { }
virtual void SetEmberFile(const EmberFile<double>& emberFile) { } virtual void SetEmberFile(const EmberFile<double>& emberFile) { }
virtual void CopyEmberFile(EmberFile<double>& emberFile, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) { } virtual void CopyEmberFile(EmberFile<double>& emberFile, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) { }
virtual void SetTempPalette(const Palette<double>& palette) { } virtual void SetTempPalette(const Palette<double>& palette) { }
virtual void CopyTempPalette(Palette<double>& palette) { } virtual void CopyTempPalette(Palette<double>& palette) { }
#endif #endif
virtual void SetEmber(size_t index) { } virtual void SetEmber(size_t index, bool verbatim) { }
//virtual void Clear() { } //virtual void Clear() { }
virtual void AddXform() { } virtual void AddXform() { }
virtual void AddLinkedXform() { } virtual void AddLinkedXform() { }
@ -95,7 +95,7 @@ public:
virtual void OpenAndPrepFiles(const QStringList& filenames, bool append) { } virtual void OpenAndPrepFiles(const QStringList& filenames, bool append) { }
virtual void SaveCurrentAsXml() { } virtual void SaveCurrentAsXml() { }
virtual void SaveEntireFileAsXml() { } virtual void SaveEntireFileAsXml() { }
virtual void SaveCurrentToOpenedFile() { } virtual uint SaveCurrentToOpenedFile() { return 0; }
virtual void Undo() { }//Edit. virtual void Undo() { }//Edit.
virtual void Redo() { } virtual void Redo() { }
virtual void CopyXml() { } virtual void CopyXml() { }
@ -290,21 +290,21 @@ public:
virtual ~FractoriumEmberController(); virtual ~FractoriumEmberController();
//Embers. //Embers.
virtual void SetEmber(const Ember<float>& ember, bool verbatim = false) override; virtual void SetEmber(const Ember<float>& ember, bool verbatim, bool updatePointer) override;
virtual void CopyEmber(Ember<float>& ember, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) override; virtual void CopyEmber(Ember<float>& ember, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) override;
virtual void SetEmberFile(const EmberFile<float>& emberFile) override; virtual void SetEmberFile(const EmberFile<float>& emberFile) override;
virtual void CopyEmberFile(EmberFile<float>& emberFile, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) override; virtual void CopyEmberFile(EmberFile<float>& emberFile, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) override;
virtual void SetTempPalette(const Palette<float>& palette) override; virtual void SetTempPalette(const Palette<float>& palette) override;
virtual void CopyTempPalette(Palette<float>& palette) override; virtual void CopyTempPalette(Palette<float>& palette) override;
#ifdef DO_DOUBLE #ifdef DO_DOUBLE
virtual void SetEmber(const Ember<double>& ember, bool verbatim = false) override; virtual void SetEmber(const Ember<double>& ember, bool verbatim, bool updatePointer) override;
virtual void CopyEmber(Ember<double>& ember, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) override; virtual void CopyEmber(Ember<double>& ember, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) override;
virtual void SetEmberFile(const EmberFile<double>& emberFile) override; virtual void SetEmberFile(const EmberFile<double>& emberFile) override;
virtual void CopyEmberFile(EmberFile<double>& emberFile, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) override; virtual void CopyEmberFile(EmberFile<double>& emberFile, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) override;
virtual void SetTempPalette(const Palette<double>& palette) override; virtual void SetTempPalette(const Palette<double>& palette) override;
virtual void CopyTempPalette(Palette<double>& palette) override; virtual void CopyTempPalette(Palette<double>& palette) override;
#endif #endif
virtual void SetEmber(size_t index) override; virtual void SetEmber(size_t index, bool verbatim) override;
//virtual void Clear() override { } //virtual void Clear() override { }
virtual void AddXform() override; virtual void AddXform() override;
virtual void AddLinkedXform() override; virtual void AddLinkedXform() override;
@ -336,7 +336,7 @@ public:
virtual void OpenAndPrepFiles(const QStringList& filenames, bool append) override; virtual void OpenAndPrepFiles(const QStringList& filenames, bool append) override;
virtual void SaveCurrentAsXml() override; virtual void SaveCurrentAsXml() override;
virtual void SaveEntireFileAsXml() override; virtual void SaveEntireFileAsXml() override;
virtual void SaveCurrentToOpenedFile() override; virtual uint SaveCurrentToOpenedFile() override;
virtual void Undo() override; virtual void Undo() override;
virtual void Redo() override; virtual void Redo() override;
virtual void CopyXml() override; virtual void CopyXml() override;
@ -472,7 +472,7 @@ public:
private: private:
//Embers. //Embers.
void ApplyXmlSavingTemplate(Ember<T>& ember); void ApplyXmlSavingTemplate(Ember<T>& ember);
template <typename U> void SetEmberPrivate(const Ember<U>& ember, bool verbatim); template <typename U> void SetEmberPrivate(const Ember<U>& ember, bool verbatim, bool updatePointer);
//Params. //Params.
void ParamsToEmber(Ember<T>& ember); void ParamsToEmber(Ember<T>& ember);
@ -509,7 +509,7 @@ private:
Xform<T> m_CopiedFinalXform; Xform<T> m_CopiedFinalXform;
Palette<T> m_TempPalette; Palette<T> m_TempPalette;
PaletteList<T> m_PaletteList; PaletteList<T> m_PaletteList;
VariationList<T>& m_VariationList; shared_ptr<VariationList<T>> m_VariationList;
unique_ptr<SheepTools<T, float>> m_SheepTools; unique_ptr<SheepTools<T, float>> m_SheepTools;
unique_ptr<GLEmberController<T>> m_GLController; unique_ptr<GLEmberController<T>> m_GLController;
unique_ptr<EmberNs::Renderer<T, float>> m_PreviewRenderer = make_unique<EmberNs::Renderer<T, float>>(); unique_ptr<EmberNs::Renderer<T, float>> m_PreviewRenderer = make_unique<EmberNs::Renderer<T, float>>();

View File

@ -243,7 +243,7 @@ void FractoriumEmberController<T>::EmberTreeItemDoubleClicked(QTreeWidgetItem* i
{ {
//qDebug() << "Setting current ember to: " << QString::fromStdString(emberItem->GetEmber()->m_Name); //qDebug() << "Setting current ember to: " << QString::fromStdString(emberItem->GetEmber()->m_Name);
ClearUndo(); ClearUndo();
SetEmber(*emberItem->GetEmber()); SetEmber(*emberItem->GetEmber(), false, true);
} }
} }

View File

@ -76,7 +76,7 @@ void FractoriumEmberController<T>::NewFlock(size_t count)
void Fractorium::OnActionNewFlock(bool checked) void Fractorium::OnActionNewFlock(bool checked)
{ {
m_Controller->NewFlock(m_Settings->RandomCount()); m_Controller->NewFlock(m_Settings->RandomCount());
m_Controller->SetEmber(0); m_Controller->SetEmber(0, false);
} }
/// <summary> /// <summary>
@ -102,7 +102,7 @@ void FractoriumEmberController<T>::NewEmptyFlameInCurrentFile()
m_EmberFile.m_Embers.push_back(ember);//Will invalidate the pointers contained in the EmberTreeWidgetItems, UpdateLibraryTree() will resync. m_EmberFile.m_Embers.push_back(ember);//Will invalidate the pointers contained in the EmberTreeWidgetItems, UpdateLibraryTree() will resync.
m_EmberFile.MakeNamesUnique(); m_EmberFile.MakeNamesUnique();
UpdateLibraryTree(); UpdateLibraryTree();
SetEmber(m_EmberFile.Size() - 1); SetEmber(m_EmberFile.Size() - 1, false);
} }
void Fractorium::OnActionNewEmptyFlameInCurrentFile(bool checked) { m_Controller->NewEmptyFlameInCurrentFile(); } void Fractorium::OnActionNewEmptyFlameInCurrentFile(bool checked) { m_Controller->NewEmptyFlameInCurrentFile(); }
@ -124,7 +124,7 @@ void FractoriumEmberController<T>::NewRandomFlameInCurrentFile()
m_EmberFile.m_Embers.push_back(ember);//Will invalidate the pointers contained in the EmberTreeWidgetItems, UpdateLibraryTree() will resync. m_EmberFile.m_Embers.push_back(ember);//Will invalidate the pointers contained in the EmberTreeWidgetItems, UpdateLibraryTree() will resync.
m_EmberFile.MakeNamesUnique(); m_EmberFile.MakeNamesUnique();
UpdateLibraryTree(); UpdateLibraryTree();
SetEmber(m_EmberFile.Size() - 1); SetEmber(m_EmberFile.Size() - 1, false);
} }
void Fractorium::OnActionNewRandomFlameInCurrentFile(bool checked) { m_Controller->NewRandomFlameInCurrentFile(); } void Fractorium::OnActionNewRandomFlameInCurrentFile(bool checked) { m_Controller->NewRandomFlameInCurrentFile(); }
@ -144,7 +144,7 @@ void FractoriumEmberController<T>::CopyFlameInCurrentFile()
m_EmberFile.m_Embers.push_back(ember);//Will invalidate the pointers contained in the EmberTreeWidgetItems, UpdateLibraryTree() will resync. m_EmberFile.m_Embers.push_back(ember);//Will invalidate the pointers contained in the EmberTreeWidgetItems, UpdateLibraryTree() will resync.
m_EmberFile.MakeNamesUnique(); m_EmberFile.MakeNamesUnique();
UpdateLibraryTree(); UpdateLibraryTree();
SetEmber(m_EmberFile.Size() - 1); SetEmber(m_EmberFile.Size() - 1, false);
} }
void Fractorium::OnActionCopyFlameInCurrentFile(bool checked) { m_Controller->CopyFlameInCurrentFile(); } void Fractorium::OnActionCopyFlameInCurrentFile(bool checked) { m_Controller->CopyFlameInCurrentFile(); }
@ -231,7 +231,7 @@ void FractoriumEmberController<T>::OpenAndPrepFiles(const QStringList& filenames
FillLibraryTree(append ? previousSize - 1 : 0); FillLibraryTree(append ? previousSize - 1 : 0);
ClearUndo(); ClearUndo();
SetEmber(previousSize); SetEmber(previousSize, false);
} }
} }
@ -365,14 +365,19 @@ void Fractorium::OnActionSaveCurrentScreen(bool checked)
/// <summary> /// <summary>
/// Save the current ember back to its position in the opened file. /// Save the current ember back to its position in the opened file.
/// This will not take any action if the previews are still rendering because
/// this writes to memory the preview renderer might be reading, and also stops the
/// preview renderer.
/// This does not save to disk. /// This does not save to disk.
/// </summary> /// </summary>
template <typename T> template <typename T>
void FractoriumEmberController<T>::SaveCurrentToOpenedFile() uint FractoriumEmberController<T>::SaveCurrentToOpenedFile()
{ {
uint i = 0; uint i = 0;
bool fileFound = false; bool fileFound = false;
if (!m_PreviewRunning)
{
for (auto& it : m_EmberFile.m_Embers) for (auto& it : m_EmberFile.m_Embers)
{ {
if (&it == m_EmberFilePointer)//Just compare memory addresses. if (&it == m_EmberFilePointer)//Just compare memory addresses.
@ -396,6 +401,9 @@ void FractoriumEmberController<T>::SaveCurrentToOpenedFile()
{ {
RenderPreviews(i, i + 1); RenderPreviews(i, i + 1);
} }
}
return i;
} }
/// <summary> /// <summary>
@ -419,9 +427,7 @@ void FractoriumEmberController<T>::Undo()
int index = m_Ember.GetTotalXformIndex(CurrentXform()); int index = m_Ember.GetTotalXformIndex(CurrentXform());
m_LastEditWasUndoRedo = true; m_LastEditWasUndoRedo = true;
m_UndoIndex = std::max<size_t>(0u, m_UndoIndex - 1u); m_UndoIndex = std::max<size_t>(0u, m_UndoIndex - 1u);
auto temp = m_EmberFilePointer;//m_EmberFilePointer will be set to point to whatever is passed in, which we don't want since it's coming from the undo list... SetEmber(m_UndoList[m_UndoIndex], true, false);//Don't update pointer because it's coming from the undo list...
SetEmber(m_UndoList[m_UndoIndex], true);
m_EmberFilePointer = temp;//...keep it pointing to the original one in the file.
m_EditState = eEditUndoState::UNDO_REDO; m_EditState = eEditUndoState::UNDO_REDO;
if (index >= 0) if (index >= 0)
@ -445,9 +451,7 @@ void FractoriumEmberController<T>::Redo()
int index = m_Ember.GetTotalXformIndex(CurrentXform()); int index = m_Ember.GetTotalXformIndex(CurrentXform());
m_LastEditWasUndoRedo = true; m_LastEditWasUndoRedo = true;
m_UndoIndex = std::min<size_t>(m_UndoIndex + 1, m_UndoList.size() - 1); m_UndoIndex = std::min<size_t>(m_UndoIndex + 1, m_UndoList.size() - 1);
auto temp = m_EmberFilePointer; SetEmber(m_UndoList[m_UndoIndex], true, false);
SetEmber(m_UndoList[m_UndoIndex], true);
m_EmberFilePointer = temp;//...keep it pointing to the original one in the file.
m_EditState = eEditUndoState::UNDO_REDO; m_EditState = eEditUndoState::UNDO_REDO;
if (index >= 0) if (index >= 0)
@ -552,7 +556,7 @@ void FractoriumEmberController<T>::PasteXmlAppend()
m_EmberFile.MakeNamesUnique(); m_EmberFile.MakeNamesUnique();
UpdateLibraryTree(); UpdateLibraryTree();
SetEmber(previousSize); SetEmber(previousSize, false);
} }
} }
@ -611,7 +615,7 @@ void FractoriumEmberController<T>::PasteXmlOver()
m_EmberFile.MakeNamesUnique(); m_EmberFile.MakeNamesUnique();
FillLibraryTree(); FillLibraryTree();
SetEmber(0); SetEmber(0, false);
} }
void Fractorium::OnActionPasteXmlOver(bool checked) { m_Controller->PasteXmlOver(); } void Fractorium::OnActionPasteXmlOver(bool checked) { m_Controller->PasteXmlOver(); }

View File

@ -455,7 +455,7 @@ bool FractoriumEmberController<T>::Render()
gl->update(); gl->update();
if (ProcessState() == eProcessState::ACCUM_DONE) if (ProcessState() == eProcessState::ACCUM_DONE)
SaveCurrentToOpenedFile(); SaveCurrentToOpenedFile();//Will not save if the previews are still rendering.
//Uncomment for debugging kernel build and execution errors. //Uncomment for debugging kernel build and execution errors.
//m_Fractorium->ui.InfoRenderingTextEdit->setText(QString::fromStdString(m_Fractorium->m_Wrapper.DumpInfo())); //m_Fractorium->ui.InfoRenderingTextEdit->setText(QString::fromStdString(m_Fractorium->m_Wrapper.DumpInfo()));
@ -671,6 +671,7 @@ bool Fractorium::CreateControllerFromOptions()
auto blur = m_PaletteBlurSpin->value(); auto blur = m_PaletteBlurSpin->value();
auto freq = m_PaletteFrequencySpin->value(); auto freq = m_PaletteFrequencySpin->value();
double scale; double scale;
uint current = 0;
#ifdef DO_DOUBLE #ifdef DO_DOUBLE
Ember<double> ed; Ember<double> ed;
EmberFile<double> efd; EmberFile<double> efd;
@ -686,6 +687,7 @@ bool Fractorium::CreateControllerFromOptions()
if (m_Controller.get()) if (m_Controller.get())
{ {
scale = m_Controller->LockedScale(); scale = m_Controller->LockedScale();
current = m_Controller->SaveCurrentToOpenedFile();
m_Controller->StopPreviewRender();//Must stop any previews first, else changing controllers will crash the program. m_Controller->StopPreviewRender();//Must stop any previews first, else changing controllers will crash the program.
m_Controller->CopyTempPalette(tempPalette);//Convert float to double or save double verbatim; m_Controller->CopyTempPalette(tempPalette);//Convert float to double or save double verbatim;
//Replace below with this once LLVM fixes a crash in their compiler with default lambda parameters.//TODO //Replace below with this once LLVM fixes a crash in their compiler with default lambda parameters.//TODO
@ -713,8 +715,8 @@ bool Fractorium::CreateControllerFromOptions()
if (m_Controller.get()) if (m_Controller.get())
{ {
ed.m_Palette = tempPalette;//Restore base temp palette. Adjustments will be then be applied and stored back in in m_Ember.m_Palette below. ed.m_Palette = tempPalette;//Restore base temp palette. Adjustments will be then be applied and stored back in in m_Ember.m_Palette below.
m_Controller->SetEmber(ed);//Convert float to double or set double verbatim. This will assign m_Ember.m_Palette (which was just tempPalette) to m_TempPalette.
m_Controller->SetEmberFile(efd); m_Controller->SetEmberFile(efd);
m_Controller->SetEmber(current, true);
m_Controller->LockedScale(scale); m_Controller->LockedScale(scale);
//Setting these and updating the GUI overwrites the work of clearing them done in SetEmber() above. //Setting these and updating the GUI overwrites the work of clearing them done in SetEmber() above.
//It's a corner case, but doesn't seem to matter. //It's a corner case, but doesn't seem to matter.

View File

@ -279,7 +279,7 @@ void FractoriumEmberController<T>::AddFinalXform()
Update([&]() Update([&]()
{ {
Xform<T> final; Xform<T> final;
final.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR));//Just a placeholder so other parts of the code don't see it as being empty. final.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR));//Just a placeholder so other parts of the code don't see it as being empty.
m_Ember.SetFinalXform(final); m_Ember.SetFinalXform(final);
int index = int(m_Ember.TotalXformCount() - 1);//Set index to the last item. int index = int(m_Ember.TotalXformCount() - 1);//Set index to the last item.
FillXforms(index); FillXforms(index);

View File

@ -84,8 +84,8 @@ void FractoriumEmberController<T>::FilteredVariations()
m_FilteredVariations.clear(); m_FilteredVariations.clear();
m_FilteredVariations.reserve(map.size()); m_FilteredVariations.reserve(map.size());
for (auto i = 0; i < m_VariationList.Size(); i++) for (auto i = 0; i < m_VariationList->Size(); i++)
if (auto var = m_VariationList.GetVariation(i)) if (auto var = m_VariationList->GetVariation(i))
if (map.contains(var->Name().c_str()) && map[var->Name().c_str()].toBool()) if (map.contains(var->Name().c_str()) && map[var->Name().c_str()].toBool())
m_FilteredVariations.push_back(var->VariationId()); m_FilteredVariations.push_back(var->VariationId());
} }
@ -107,9 +107,9 @@ void FractoriumEmberController<T>::SetupVariationsTree()
tree->clear(); tree->clear();
tree->blockSignals(true); tree->blockSignals(true);
for (size_t i = 0; i < m_VariationList.Size(); i++) for (size_t i = 0; i < m_VariationList->Size(); i++)
{ {
auto var = m_VariationList.GetVariation(i); auto var = m_VariationList->GetVariation(i);
auto parVar = dynamic_cast<const ParametricVariation<T>*>(var); auto parVar = dynamic_cast<const ParametricVariation<T>*>(var);
//First add the variation, with a spinner for its weight. //First add the variation, with a spinner for its weight.
auto item = new VariationTreeWidgetItem(var->VariationId(), tree); auto item = new VariationTreeWidgetItem(var->VariationId(), tree);
@ -206,7 +206,7 @@ void FractoriumEmberController<T>::VariationSpinBoxValueChanged(double d)//Would
{ {
UpdateXform([&](Xform<T>* xform) UpdateXform([&](Xform<T>* xform)
{ {
auto var = m_VariationList.GetVariation(sender->GetVariationId());//The variation attached to the sender, for reference only. auto var = m_VariationList->GetVariation(sender->GetVariationId());//The variation attached to the sender, for reference only.
auto parVar = dynamic_cast<const ParametricVariation<T>*>(var);//The parametric cast of that variation. auto parVar = dynamic_cast<const ParametricVariation<T>*>(var);//The parametric cast of that variation.
auto xformVar = xform->GetVariationById(var->VariationId());//The corresponding variation in the currently selected xform. auto xformVar = xform->GetVariationById(var->VariationId());//The corresponding variation in the currently selected xform.
auto widgetItem = sender->WidgetItem(); auto widgetItem = sender->WidgetItem();
@ -294,7 +294,7 @@ void FractoriumEmberController<T>::FillVariationTreeWithXform(Xform<T>* xform)
auto item = dynamic_cast<VariationTreeWidgetItem*>(tree->topLevelItem(i)); auto item = dynamic_cast<VariationTreeWidgetItem*>(tree->topLevelItem(i));
auto var = xform->GetVariationById(item->Id());//See if this variation in the tree was contained in the xform. auto var = xform->GetVariationById(item->Id());//See if this variation in the tree was contained in the xform.
auto parVar = dynamic_cast<ParametricVariation<T>*>(var);//Attempt cast to parametric variation for later. auto parVar = dynamic_cast<ParametricVariation<T>*>(var);//Attempt cast to parametric variation for later.
auto origParVar = dynamic_cast<const ParametricVariation<T>*>(m_VariationList.GetVariation(item->Id())); auto origParVar = dynamic_cast<const ParametricVariation<T>*>(m_VariationList->GetVariation(item->Id()));
if (auto spinBox = dynamic_cast<VariationTreeDoubleSpinBox*>(tree->itemWidget(item, 1)))//Get the widget for the item, and cast the widget to the VariationTreeDoubleSpinBox type. if (auto spinBox = dynamic_cast<VariationTreeDoubleSpinBox*>(tree->itemWidget(item, 1)))//Get the widget for the item, and cast the widget to the VariationTreeDoubleSpinBox type.
{ {

View File

@ -27,6 +27,8 @@ int main(int argc, char* argv[])
putenv(const_cast<char*>("GPU_MAX_ALLOC_PERCENT=100")); putenv(const_cast<char*>("GPU_MAX_ALLOC_PERCENT=100"));
#endif #endif
int rv = -1; int rv = -1;
auto vlf = VariationList<float>::Instance();//Create two instances that will stay alive until this function exits.
auto vld = VariationList<double>::Instance();//No further creations should occur after this.
try try
{ {

View File

@ -128,26 +128,26 @@ void FractoriumVariationsDialog::OnSelectNoneButtonClicked(bool checked)
void FractoriumVariationsDialog::Populate() void FractoriumVariationsDialog::Populate()
{ {
auto table = ui.VariationsTable; auto table = ui.VariationsTable;
int size = int(std::max<size_t>(std::max<size_t>(m_VariationList.RegSize(), m_VariationList.PreSize()), m_VariationList.PostSize())); int size = int(std::max<size_t>(std::max<size_t>(m_VariationList->RegSize(), m_VariationList->PreSize()), m_VariationList->PostSize()));
table->setRowCount(size); table->setRowCount(size);
for (auto i = 0; i < size; i++) for (auto i = 0; i < size; i++)
{ {
if (auto pre = m_VariationList.GetVariation(i, eVariationType::VARTYPE_PRE)) if (auto pre = m_VariationList->GetVariation(i, eVariationType::VARTYPE_PRE))
{ {
auto cb = new QTableWidgetItem(pre->Name().c_str()); auto cb = new QTableWidgetItem(pre->Name().c_str());
table->setItem(i, 0, cb); table->setItem(i, 0, cb);
SetCheckFromMap(cb, pre); SetCheckFromMap(cb, pre);
} }
if (auto reg = m_VariationList.GetVariation(i, eVariationType::VARTYPE_REG)) if (auto reg = m_VariationList->GetVariation(i, eVariationType::VARTYPE_REG))
{ {
auto cb = new QTableWidgetItem(reg->Name().c_str()); auto cb = new QTableWidgetItem(reg->Name().c_str());
table->setItem(i, 1, cb); table->setItem(i, 1, cb);
SetCheckFromMap(cb, reg); SetCheckFromMap(cb, reg);
} }
if (auto post = m_VariationList.GetVariation(i, eVariationType::VARTYPE_POST)) if (auto post = m_VariationList->GetVariation(i, eVariationType::VARTYPE_POST))
{ {
auto cb = new QTableWidgetItem(post->Name().c_str()); auto cb = new QTableWidgetItem(post->Name().c_str());
table->setItem(i, 2, cb); table->setItem(i, 2, cb);
@ -209,7 +209,7 @@ void FractoriumVariationsDialog::DataToGui()
{ {
ForEachCell([&](QTableWidgetItem * cb) ForEachCell([&](QTableWidgetItem * cb)
{ {
if (auto var = m_VariationList.GetVariation(cb->text().toStdString())) if (auto var = m_VariationList->GetVariation(cb->text().toStdString()))
SetCheckFromMap(cb, var); SetCheckFromMap(cb, var);
}); });
} }
@ -221,7 +221,7 @@ void FractoriumVariationsDialog::GuiToData()
{ {
ForEachCell([&](QTableWidgetItem * cb) ForEachCell([&](QTableWidgetItem * cb)
{ {
if (auto var = m_VariationList.GetVariation(cb->text().toStdString())) if (auto var = m_VariationList->GetVariation(cb->text().toStdString()))
m_Vars[cb->text()] = (cb->checkState() == Qt::Checked); m_Vars[cb->text()] = (cb->checkState() == Qt::Checked);
}); });
} }

View File

@ -41,7 +41,7 @@ private:
void GuiToData(); void GuiToData();
void Populate(); void Populate();
void SetCheckFromMap(QTableWidgetItem* cb, const Variation<float>* var); void SetCheckFromMap(QTableWidgetItem* cb, const Variation<float>* var);
VariationList<float>& m_VariationList; shared_ptr<VariationList<float>> m_VariationList;
QMap<QString, QVariant> m_Vars; QMap<QString, QVariant> m_Vars;
FractoriumSettings* m_Settings; FractoriumSettings* m_Settings;
Ui::VariationsDialog ui; Ui::VariationsDialog ui;