0.4.0.9 Beta 07/27/2014

0.4.0.9 Beta 07/27/2014
--User Changes
Properly set tab order on all controls.
Calculate and report iters/second in the final render dialog.
Immediately draw yellow dot on xform mouse down on previously unselected
xform.

--Bug Fixes
Fix GlynnSim1, GlynnSim2, GlynnSim3 and juliaNab by ensuring the first
argument to pow() is >= 0.
Ensure OpenCL platform and device combo boxes in the final render dialog
expand as needed.

--Code Changes
Make VariationTreeSpinbox take its parent VariationTreeWidgetItem as a
constructor argument. This makes SetupVariationTree() and
VariationSpinBoxValueChanged() more efficient.
Make Interference2 and ho use fabs().
This commit is contained in:
mfeemster 2014-07-27 22:25:38 -07:00
parent a5d69c75a2
commit 88a325a5cd
28 changed files with 561 additions and 111 deletions

3
.gitignore vendored
View File

@ -35,4 +35,5 @@ Builds/MSVC/VS2010/Obj/EmberTester/x64/Debug/EmberTester_manifest.rc
Builds/MSVC/VS2010/Obj/EmberRender/x64/Debug/EmberRender_manifest.rc Builds/MSVC/VS2010/Obj/EmberRender/x64/Debug/EmberRender_manifest.rc
Builds/MSVC/VS2010/Obj/EmberGenome/x64/Debug/EmberGenome_manifest.rc Builds/MSVC/VS2010/Obj/EmberGenome/x64/Debug/EmberGenome_manifest.rc
Builds/MSVC/VS2010/Obj/EmberAnimate/x64/Debug/EmberAnimate_manifest.rc Builds/MSVC/VS2010/Obj/EmberAnimate/x64/Debug/EmberAnimate_manifest.rc
Builds/MSVC/VS2010/Obj/Ember/x64/Debug/Ember_manifest.rc Builds/MSVC/VS2010/Obj/Ember/x64/Debug/Ember_manifest.rc
Bin/x64/Release/testallvarsout.flame

View File

@ -6,7 +6,7 @@
<ProductVersion>3.7</ProductVersion> <ProductVersion>3.7</ProductVersion>
<ProjectGuid>{c8096c47-e358-438c-a520-146d46b0637d}</ProjectGuid> <ProjectGuid>{c8096c47-e358-438c-a520-146d46b0637d}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<OutputName>Fractorium_Beta_0.4.0.8</OutputName> <OutputName>Fractorium_Beta_0.4.0.9</OutputName>
<OutputType>Package</OutputType> <OutputType>Package</OutputType>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath> <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath> <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define ProductVersion="0.4.0.8" ?> <?define ProductVersion="0.4.0.9" ?>
<?define ProductName="Fractorium Beta $(var.ProductVersion) ($(var.GpuType))" ?> <?define ProductName="Fractorium Beta $(var.ProductVersion) ($(var.GpuType))" ?>
<?define UpgradeCode="{4714cd15-bfba-44f6-8059-9e1466ebfa6e}"?> <?define UpgradeCode="{4714cd15-bfba-44f6-8059-9e1466ebfa6e}"?>
<?define Manufacturer="Fractorium"?> <?define Manufacturer="Fractorium"?>
@ -13,7 +13,7 @@
<!-- <!--
Change this for every release. Change this for every release.
--> -->
<?define ProductCode="{567692F8-C869-4EEA-98C4-5D69982F9F76}"?> <?define ProductCode="{FCD71232-4553-4224-9328-A1B039A5A773}"?>
<Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)"> <Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
<Package <Package

BIN
Data/Bench.xlsx Normal file

Binary file not shown.

View File

@ -1,3 +1,17 @@
0.4.0.9 Beta 07/27/2014
--User Changes
Properly set tab order on all controls.
Calculate and report iters/second in the final render dialog.
Immediately draw yellow dot on xform mouse down on previously unselected xform.
--Bug Fixes
Fix GlynnSim1, GlynnSim2, GlynnSim3 and juliaNab by ensuring the first argument to pow() is >= 0.
Ensure OpenCL platform and device combo boxes in the final render dialog expand as needed.
--Code Changes
Make VariationTreeSpinbox take its parent VariationTreeWidgetItem as a constructor argument. This makes SetupVariationTree() and VariationSpinBoxValueChanged() more efficient.
Make Interference2 and ho use fabs().
0.4.0.8 Beta 07/26/2014 0.4.0.8 Beta 07/26/2014
--Bug Fixes --Bug Fixes
Fix falloff, falloff2, falloff3. Fix falloff, falloff2, falloff3.

View File

@ -25,7 +25,7 @@ namespace EmberNs
extern void sincos(double x, double *s, double *c); extern void sincos(double x, double *s, double *c);
#endif #endif
#define EMBER_VERSION "0.4.0.8" #define EMBER_VERSION "0.4.0.9"
#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

View File

@ -3473,7 +3473,7 @@ public:
{ {
T wx = m_Weight * T(1.3029400317411197908970256609023);//This precision came from the original. T wx = m_Weight * T(1.3029400317411197908970256609023);//This precision came from the original.
T y2 = helper.In.y * 2; T y2 = helper.In.y * 2;
T r = wx * sqrt(fabs(helper.In.y * helper.In.x) / Zeps(helper.In.x * helper.In.x + y2 * y2)); T r = wx * sqrt(fabs(helper.In.y * helper.In.x) / Zeps(SQR(helper.In.x) + SQR(y2)));
helper.Out.x = r * helper.In.x; helper.Out.x = r * helper.In.x;
helper.Out.y = r * y2; helper.Out.y = r * y2;
@ -3488,7 +3488,7 @@ public:
ss << "\t{\n" ss << "\t{\n"
<< "\t\treal_t wx = xform->m_VariationWeights[" << varIndex << "] * 1.3029400317411197908970256609023;\n" << "\t\treal_t wx = xform->m_VariationWeights[" << varIndex << "] * 1.3029400317411197908970256609023;\n"
<< "\t\treal_t y2 = vIn.y * 2.0;\n" << "\t\treal_t y2 = vIn.y * 2.0;\n"
<< "\t\treal_t r = wx * sqrt(fabs(vIn.y * vIn.x) / Zeps(vIn.x * vIn.x + y2 * y2));\n" << "\t\treal_t r = wx * sqrt(fabs(vIn.y * vIn.x) / Zeps(SQR(vIn.x) + SQR(y2)));\n"
<< "\n" << "\n"
<< "\t\tvOut.x = r * vIn.x;\n" << "\t\tvOut.x = r * vIn.x;\n"
<< "\t\tvOut.y = r * y2;\n" << "\t\tvOut.y = r * y2;\n"

View File

@ -424,7 +424,7 @@ public:
void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand)
{ {
T x, y, z, alpha = m_Radius / helper.m_PrecalcSqrtSumSquares; T x, y, z;
if (helper.m_PrecalcSqrtSumSquares < m_Radius)//Object generation. if (helper.m_PrecalcSqrtSumSquares < m_Radius)//Object generation.
{ {
@ -434,6 +434,8 @@ public:
} }
else else
{ {
T alpha = fabs(m_Radius / Zeps(helper.m_PrecalcSqrtSumSquares));//Original did not fabs().
if (rand.Frand01<T>() > m_Contrast * pow(alpha, m_Pow)) if (rand.Frand01<T>() > m_Contrast * pow(alpha, m_Pow))
{ {
x = helper.In.x; x = helper.In.x;
@ -479,7 +481,7 @@ public:
string y1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string y1 = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n" ss << "\t{\n"
<< "\t\treal_t x, y, z, alpha = " << radius << " / precalcSqrtSumSquares;\n" << "\t\treal_t x, y, z;\n"
<< "\n" << "\n"
<< "\t\tif (precalcSqrtSumSquares < " << radius << ")\n" << "\t\tif (precalcSqrtSumSquares < " << radius << ")\n"
<< "\t\t{\n" << "\t\t{\n"
@ -489,6 +491,8 @@ public:
<< "\t\t}\n" << "\t\t}\n"
<< "\t\telse\n" << "\t\telse\n"
<< "\t\t{\n" << "\t\t{\n"
<< "\t\t real_t alpha = fabs(" << radius << " / Zeps(precalcSqrtSumSquares));\n"
<< "\n"
<< "\t\t if (MwcNext01(mwc) > " << contrast << " * pow(alpha, " << pow << "))\n" << "\t\t if (MwcNext01(mwc) > " << contrast << " * pow(alpha, " << pow << "))\n"
<< "\t\t {\n" << "\t\t {\n"
<< "\t\t x = vIn.x;\n" << "\t\t x = vIn.x;\n"
@ -602,7 +606,7 @@ public:
void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand)
{ {
T x, y, alpha = m_Radius / helper.m_PrecalcSqrtSumSquares; T x, y;
if (helper.m_PrecalcSqrtSumSquares < m_Radius) if (helper.m_PrecalcSqrtSumSquares < m_Radius)
{ {
@ -612,6 +616,8 @@ public:
} }
else else
{ {
T alpha = fabs(m_Radius / Zeps(helper.m_PrecalcSqrtSumSquares));//Original did not fabs().
if (rand.Frand01<T>() > m_Contrast * pow(alpha, m_Pow)) if (rand.Frand01<T>() > m_Contrast * pow(alpha, m_Pow))
{ {
helper.Out.x = m_Weight * helper.In.x; helper.Out.x = m_Weight * helper.In.x;
@ -645,7 +651,7 @@ public:
string delta = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string delta = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n" ss << "\t{\n"
<< "\t\treal_t x, y, alpha = " << radius << " / precalcSqrtSumSquares;\n" << "\t\treal_t x, y;\n"
<< "\n" << "\n"
<< "\t\tif (precalcSqrtSumSquares < " << radius << ")\n" << "\t\tif (precalcSqrtSumSquares < " << radius << ")\n"
<< "\t\t{\n" << "\t\t{\n"
@ -655,6 +661,8 @@ public:
<< "\t\t}\n" << "\t\t}\n"
<< "\t\telse\n" << "\t\telse\n"
<< "\t\t{\n" << "\t\t{\n"
<< "\t\t real_t alpha = fabs(" << radius << " / Zeps(precalcSqrtSumSquares));\n"
<< "\n"
<< "\t\t if (MwcNext01(mwc) > " << contrast << " * pow(alpha, " << pow << "))\n" << "\t\t if (MwcNext01(mwc) > " << contrast << " * pow(alpha, " << pow << "))\n"
<< "\t\t {\n" << "\t\t {\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n"
@ -692,9 +700,9 @@ public:
virtual void Precalc() virtual void Precalc()
{ {
m_Pow = fabs(m_Pow); m_Pow = fabs(m_Pow);
m_Phi10 = M_2PI * m_Phi1; m_Phi10 = T(M_PI) * m_Phi1 / 180;
m_Phi20 = M_2PI * m_Phi2; m_Phi20 = T(M_PI) * m_Phi2 / 180;
m_Gamma = m_Thickness * (2 * m_Radius + m_Thickness) / (m_Radius + m_Thickness); m_Gamma = m_Thickness * (2 * m_Radius + m_Thickness) / Zeps(m_Radius + m_Thickness);
m_Delta = m_Phi20 - m_Phi10; m_Delta = m_Phi20 - m_Phi10;
} }
@ -756,7 +764,7 @@ public:
void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand)
{ {
T x, y, alpha = m_Radius / helper.m_PrecalcSqrtSumSquares; T x, y;
if (helper.m_PrecalcSqrtSumSquares < m_Radius1) if (helper.m_PrecalcSqrtSumSquares < m_Radius1)
{ {
@ -766,6 +774,8 @@ public:
} }
else else
{ {
T alpha = fabs(m_Radius / Zeps(helper.m_PrecalcSqrtSumSquares));//Original did not fabs().
if (rand.Frand01<T>() > m_Contrast * pow(alpha, m_Pow)) if (rand.Frand01<T>() > m_Contrast * pow(alpha, m_Pow))
{ {
helper.Out.x = m_Weight * helper.In.x; helper.Out.x = m_Weight * helper.In.x;
@ -797,7 +807,7 @@ public:
string gamma = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string gamma = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n" ss << "\t{\n"
<< "\t\treal_t x, y, alpha = " << radius << " / precalcSqrtSumSquares;\n" << "\t\treal_t x, y;\n"
<< "\n" << "\n"
<< "\t\tif (precalcSqrtSumSquares < " << radius1 << ")\n" << "\t\tif (precalcSqrtSumSquares < " << radius1 << ")\n"
<< "\t\t{\n" << "\t\t{\n"
@ -807,6 +817,8 @@ public:
<< "\t\t}\n" << "\t\t}\n"
<< "\t\telse\n" << "\t\telse\n"
<< "\t\t{\n" << "\t\t{\n"
<< "\t\t real_t alpha = fabs(" << radius << " / Zeps(precalcSqrtSumSquares));\n"
<< "\n"
<< "\t\t if (MwcNext01(mwc) > " << contrast << " * pow(alpha, " << pow << "))\n" << "\t\t if (MwcNext01(mwc) > " << contrast << " * pow(alpha, " << pow << "))\n"
<< "\t\t {\n" << "\t\t {\n"
<< "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n" << "\t\t vOut.x = xform->m_VariationWeights[" << varIndex << "] * vIn.x;\n"
@ -849,8 +861,8 @@ public:
virtual void Precalc() virtual void Precalc()
{ {
m_Radius1 = m_Radius + m_Thickness; m_Radius1 = m_Radius + m_Thickness;
m_Radius2 = SQR(m_Radius) / m_Radius1; m_Radius2 = SQR(m_Radius) / Zeps(m_Radius1);
m_Gamma = m_Radius1 / (m_Radius1 + m_Radius2); m_Gamma = m_Radius1 / Zeps(m_Radius1 + m_Radius2);
} }
protected: protected:
@ -1045,18 +1057,13 @@ public:
return ss.str(); return ss.str();
} }
virtual void Precalc()
{
ClampGte0Ref<T>(m_Power);
}
protected: protected:
void Init() void Init()
{ {
string prefix = Prefix(); string prefix = Prefix();
m_Params.clear(); m_Params.clear();
m_Params.push_back(ParamWithName<T>(&m_Power, prefix + "sineblur_power", 1)); m_Params.push_back(ParamWithName<T>(&m_Power, prefix + "sineblur_power", 1, REAL, 0));
} }
private: private:

View File

@ -1231,7 +1231,7 @@ public:
{ {
T jun = Zeps(fabs(m_N)); T jun = Zeps(fabs(m_N));
T a = (atan2(helper.In.y, pow(helper.In.x, m_Sep)) + M_2PI * Floor<T>(rand.Frand01<T>() * m_AbsN)) / jun; T a = (atan2(helper.In.y, pow(fabs(helper.In.x), m_Sep)) + M_2PI * Floor<T>(rand.Frand01<T>() * m_AbsN)) / jun;
T r = m_Weight * pow(helper.m_PrecalcSumSquares, m_Cn * m_A); T r = m_Weight * pow(helper.m_PrecalcSumSquares, m_Cn * m_A);
helper.Out.x = r * cos(a) + m_B; helper.Out.x = r * cos(a) + m_B;
@ -1255,7 +1255,7 @@ public:
ss << "\t{\n" ss << "\t{\n"
<< "\t\treal_t jun = Zeps(fabs(" << n << "));\n" << "\t\treal_t jun = Zeps(fabs(" << n << "));\n"
<< "\n" << "\n"
<< "\t\treal_t a = (atan2(vIn.y, pow(vIn.x, " << sep << ")) + M_2PI * floor(MwcNext01(mwc) * " << absN << ")) / jun;\n" << "\t\treal_t a = (atan2(vIn.y, pow(fabs(vIn.x), " << sep << ")) + M_2PI * floor(MwcNext01(mwc) * " << absN << ")) / jun;\n"
<< "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * pow(precalcSumSquares, " << cn << " * " << a << ");\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * pow(precalcSumSquares, " << cn << " * " << a << ");\n"
<< "\n" << "\n"
<< "\t\tvOut.x = r * cos(a) + " << b << ";\n" << "\t\tvOut.x = r * cos(a) + " << b << ";\n"
@ -1709,8 +1709,8 @@ public:
pr1 = m_An2_1 * pow(fabs(mcosr), m_N2_1) + m_Bn3_1 * pow(fabs(msinr), m_N3_1); pr1 = m_An2_1 * pow(fabs(mcosr), m_N2_1) + m_Bn3_1 * pow(fabs(msinr), m_N3_1);
pr2 = m_An2_2 * pow(fabs(mcosp), m_N2_2) + m_Bn3_2 * pow(fabs(msinp), m_N3_2); pr2 = m_An2_2 * pow(fabs(mcosp), m_N2_2) + m_Bn3_2 * pow(fabs(msinp), m_N3_2);
r1 = pow(pr1, m_N1_1) + m_Spiral * rho1; r1 = pow(fabs(pr1), m_N1_1) + m_Spiral * rho1;
r2 = pow(pr2, m_N1_2); r2 = pow(fabs(pr2), m_N1_2);
if ((int)m_Toroidmap == 1) if ((int)m_Toroidmap == 1)
{ {
@ -1784,8 +1784,8 @@ public:
<< "\n" << "\n"
<< "\t\tpr1 = " << an2_1 << " * pow(fabs(mcosr), " << n2_1 << ") + " << bn3_1 << " * pow(fabs(msinr), " << n3_1 << ");\n" << "\t\tpr1 = " << an2_1 << " * pow(fabs(mcosr), " << n2_1 << ") + " << bn3_1 << " * pow(fabs(msinr), " << n3_1 << ");\n"
<< "\t\tpr2 = " << an2_2 << " * pow(fabs(mcosp), " << n2_2 << ") + " << bn3_2 << " * pow(fabs(msinp), " << n3_2 << ");\n" << "\t\tpr2 = " << an2_2 << " * pow(fabs(mcosp), " << n2_2 << ") + " << bn3_2 << " * pow(fabs(msinp), " << n3_2 << ");\n"
<< "\t\tr1 = pow(pr1, " << n1_1 << ") + " << spiral << " * rho1;\n" << "\t\tr1 = pow(fabs(pr1), " << n1_1 << ") + " << spiral << " * rho1;\n"
<< "\t\tr2 = pow(pr2, " << n1_2 << ");\n" << "\t\tr2 = pow(fabs(pr2), " << n1_2 << ");\n"
<< "\n" << "\n"
<< "\t\tif ((int)" << toroid << " == 1)\n" << "\t\tif ((int)" << toroid << " == 1)\n"
<< "\t\t{\n" << "\t\t{\n"
@ -3083,12 +3083,12 @@ public:
return return
"real_t Interference2Sine(real_t a, real_t b, real_t c, real_t p, real_t x)\n" "real_t Interference2Sine(real_t a, real_t b, real_t c, real_t p, real_t x)\n"
"{\n" "{\n"
" return a * pow(ClampGte(sin(b * x + c), EPS), p);\n" " return a * pow(fabs(sin(b * x + c)), p);\n"
"}\n" "}\n"
"\n" "\n"
"real_t Interference2Tri(real_t a, real_t b, real_t c, real_t p, real_t x)\n" "real_t Interference2Tri(real_t a, real_t b, real_t c, real_t p, real_t x)\n"
"{\n" "{\n"
" return a * 2 * pow(ClampGte(asin(cos(b * x + c - M_PI_2)), EPS) * M_1_PI, p);\n" " return a * 2 * pow(fabs(asin(cos(b * x + c - M_PI_2))) * M_1_PI, p);\n"
"}\n" "}\n"
"\n" "\n"
"real_t Interference2Squ(real_t a, real_t b, real_t c, real_t p, real_t x)\n" "real_t Interference2Squ(real_t a, real_t b, real_t c, real_t p, real_t x)\n"
@ -3119,12 +3119,12 @@ protected:
private: private:
inline static T Sine(T a, T b, T c, T p, T x) inline static T Sine(T a, T b, T c, T p, T x)
{ {
return a * pow(ClampGte<T>(sin(b * x + c), EPS), p);//Original did not clamp. return a * pow(fabs(sin(b * x + c)), p);//Original did not fabs().
} }
inline static T Tri(T a, T b, T c, T p, T x) inline static T Tri(T a, T b, T c, T p, T x)
{ {
return a * 2 * pow(ClampGte<T>(asin(cos(b * x + c - T(M_PI_2))), EPS) * T(M_1_PI), p);//Original did not clamp. return a * 2 * pow(fabs(asin(cos(b * x + c - T(M_PI_2)))) * T(M_1_PI), p);//Original did not fabs().
} }
inline static T Squ(T a, T b, T c, T p, T x) inline static T Squ(T a, T b, T c, T p, T x)

View File

@ -1085,9 +1085,9 @@ public:
T cv = cos(helper.In.y); T cv = cos(helper.In.y);
T cucv = cu * cv; T cucv = cu * cv;
T sucv = su * cv; T sucv = su * cv;
T x = pow(ClampGte<T>(cucv, EPS), m_XPow) + (cucv * m_XPow) + (T(0.25) * atOmegaX);//Must clamp first argument to pow, because negative values will return NaN. T x = pow(fabs(cucv), m_XPow) + (cucv * m_XPow) + (T(0.25) * atOmegaX);//Must fabs first argument to pow, because negative values will return NaN.
T y = pow(ClampGte<T>(sucv, EPS), m_YPow) + (sucv * m_YPow) + (T(0.25) * atOmegaY);//Original did not do this and would frequently return bad values. T y = pow(fabs(sucv), m_YPow) + (sucv * m_YPow) + (T(0.25) * atOmegaY);//Original did not do this and would frequently return bad values.
T z = pow(ClampGte<T>(sv, EPS), m_ZPow) + sv * m_ZPow; T z = pow(fabs(sv), m_ZPow) + sv * m_ZPow;
helper.Out.x = m_Weight * x; helper.Out.x = m_Weight * x;
helper.Out.y = m_Weight * y; helper.Out.y = m_Weight * y;
@ -1117,9 +1117,9 @@ public:
<< "\t\treal_t cv = cos(vIn.y);\n" << "\t\treal_t cv = cos(vIn.y);\n"
<< "\t\treal_t cucv = cu * cv;\n" << "\t\treal_t cucv = cu * cv;\n"
<< "\t\treal_t sucv = su * cv;\n" << "\t\treal_t sucv = su * cv;\n"
<< "\t\treal_t x = pow(ClampGte(cucv, EPS), " << xpow << ") + (cucv * " << xpow << ") + (0.25 * atOmegaX);\n" << "\t\treal_t x = pow(fabs(cucv), " << xpow << ") + (cucv * " << xpow << ") + (0.25 * atOmegaX);\n"
<< "\t\treal_t y = pow(ClampGte(sucv, EPS), " << ypow << ") + (sucv * " << ypow << ") + (0.25 * atOmegaY);\n" << "\t\treal_t y = pow(fabs(sucv), " << ypow << ") + (sucv * " << ypow << ") + (0.25 * atOmegaY);\n"
<< "\t\treal_t z = pow(ClampGte(sv, EPS), " << zpow << ") + sv * " << zpow << ";\n" << "\t\treal_t z = pow(fabs(sv), " << zpow << ") + sv * " << zpow << ";\n"
<< "\n" << "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * x;\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * x;\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * y;\n" << "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * y;\n"
@ -2151,8 +2151,8 @@ public:
case 2://Box. case 2://Box.
scale = Clamp<T>(rs, 0, T(0.9)) + T(0.1); scale = Clamp<T>(rs, 0, T(0.9)) + T(0.1);
denom = 1 / scale; denom = 1 / scale;
helper.Out.x = m_Weight * Lerp<T>(helper.In.x, floor(helper.In.x * denom) + scale * ax, m_MulX * rs) + m_MulX * pow(ax, m_BoxPow) * rs * denom; helper.Out.x = m_Weight * Lerp<T>(helper.In.x, floor(helper.In.x * denom) + scale * ax, m_MulX * rs) + m_MulX * pow(ax, m_BoxPow) * rs * denom;//m_BoxPow should be an integer value held in T,
helper.Out.y = m_Weight * Lerp<T>(helper.In.y, floor(helper.In.y * denom) + scale * ay, m_MulY * rs) + m_MulY * pow(ay, m_BoxPow) * rs * denom; helper.Out.y = m_Weight * Lerp<T>(helper.In.y, floor(helper.In.y * denom) + scale * ay, m_MulY * rs) + m_MulY * pow(ay, m_BoxPow) * rs * denom;//so fabs() shouldn't be necessary.
helper.Out.z = m_Weight * Lerp<T>(helper.In.z, floor(helper.In.z * denom) + scale * az, m_MulZ * rs) + m_MulZ * pow(az, m_BoxPow) * rs * denom; helper.Out.z = m_Weight * Lerp<T>(helper.In.z, floor(helper.In.z * denom) + scale * az, m_MulZ * rs) + m_MulZ * pow(az, m_BoxPow) * rs * denom;
break; break;
} }

View File

@ -49,8 +49,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,4,0,8 FILEVERSION 0,4,0,9
PRODUCTVERSION 0,4,0,8 PRODUCTVERSION 0,4,0,9
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -67,12 +67,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Open Source" VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Renders fractal flames as animations with motion blur" VALUE "FileDescription", "Renders fractal flames as animations with motion blur"
VALUE "FileVersion", "0.4.0.8" VALUE "FileVersion", "0.4.0.9"
VALUE "InternalName", "EmberAnimate.rc" VALUE "InternalName", "EmberAnimate.rc"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3" VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3"
VALUE "OriginalFilename", "EmberAnimate.rc" VALUE "OriginalFilename", "EmberAnimate.rc"
VALUE "ProductName", "Ember Animate" VALUE "ProductName", "Ember Animate"
VALUE "ProductVersion", "0.4.0.8" VALUE "ProductVersion", "0.4.0.9"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -49,8 +49,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,4,0,8 FILEVERSION 0,4,0,9
PRODUCTVERSION 0,4,0,8 PRODUCTVERSION 0,4,0,9
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -67,12 +67,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Open Source" VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Manipulates fractal flames parameter files" VALUE "FileDescription", "Manipulates fractal flames parameter files"
VALUE "FileVersion", "0.4.0.8" VALUE "FileVersion", "0.4.0.9"
VALUE "InternalName", "EmberGenome.rc" VALUE "InternalName", "EmberGenome.rc"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3" VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3"
VALUE "OriginalFilename", "EmberGenome.rc" VALUE "OriginalFilename", "EmberGenome.rc"
VALUE "ProductName", "Ember Genome" VALUE "ProductName", "Ember Genome"
VALUE "ProductVersion", "0.4.0.8" VALUE "ProductVersion", "0.4.0.9"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -49,8 +49,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,4,0,8 FILEVERSION 0,4,0,9
PRODUCTVERSION 0,4,0,8 PRODUCTVERSION 0,4,0,9
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -67,12 +67,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Open Source" VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Renders fractal flames as single images" VALUE "FileDescription", "Renders fractal flames as single images"
VALUE "FileVersion", "0.4.0.8" VALUE "FileVersion", "0.4.0.9"
VALUE "InternalName", "EmberRender.rc" VALUE "InternalName", "EmberRender.rc"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3" VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3"
VALUE "OriginalFilename", "EmberRender.rc" VALUE "OriginalFilename", "EmberRender.rc"
VALUE "ProductName", "Ember Render" VALUE "ProductName", "Ember Render"
VALUE "ProductVersion", "0.4.0.8" VALUE "ProductVersion", "0.4.0.9"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -52,7 +52,7 @@
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;br/&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Fractorium 0.4.0.8 Beta&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;&lt;br/&gt;A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Matt Feemster&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;br/&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Fractorium 0.4.0.9 Beta&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;&lt;br/&gt;A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Matt Feemster&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="textFormat"> <property name="textFormat">
<enum>Qt::RichText</enum> <enum>Qt::RichText</enum>

View File

@ -45,6 +45,12 @@ private:
double m_SmallStep; double m_SmallStep;
}; };
/// <summary>
/// VariationTreeWidgetItem and VariationTreeDoubleSpinBox need each other, but each can't include the other.
/// So VariationTreeWidgetItem includes this file, and use a forward declaration here.
/// </summary>
template <typename T> class VariationTreeWidgetItem;
/// <summary> /// <summary>
/// Derivation for the double spin boxes that are in the /// Derivation for the double spin boxes that are in the
/// variations tree. /// variations tree.
@ -57,13 +63,15 @@ public:
/// Constructor that passes agruments to the base and assigns the m_Param and m_Variation members. /// Constructor that passes agruments to the base and assigns the m_Param and m_Variation members.
/// </summary> /// </summary>
/// <param name="parent">The parent widget</param> /// <param name="parent">The parent widget</param>
/// <param name="widgetItem">The widget item this spinner is contained in</param>
/// <param name="var">The variation this spinner is for</param> /// <param name="var">The variation this spinner is for</param>
/// <param name="param">The name of the parameter this is for</param> /// <param name="param">The name of the parameter this is for</param>
/// <param name="height">The height of the spin box. Default: 16.</param> /// <param name="height">The height of the spin box. Default: 16.</param>
/// <param name="step">The step used to increment/decrement the spin box when using the mouse wheel. Default: 0.05.</param> /// <param name="step">The step used to increment/decrement the spin box when using the mouse wheel. Default: 0.05.</param>
explicit VariationTreeDoubleSpinBox(QWidget* parent, Variation<T>* var, string param, int height = 16, double step = 0.05) explicit VariationTreeDoubleSpinBox(QWidget* parent, VariationTreeWidgetItem<T>* widgetItem, Variation<T>* var, string param, int height = 16, double step = 0.05)
: DoubleSpinBox(parent, height, step) : DoubleSpinBox(parent, height, step)
{ {
m_WidgetItem = widgetItem;
m_Param = param; m_Param = param;
m_Variation = var; m_Variation = var;
setDecimals(3); setDecimals(3);
@ -73,8 +81,10 @@ public:
bool IsParam() { return !m_Param.empty(); } bool IsParam() { return !m_Param.empty(); }
string ParamName() { return m_Param; } string ParamName() { return m_Param; }
Variation<T>* GetVariation() { return m_Variation; } Variation<T>* GetVariation() { return m_Variation; }
VariationTreeWidgetItem<T>* WidgetItem() { return m_WidgetItem; }
private: private:
string m_Param; string m_Param;
Variation<T>* m_Variation; Variation<T>* m_Variation;
VariationTreeWidgetItem<T>* m_WidgetItem;
}; };

View File

@ -119,6 +119,38 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(FractoriumSettings* set
s.setHeight(min(s.height(), (int)((double)desktopHeight * 0.90))); s.setHeight(min(s.height(), (int)((double)desktopHeight * 0.90)));
setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, s, qApp->desktop()->availableGeometry())); setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, s, qApp->desktop()->availableGeometry()));
QWidget* w = SetTabOrder(this, ui.FinalRenderEarlyClipCheckBox, ui.FinalRenderYAxisUpCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderTransparencyCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderOpenCLCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderDoublePrecisionCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderSaveXmlCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderDoAllCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderDoSequenceCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderKeepAspectCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderScaleNoneRadioButton);
w = SetTabOrder(this, w, ui.FinalRenderScaleWidthRadioButton);
w = SetTabOrder(this, w, ui.FinalRenderScaleHeightRadioButton);
w = SetTabOrder(this, w, ui.FinalRenderJpgRadioButton);
w = SetTabOrder(this, w, ui.FinalRenderPngRadioButton);
w = SetTabOrder(this, w, ui.FinalRenderPlatformCombo);
w = SetTabOrder(this, w, ui.FinalRenderDeviceCombo);
w = SetTabOrder(this, w, ui.FinalRenderThreadCountSpin);
w = SetTabOrder(this, w, m_WidthSpin);
w = SetTabOrder(this, w, m_HeightSpin);
w = SetTabOrder(this, w, m_QualitySpin);
w = SetTabOrder(this, w, m_TemporalSamplesSpin);
w = SetTabOrder(this, w, m_SupersampleSpin);
w = SetTabOrder(this, w, tbw);
w = SetTabOrder(this, w, tbw->m_Button1);
w = SetTabOrder(this, w, tbw->m_Button2);
w = SetTabOrder(this, w, m_PrefixEdit);
w = SetTabOrder(this, w, m_SuffixEdit);
w = SetTabOrder(this, w, ui.FinalRenderTextOutput);
w = SetTabOrder(this, w, ui.StartRenderButton);
w = SetTabOrder(this, w, ui.StopRenderButton);
w = SetTabOrder(this, w, ui.CloseButton);
} }
/// <summary> /// <summary>

View File

@ -46,6 +46,9 @@
</property> </property>
<item> <item>
<widget class="QScrollArea" name="scrollArea"> <widget class="QScrollArea" name="scrollArea">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
@ -352,44 +355,44 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QComboBox" name="FinalRenderDeviceCombo"> <widget class="QComboBox" name="FinalRenderPlatformCombo">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>320</width> <width>0</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>320</width> <width>16777215</width>
<height>16777215</height> <height>16777215</height>
</size> </size>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QComboBox" name="FinalRenderPlatformCombo"> <widget class="QComboBox" name="FinalRenderDeviceCombo">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>320</width> <width>0</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>320</width> <width>16777215</width>
<height>16777215</height> <height>16777215</height>
</size> </size>
</property> </property>
@ -476,6 +479,9 @@
<property name="gridStyle"> <property name="gridStyle">
<enum>Qt::SolidLine</enum> <enum>Qt::SolidLine</enum>
</property> </property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="cornerButtonEnabled"> <property name="cornerButtonEnabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -828,7 +834,13 @@
</size> </size>
</property> </property>
<property name="focusPolicy"> <property name="focusPolicy">
<enum>Qt::TabFocus</enum> <enum>Qt::StrongFocus</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property> </property>
</widget> </widget>
</item> </item>
@ -916,6 +928,30 @@
<header>TableWidget.h</header> <header>TableWidget.h</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<tabstops>
<tabstop>FinalRenderEarlyClipCheckBox</tabstop>
<tabstop>FinalRenderYAxisUpCheckBox</tabstop>
<tabstop>FinalRenderTransparencyCheckBox</tabstop>
<tabstop>FinalRenderOpenCLCheckBox</tabstop>
<tabstop>FinalRenderDoublePrecisionCheckBox</tabstop>
<tabstop>FinalRenderSaveXmlCheckBox</tabstop>
<tabstop>FinalRenderDoAllCheckBox</tabstop>
<tabstop>FinalRenderDoSequenceCheckBox</tabstop>
<tabstop>FinalRenderKeepAspectCheckBox</tabstop>
<tabstop>FinalRenderScaleNoneRadioButton</tabstop>
<tabstop>FinalRenderScaleWidthRadioButton</tabstop>
<tabstop>FinalRenderScaleHeightRadioButton</tabstop>
<tabstop>FinalRenderJpgRadioButton</tabstop>
<tabstop>FinalRenderPngRadioButton</tabstop>
<tabstop>FinalRenderPlatformCombo</tabstop>
<tabstop>FinalRenderDeviceCombo</tabstop>
<tabstop>FinalRenderThreadCountSpin</tabstop>
<tabstop>FinalRenderGeometryTable</tabstop>
<tabstop>FinalRenderTextOutput</tabstop>
<tabstop>StartRenderButton</tabstop>
<tabstop>StopRenderButton</tabstop>
<tabstop>CloseButton</tabstop>
</tabstops>
<resources/> <resources/>
<connections> <connections>
<connection> <connection>

View File

@ -201,6 +201,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
for (i = 0; i < m_EmberFile.m_Embers.size() && m_Run; i++) for (i = 0; i < m_EmberFile.m_Embers.size() && m_Run; i++)
{ {
m_Renderer->Reset();//Have to manually set this since the ember is not set each time through. m_Renderer->Reset();//Have to manually set this since the ember is not set each time through.
m_PureIterTime = 0;
m_RenderTimer.Tic();//Toc() is called in the progress function. m_RenderTimer.Tic();//Toc() is called in the progress function.
if (m_Renderer->Run(m_FinalImage, i) != RENDER_OK) if (m_Renderer->Run(m_FinalImage, i) != RENDER_OK)
@ -223,6 +224,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
for (i = 0; i < m_EmberFile.m_Embers.size() && m_Run; i++) for (i = 0; i < m_EmberFile.m_Embers.size() && m_Run; i++)
{ {
m_Renderer->SetEmber(m_EmberFile.m_Embers[i]); m_Renderer->SetEmber(m_EmberFile.m_Embers[i]);
m_PureIterTime = 0;
m_RenderTimer.Tic();//Toc() is called in the progress function. m_RenderTimer.Tic();//Toc() is called in the progress function.
if (m_Renderer->Run(m_FinalImage) != RENDER_OK) if (m_Renderer->Run(m_FinalImage) != RENDER_OK)
@ -240,6 +242,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
ResetProgress(); ResetProgress();
m_Ember.m_TemporalSamples = 1; m_Ember.m_TemporalSamples = 1;
m_Renderer->SetEmber(m_Ember); m_Renderer->SetEmber(m_Ember);
m_PureIterTime = 0;
m_RenderTimer.Tic();//Toc() is called in the progress function. m_RenderTimer.Tic();//Toc() is called in the progress function.
if (m_Renderer->Run(m_FinalImage) != RENDER_OK) if (m_Renderer->Run(m_FinalImage) != RENDER_OK)
@ -288,22 +291,29 @@ template <typename T>
int FinalRenderEmberController<T>::ProgressFunc(Ember<T>& ember, void* foo, double fraction, int stage, double etaMs) int FinalRenderEmberController<T>::ProgressFunc(Ember<T>& ember, void* foo, double fraction, int stage, double etaMs)
{ {
static int count = 0; static int count = 0;
int intFract = (int)fraction;
if (stage == 0) if (stage == 0)
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderIterationProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int(fraction))); {
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderIterationProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, intFract));
if (intFract == 100)
m_PureIterTime = m_RenderTimer.Toc();
}
else if (stage == 1) else if (stage == 1)
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderFilteringProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int(fraction))); QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderFilteringProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, intFract));
else if (stage == 2) else if (stage == 2)
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderAccumProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int(fraction))); QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderAccumProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, intFract));
//Finished, so take special action. //Finished, so take special action.
if (stage == 2 && (int)fraction == 100) if (stage == 2 && intFract == 100)
{ {
string renderTimeString = m_RenderTimer.Format(m_RenderTimer.Toc()), totalTimeString; string renderTimeString = m_RenderTimer.Format(m_RenderTimer.Toc()), totalTimeString;
QString status, filename = m_GuiState.m_Path; QString status, filename = m_GuiState.m_Path;
QFileInfo original(filename); QFileInfo original(filename);
EmberStats stats = m_Renderer->Stats(); EmberStats stats = m_Renderer->Stats();
QString iters = QLocale(QLocale::English).toString(stats.m_Iters); QString iters = QLocale(QLocale::English).toString(stats.m_Iters);
QString itersPerSec = QLocale(QLocale::English).toString(int(stats.m_Iters / (m_PureIterTime / 1000.0)));
if (m_GuiState.m_DoAll && m_EmberFile.m_Embers.size() > 1) if (m_GuiState.m_DoAll && m_EmberFile.m_Embers.size() > 1)
filename = original.absolutePath() + QDir::separator() + m_GuiState.m_Prefix + QString::fromStdString(m_EmberFile.m_Embers[m_FinishedImageCount].m_Name) + m_GuiState.m_Suffix + "." + m_GuiState.m_DoAllExt; filename = original.absolutePath() + QDir::separator() + m_GuiState.m_Prefix + QString::fromStdString(m_EmberFile.m_Embers[m_FinishedImageCount].m_Name) + m_GuiState.m_Suffix + "." + m_GuiState.m_DoAllExt;
@ -348,9 +358,9 @@ int FinalRenderEmberController<T>::ProgressFunc(Ember<T>& ember, void* foo, doub
} }
m_FinishedImageCount++; m_FinishedImageCount++;
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderIterationProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int(100)));//Just to be safe. QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderIterationProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, 100));//Just to be safe.
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderFilteringProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int(100))); QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderFilteringProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, 100));
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderAccumProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int(100))); QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderAccumProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, 100));
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderTotalProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int(((float)m_FinishedImageCount / (float)m_ImageCount) * 100))); QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderTotalProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int(((float)m_FinishedImageCount / (float)m_ImageCount) * 100)));
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderImageCountLabel, "setText", Qt::QueuedConnection, Q_ARG(QString, QString::number(m_FinishedImageCount) + " / " + QString::number(m_ImageCount))); QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderImageCountLabel, "setText", Qt::QueuedConnection, Q_ARG(QString, QString::number(m_FinishedImageCount) + " / " + QString::number(m_ImageCount)));
@ -358,7 +368,7 @@ int FinalRenderEmberController<T>::ProgressFunc(Ember<T>& ember, void* foo, doub
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderTextOutput, "append", Qt::QueuedConnection, Q_ARG(QString, status)); QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderTextOutput, "append", Qt::QueuedConnection, Q_ARG(QString, status));
totalTimeString = m_TotalTimer.Format(m_TotalTimer.Toc()); totalTimeString = m_TotalTimer.Format(m_TotalTimer.Toc());
status = "Total render time: " + QString::fromStdString(totalTimeString) + "\nTotal iters: " + iters + "\n"; status = "Total render time: " + QString::fromStdString(totalTimeString) + "\nTotal iters: " + iters + "\nIters/second: " + itersPerSec + "\n";
QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderTextOutput, "append", Qt::QueuedConnection, Q_ARG(QString, status)); QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderTextOutput, "append", Qt::QueuedConnection, Q_ARG(QString, status));
QMetaObject::invokeMethod(m_FinalRender, "MoveCursorToEnd", Qt::QueuedConnection); QMetaObject::invokeMethod(m_FinalRender, "MoveCursorToEnd", Qt::QueuedConnection);

View File

@ -76,6 +76,7 @@ protected:
bool m_PreviewRun; bool m_PreviewRun;
unsigned int m_ImageCount; unsigned int m_ImageCount;
unsigned int m_FinishedImageCount; unsigned int m_FinishedImageCount;
double m_PureIterTime;
QFuture<void> m_Result; QFuture<void> m_Result;
QFuture<void> m_PreviewResult; QFuture<void> m_PreviewResult;

View File

@ -144,6 +144,8 @@ Fractorium::Fractorium(QWidget* parent)
ui.GLDisplay->SetMainWindow(this); ui.GLDisplay->SetMainWindow(this);
SetCoordinateStatus(0, 0, 0, 0); SetCoordinateStatus(0, 0, 0, 0);
SetTabOrders();
//At this point, everything has been setup except the renderer. Shortly after //At this point, everything has been setup except the renderer. Shortly after
//this constructor exits, GLWidget::initializeGL() will create the initial flock and start the rendering timer //this constructor exits, GLWidget::initializeGL() will create the initial flock and start the rendering timer
//which executes whenever the program is idle. Upon starting the timer, the renderer //which executes whenever the program is idle. Upon starting the timer, the renderer
@ -527,6 +529,134 @@ QString Fractorium::SetupSaveFolderDialog()
return filename; return filename;
} }
/// <summary>
/// Explicitly set the tab orders for the entire program.
/// Qt has a facility to do this, but it fails when using custom widgets in
/// tables, so it must be done manually here.
/// This list must be kept in sync with any UI changes.
/// </summary>
void Fractorium::SetTabOrders()
{
QWidget* w = SetTabOrder(this, ui.ColorTable, m_BrightnessSpin);//Flame.
w = SetTabOrder(this, w, m_GammaSpin);
w = SetTabOrder(this, w, m_GammaThresholdSpin);
w = SetTabOrder(this, w, m_VibrancySpin);
w = SetTabOrder(this, w, m_HighlightSpin);
w = SetTabOrder(this, w, m_BackgroundColorButton);
w = SetTabOrder(this, w, m_PaletteModeCombo);
w = SetTabOrder(this, w, m_CenterXSpin);
w = SetTabOrder(this, w, m_CenterYSpin);
w = SetTabOrder(this, w, m_ScaleSpin);
w = SetTabOrder(this, w, m_ZoomSpin);
w = SetTabOrder(this, w, m_RotateSpin);
w = SetTabOrder(this, w, m_ZPosSpin);
w = SetTabOrder(this, w, m_PerspectiveSpin);
w = SetTabOrder(this, w, m_PitchSpin);
w = SetTabOrder(this, w, m_YawSpin);
w = SetTabOrder(this, w, m_DepthBlurSpin);
w = SetTabOrder(this, w, m_SpatialFilterWidthSpin);
w = SetTabOrder(this, w, m_SpatialFilterTypeCombo);
w = SetTabOrder(this, w, m_TemporalFilterTypeCombo);
w = SetTabOrder(this, w, m_DEFilterMinRadiusSpin);
w = SetTabOrder(this, w, m_DEFilterMaxRadiusSpin);
w = SetTabOrder(this, w, m_DECurveSpin);
w = SetTabOrder(this, w, m_PassesSpin);
w = SetTabOrder(this, w, m_TemporalSamplesSpin);
w = SetTabOrder(this, w, m_QualitySpin);
w = SetTabOrder(this, w, m_SupersampleSpin);
w = SetTabOrder(this, w, m_AffineInterpTypeCombo);
w = SetTabOrder(this, w, m_InterpTypeCombo);
w = SetTabOrder(this, ui.CurrentXformCombo, ui.AddXformButton);//Xforms.
w = SetTabOrder(this, w, ui.DuplicateXformButton);
w = SetTabOrder(this, w, ui.ClearXformButton);
w = SetTabOrder(this, w, ui.DeleteXformButton);
w = SetTabOrder(this, w, ui.AddFinalXformButton);
w = SetTabOrder(this, w, m_XformWeightSpin);
w = SetTabOrder(this, w, m_XformWeightSpinnerButtonWidget->m_Button);
w = SetTabOrder(this, m_XformColorIndexSpin, ui.XformColorScroll);//Xforms color.
w = SetTabOrder(this, w, m_XformColorSpeedSpin);
w = SetTabOrder(this, w, m_XformOpacitySpin);
w = SetTabOrder(this, w, m_XformDirectColorSpin);
w = SetTabOrder(this, w, ui.SoloXformCheckBox);
w = SetTabOrder(this, ui.PreAffineGroupBox, m_PreX1Spin);//Xforms affine.
w = SetTabOrder(this, w, m_PreX2Spin);
w = SetTabOrder(this, w, m_PreY1Spin);
w = SetTabOrder(this, w, m_PreY2Spin);
w = SetTabOrder(this, w, m_PreO1Spin);
w = SetTabOrder(this, w, m_PreO2Spin);
w = SetTabOrder(this, w, ui.PreFlipVerticalButton);
w = SetTabOrder(this, w, ui.PreResetButton);
w = SetTabOrder(this, w, ui.PreFlipHorizontalButton);
w = SetTabOrder(this, w, ui.PreRotate90CcButton);
w = SetTabOrder(this, w, ui.PreRotateCcButton);
w = SetTabOrder(this, w, ui.PreRotateCombo);
w = SetTabOrder(this, w, ui.PreRotateCButton);
w = SetTabOrder(this, w, ui.PreRotate90CButton);
w = SetTabOrder(this, w, ui.PreMoveUpButton);
w = SetTabOrder(this, w, ui.PreMoveDownButton);
w = SetTabOrder(this, w, ui.PreMoveCombo);
w = SetTabOrder(this, w, ui.PreMoveLeftButton);
w = SetTabOrder(this, w, ui.PreMoveRightButton);
w = SetTabOrder(this, w, ui.PreScaleUpButton);
w = SetTabOrder(this, w, ui.PreScaleCombo);
w = SetTabOrder(this, w, ui.PreScaleDownButton);
w = SetTabOrder(this, w, ui.ShowPreAffineCurrentRadio);
w = SetTabOrder(this, w, ui.ShowPreAffineAllRadio);
w = SetTabOrder(this, w, ui.PostAffineGroupBox);
w = SetTabOrder(this, w, m_PostX1Spin);
w = SetTabOrder(this, w, m_PostX2Spin);
w = SetTabOrder(this, w, m_PostY1Spin);
w = SetTabOrder(this, w, m_PostY2Spin);
w = SetTabOrder(this, w, m_PostO1Spin);
w = SetTabOrder(this, w, m_PostO2Spin);
w = SetTabOrder(this, w, ui.PostFlipVerticalButton);
w = SetTabOrder(this, w, ui.PostResetButton);
w = SetTabOrder(this, w, ui.PostFlipHorizontalButton);
w = SetTabOrder(this, w, ui.PostRotate90CcButton);
w = SetTabOrder(this, w, ui.PostRotateCcButton);
w = SetTabOrder(this, w, ui.PostRotateCombo);
w = SetTabOrder(this, w, ui.PostRotateCButton);
w = SetTabOrder(this, w, ui.PostRotate90CButton);
w = SetTabOrder(this, w, ui.PostMoveUpButton);
w = SetTabOrder(this, w, ui.PostMoveDownButton);
w = SetTabOrder(this, w, ui.PostMoveCombo);
w = SetTabOrder(this, w, ui.PostMoveLeftButton);
w = SetTabOrder(this, w, ui.PostMoveRightButton);
w = SetTabOrder(this, w, ui.PostScaleUpButton);
w = SetTabOrder(this, w, ui.PostScaleCombo);
w = SetTabOrder(this, w, ui.PostScaleDownButton);
w = SetTabOrder(this, w, ui.ShowPostAffineCurrentRadio);
w = SetTabOrder(this, w, ui.ShowPostAffineAllRadio);
w = SetTabOrder(this, w, ui.LocalPivotRadio);
w = SetTabOrder(this, w, ui.WorldPivotRadio);
w = SetTabOrder(this, ui.VariationsFilterLineEdit, ui.VariationsFilterClearButton);//Xforms variation.
w = SetTabOrder(this, w, ui.VariationsTree);
//Xforms xaos is done dynamically every time.
w = SetTabOrder(this, m_PaletteHueSpin, m_PaletteContrastSpin);//Palette.
w = SetTabOrder(this, w, m_PaletteSaturationSpin);
w = SetTabOrder(this, w, m_PaletteBlurSpin);
w = SetTabOrder(this, w, m_PaletteBrightnessSpin);
w = SetTabOrder(this, w, m_PaletteFrequencySpin);
w = SetTabOrder(this, w, ui.PaletteListTable);
w = SetTabOrder(this, ui.InfoBoundsGroupBox, ui.InfoBoundsFrame);//Info.
w = SetTabOrder(this, w, ui.InfoBoundsTable);
w = SetTabOrder(this, w, ui.InfoFileOpeningGroupBox);
w = SetTabOrder(this, w, ui.InfoFileOpeningTextEdit);
w = SetTabOrder(this, w, ui.InfoRenderingGroupBox);
w = SetTabOrder(this, w, ui.InfoRenderingTextEdit);
}
/// <summary> /// <summary>
/// This is no longer needed and was used to compensate for a different bug /// This is no longer needed and was used to compensate for a different bug
/// however the code is interesting, so keep it around for possible future use. /// however the code is interesting, so keep it around for possible future use.

View File

@ -260,6 +260,7 @@ private:
void InitXformsXaosUI(); void InitXformsXaosUI();
void InitPaletteUI(); void InitPaletteUI();
void InitLibraryUI(); void InitLibraryUI();
void SetTabOrders();
//Embers. //Embers.
bool HaveFinal(); bool HaveFinal();
@ -446,5 +447,19 @@ static void SetupSpinner(QTableWidget* table, const QObject* receiver, int& row,
row++; row++;
} }
/// <summary>
/// Wrapper around QWidget::setTabOrder() to return the second widget.
/// This makes it easy to chain multiple calls without having to retype
/// all of them if the order changes or if a new widget is inserted.
/// </summary>
/// <param name="parent">The parent widget that w1 and w2 belong to</param>
/// <param name="w1">The widget to come first in the tab order</param>
/// <param name="w2">The widget to come second in the tab order</param>
static QWidget* SetTabOrder(QWidget* parent, QWidget* w1, QWidget* w2)
{
parent->setTabOrder(w1, w2);
return w2;
}
//template void Fractorium::SetupSpinner<SpinBox, int> (QTableWidget* table, const QObject* receiver, int& row, int col, SpinBox*& spinBox, int height, int min, int max, int step, const char* signal, const char* slot, bool incRow, int val, int doubleClickZero, int doubleClickNonZero); //template void Fractorium::SetupSpinner<SpinBox, int> (QTableWidget* table, const QObject* receiver, int& row, int col, SpinBox*& spinBox, int height, int min, int max, int step, const char* signal, const char* slot, bool incRow, int val, int doubleClickZero, int doubleClickNonZero);
//template void Fractorium::SetupSpinner<DoubleSpinBox, double>(QTableWidget* table, const QObject* receiver, int& row, int col, DoubleSpinBox*& spinBox, int height, double min, double max, double step, const char* signal, const char* slot, bool incRow, double val, double doubleClickZero, double doubleClickNonZero); //template void Fractorium::SetupSpinner<DoubleSpinBox, double>(QTableWidget* table, const QObject* receiver, int& row, int col, DoubleSpinBox*& spinBox, int height, double min, double max, double step, const char* signal, const char* slot, bool incRow, double val, double doubleClickZero, double doubleClickNonZero);

Binary file not shown.

View File

@ -340,7 +340,7 @@
<enum>QTabWidget::Triangular</enum> <enum>QTabWidget::Triangular</enum>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>2</number> <number>0</number>
</property> </property>
<property name="usesScrollButtons"> <property name="usesScrollButtons">
<bool>true</bool> <bool>true</bool>
@ -403,6 +403,9 @@
</property> </property>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QTreeWidget" name="LibraryTree"> <widget class="QTreeWidget" name="LibraryTree">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="contextMenuPolicy"> <property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum> <enum>Qt::CustomContextMenu</enum>
</property> </property>
@ -525,6 +528,9 @@
<height>22</height> <height>22</height>
</size> </size>
</property> </property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::Panel</enum> <enum>QFrame::Panel</enum>
</property> </property>
@ -603,6 +609,9 @@
<height>22</height> <height>22</height>
</size> </size>
</property> </property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::Panel</enum> <enum>QFrame::Panel</enum>
</property> </property>
@ -688,7 +697,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="acceptDrops"> <property name="acceptDrops">
<bool>true</bool> <bool>false</bool>
</property> </property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::Panel</enum> <enum>QFrame::Panel</enum>
@ -705,6 +714,9 @@
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="alternatingRowColors"> <property name="alternatingRowColors">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -923,6 +935,9 @@
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="alternatingRowColors"> <property name="alternatingRowColors">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -1105,6 +1120,9 @@
<height>22</height> <height>22</height>
</size> </size>
</property> </property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::Panel</enum> <enum>QFrame::Panel</enum>
</property> </property>
@ -1183,6 +1201,9 @@
<height>22</height> <height>22</height>
</size> </size>
</property> </property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::Panel</enum> <enum>QFrame::Panel</enum>
</property> </property>
@ -1276,6 +1297,9 @@
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="alternatingRowColors"> <property name="alternatingRowColors">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -1520,6 +1544,9 @@
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="alternatingRowColors"> <property name="alternatingRowColors">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -1899,7 +1926,7 @@
</font> </font>
</property> </property>
<property name="focusPolicy"> <property name="focusPolicy">
<enum>Qt::NoFocus</enum> <enum>Qt::StrongFocus</enum>
</property> </property>
<property name="autoFillBackground"> <property name="autoFillBackground">
<bool>false</bool> <bool>false</bool>
@ -1922,6 +1949,9 @@
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::DoubleClicked|QAbstractItemView::SelectedClicked</set> <set>QAbstractItemView::DoubleClicked|QAbstractItemView::SelectedClicked</set>
</property> </property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum> <enum>QAbstractItemView::NoSelection</enum>
</property> </property>
@ -2312,6 +2342,9 @@ SpinBox
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="showDropIndicator" stdset="0"> <property name="showDropIndicator" stdset="0">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -2498,6 +2531,9 @@ SpinBox
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum> <enum>QAbstractItemView::NoSelection</enum>
</property> </property>
@ -2600,6 +2636,9 @@ SpinBox
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum> <enum>QAbstractItemView::NoSelection</enum>
</property> </property>
@ -2674,6 +2713,9 @@ SpinBox
<height>16</height> <height>16</height>
</size> </size>
</property> </property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="maximum"> <property name="maximum">
<number>255</number> <number>255</number>
</property> </property>
@ -2739,8 +2781,8 @@ SpinBox
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>118</width> <width>238</width>
<height>597</height> <height>752</height>
</rect> </rect>
</property> </property>
<property name="palette"> <property name="palette">
@ -2882,6 +2924,9 @@ SpinBox
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum> <enum>QAbstractItemView::NoSelection</enum>
</property> </property>
@ -3483,6 +3528,9 @@ SpinBox
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum> <enum>QAbstractItemView::NoSelection</enum>
</property> </property>
@ -4352,6 +4400,9 @@ SpinBox
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="showDropIndicator" stdset="0"> <property name="showDropIndicator" stdset="0">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -4569,6 +4620,9 @@ SpinBox
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum> <enum>QAbstractItemView::NoSelection</enum>
</property> </property>
@ -4661,7 +4715,7 @@ SpinBox
<item row="2" column="0"> <item row="2" column="0">
<widget class="QTableWidget" name="PaletteListTable"> <widget class="QTableWidget" name="PaletteListTable">
<property name="focusPolicy"> <property name="focusPolicy">
<enum>Qt::NoFocus</enum> <enum>Qt::StrongFocus</enum>
</property> </property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::Panel</enum> <enum>QFrame::Panel</enum>
@ -4678,6 +4732,9 @@ SpinBox
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum> <enum>QAbstractItemView::NoSelection</enum>
</property> </property>
@ -4944,6 +5001,9 @@ SpinBox
<height>250</height> <height>250</height>
</size> </size>
</property> </property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="autoFillBackground"> <property name="autoFillBackground">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -5250,6 +5310,9 @@ SpinBox
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="title"> <property name="title">
<string>Rendering</string> <string>Rendering</string>
</property> </property>
@ -5271,9 +5334,18 @@ SpinBox
</property> </property>
<item> <item>
<widget class="QTextEdit" name="InfoRenderingTextEdit"> <widget class="QTextEdit" name="InfoRenderingTextEdit">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="tabChangesFocus">
<bool>true</bool>
</property>
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="textInteractionFlags">
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -5287,6 +5359,9 @@ SpinBox
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="title"> <property name="title">
<string>File Opening</string> <string>File Opening</string>
</property> </property>
@ -5308,6 +5383,9 @@ SpinBox
</property> </property>
<item> <item>
<widget class="QTextEdit" name="InfoFileOpeningTextEdit"> <widget class="QTextEdit" name="InfoFileOpeningTextEdit">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -5644,6 +5722,86 @@ SpinBox
<container>1</container> <container>1</container>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<tabstops>
<tabstop>DockWidget</tabstop>
<tabstop>SaveCurrentAsXmlButton</tabstop>
<tabstop>SaveEntireFileAsXmlButton</tabstop>
<tabstop>SaveCurrentToOpenedFileButton</tabstop>
<tabstop>ParamsTabWidget</tabstop>
<tabstop>LibraryTree</tabstop>
<tabstop>scrollArea</tabstop>
<tabstop>CurrentXformCombo</tabstop>
<tabstop>AddXformButton</tabstop>
<tabstop>DuplicateXformButton</tabstop>
<tabstop>ClearXformButton</tabstop>
<tabstop>DeleteXformButton</tabstop>
<tabstop>AddFinalXformButton</tabstop>
<tabstop>XformWeightNameTable</tabstop>
<tabstop>XformsTabWidget</tabstop>
<tabstop>XformColorIndexTable</tabstop>
<tabstop>XformColorScroll</tabstop>
<tabstop>XformColorValuesTable</tabstop>
<tabstop>SoloXformCheckBox</tabstop>
<tabstop>scrollArea_3</tabstop>
<tabstop>PreAffineTable</tabstop>
<tabstop>PreFlipVerticalButton</tabstop>
<tabstop>PreResetButton</tabstop>
<tabstop>PreFlipHorizontalButton</tabstop>
<tabstop>PreRotate90CcButton</tabstop>
<tabstop>PreRotateCcButton</tabstop>
<tabstop>PreRotateCombo</tabstop>
<tabstop>PreRotateCButton</tabstop>
<tabstop>PreRotate90CButton</tabstop>
<tabstop>PreMoveUpButton</tabstop>
<tabstop>PreMoveDownButton</tabstop>
<tabstop>PreMoveCombo</tabstop>
<tabstop>PreMoveLeftButton</tabstop>
<tabstop>PreMoveRightButton</tabstop>
<tabstop>PreScaleUpButton</tabstop>
<tabstop>PreScaleCombo</tabstop>
<tabstop>PreScaleDownButton</tabstop>
<tabstop>ShowPreAffineCurrentRadio</tabstop>
<tabstop>ShowPreAffineAllRadio</tabstop>
<tabstop>PostAffineGroupBox</tabstop>
<tabstop>PostAffineTable</tabstop>
<tabstop>PostFlipVerticalButton</tabstop>
<tabstop>PostResetButton</tabstop>
<tabstop>PostFlipHorizontalButton</tabstop>
<tabstop>PostRotate90CcButton</tabstop>
<tabstop>PostRotateCcButton</tabstop>
<tabstop>PostRotateCombo</tabstop>
<tabstop>PostRotateCButton</tabstop>
<tabstop>PostRotate90CButton</tabstop>
<tabstop>PostMoveUpButton</tabstop>
<tabstop>PostMoveDownButton</tabstop>
<tabstop>PostMoveCombo</tabstop>
<tabstop>PostMoveLeftButton</tabstop>
<tabstop>PostMoveRightButton</tabstop>
<tabstop>PostScaleUpButton</tabstop>
<tabstop>PostScaleCombo</tabstop>
<tabstop>PostScaleDownButton</tabstop>
<tabstop>ShowPostAffineCurrentRadio</tabstop>
<tabstop>ShowPostAffineAllRadio</tabstop>
<tabstop>LocalPivotRadio</tabstop>
<tabstop>WorldPivotRadio</tabstop>
<tabstop>VariationsFilterLineEdit</tabstop>
<tabstop>VariationsFilterClearButton</tabstop>
<tabstop>VariationsTree</tabstop>
<tabstop>XaosTable</tabstop>
<tabstop>PaletteAdjustTable</tabstop>
<tabstop>PaletteListTable</tabstop>
<tabstop>scrollArea_5</tabstop>
<tabstop>InfoFileOpeningGroupBox</tabstop>
<tabstop>InfoFileOpeningTextEdit</tabstop>
<tabstop>InfoRenderingGroupBox</tabstop>
<tabstop>InfoRenderingTextEdit</tabstop>
<tabstop>PreAffineGroupBox</tabstop>
<tabstop>scrollArea_4</tabstop>
<tabstop>ClearXaosButton</tabstop>
<tabstop>InfoBoundsGroupBox</tabstop>
<tabstop>XaosFromRadio</tabstop>
<tabstop>XaosToRadio</tabstop>
</tabstops>
<resources> <resources>
<include location="Fractorium.qrc"/> <include location="Fractorium.qrc"/>
</resources> </resources>

View File

@ -44,8 +44,8 @@ void FractoriumEmberController<T>::SetupVariationTree()
ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var); ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var);
//First add the variation, with a spinner for its weight. //First add the variation, with a spinner for its weight.
VariationTreeWidgetItem<T>* item = new VariationTreeWidgetItem<T>(tree); VariationTreeWidgetItem<T>* item = new VariationTreeWidgetItem<T>(var->VariationId(), tree);
VariationTreeDoubleSpinBox<T>* spinBox = new VariationTreeDoubleSpinBox<T>(tree, parVar ? parVar : var, ""); VariationTreeDoubleSpinBox<T>* spinBox = new VariationTreeDoubleSpinBox<T>(tree, item, parVar ? parVar : var, "");
item->setText(0, QString::fromStdString(var->Name())); item->setText(0, QString::fromStdString(var->Name()));
item->setSizeHint(0, hint0); item->setSizeHint(0, hint0);
@ -68,8 +68,8 @@ void FractoriumEmberController<T>::SetupVariationTree()
{ {
if (!params[j].IsPrecalc()) if (!params[j].IsPrecalc())
{ {
VariationTreeWidgetItem<T>* paramWidget = new VariationTreeWidgetItem<T>(item); VariationTreeWidgetItem<T>* paramWidget = new VariationTreeWidgetItem<T>(var->VariationId(), item);
VariationTreeDoubleSpinBox<T>* varSpinBox = new VariationTreeDoubleSpinBox<T>(tree, parVar, params[j].Name()); VariationTreeDoubleSpinBox<T>* varSpinBox = new VariationTreeDoubleSpinBox<T>(tree, paramWidget, parVar, params[j].Name());
paramWidget->setText(0, params[j].Name().c_str()); paramWidget->setText(0, params[j].Name().c_str());
paramWidget->setSizeHint(0, hint0); paramWidget->setSizeHint(0, hint0);
@ -144,7 +144,7 @@ void FractoriumEmberController<T>::VariationSpinBoxValueChanged(double d)
Variation<T>* var = sender->GetVariation();//The variation attached to the sender, for reference only. Variation<T>* var = sender->GetVariation();//The variation attached to the sender, for reference only.
ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var);//The parametric cast of that variation. ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var);//The parametric cast of that variation.
Variation<T>* xformVar = xform->GetVariationById(var->VariationId());//The corresponding variation in the currently selected xform. Variation<T>* xformVar = xform->GetVariationById(var->VariationId());//The corresponding variation in the currently selected xform.
QList<QTreeWidgetItem*> items = tree->findItems(QString::fromStdString(var->Name()), Qt::MatchExactly); VariationTreeWidgetItem<T>* widgetItem = sender->WidgetItem();
bool isParam = parVar && sender->IsParam(); bool isParam = parVar && sender->IsParam();
if (isParam) if (isParam)
@ -167,7 +167,7 @@ void FractoriumEmberController<T>::VariationSpinBoxValueChanged(double d)
if (xformVar) if (xformVar)
xform->DeleteVariationById(var->VariationId()); xform->DeleteVariationById(var->VariationId());
items[0]->setBackgroundColor(0, QColor(255, 255, 255));//Ensure background is always white if weight goes to zero. widgetItem->setBackgroundColor(0, QColor(255, 255, 255));//Ensure background is always white if weight goes to zero.
} }
else else
{ {
@ -183,7 +183,7 @@ void FractoriumEmberController<T>::VariationSpinBoxValueChanged(double d)
newVar->m_Weight = d; newVar->m_Weight = d;
xform->AddVariation(newVar); xform->AddVariation(newVar);
items[0]->setBackgroundColor(0, QColor(200, 200, 200));//Set background to gray when a variation has non-zero weight in this xform. widgetItem->setBackgroundColor(0, QColor(200, 200, 200));//Set background to gray when a variation has non-zero weight in this xform.
//If they've added a new parametric variation, then grab the values currently in the spinners //If they've added a new parametric variation, then grab the values currently in the spinners
//for the child parameters and assign them to the newly added variation. //for the child parameters and assign them to the newly added variation.
@ -191,19 +191,16 @@ void FractoriumEmberController<T>::VariationSpinBoxValueChanged(double d)
{ {
ParametricVariation<T>* newParVar = dynamic_cast<ParametricVariation<T>*>(newVar); ParametricVariation<T>* newParVar = dynamic_cast<ParametricVariation<T>*>(newVar);
if (!items.empty())//Get the tree widget for the parent variation. for (int i = 0; i < widgetItem->childCount(); i++)//Iterate through all of the children, which will be the params.
{ {
for (int i = 0; i < items[0]->childCount(); i++)//Iterate through all of the children, which will be the params. QTreeWidgetItem* childItem = widgetItem->child(i);//Get the child.
QWidget* itemWidget = tree->itemWidget(childItem, 1);//Get the widget for the child.
if (VariationTreeDoubleSpinBox<T>* spinBox = dynamic_cast<VariationTreeDoubleSpinBox<T>*>(itemWidget))//Cast the widget to the VariationTreeDoubleSpinBox type.
{ {
QTreeWidgetItem* childItem = items[0]->child(i);//Get the child. string s = childItem->text(0).toStdString();//Use the name of the child, and the value of the spinner widget to assign the param.
QWidget* itemWidget = tree->itemWidget(childItem, 1);//Get the widget for the child.
if (VariationTreeDoubleSpinBox<T>* spinBox = dynamic_cast<VariationTreeDoubleSpinBox<T>*>(itemWidget))//Cast the widget to the VariationTreeDoubleSpinBox type. newParVar->SetParamVal(s.c_str(), spinBox->value());
{
string s = childItem->text(0).toStdString();//Use the name of the child, and the value of the spinner widget to assign the param.
newParVar->SetParamVal(s.c_str(), spinBox->value());
}
} }
} }
} }
@ -231,14 +228,12 @@ void FractoriumEmberController<T>::FillVariationTreeWithXform(Xform<T>* xform)
for (unsigned int i = 0; i < tree->topLevelItemCount(); i++) for (unsigned int i = 0; i < tree->topLevelItemCount(); i++)
{ {
QTreeWidgetItem* item = tree->topLevelItem(i); VariationTreeWidgetItem<T>* item = dynamic_cast<VariationTreeWidgetItem<T>*>(tree->topLevelItem(i));
string varName = item->text(0).toStdString(); Variation<T>* var = xform->GetVariationById(item->Id());//See if this variation in the tree was contained in the xform.
Variation<T>* var = xform->GetVariationByName(varName);//See if this variation in the tree was contained in the xform.
ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var);//Attempt cast to parametric variation for later. ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var);//Attempt cast to parametric variation for later.
ParametricVariation<T>* origParVar = dynamic_cast<ParametricVariation<T>*>(m_VariationList.GetVariation(varName)); ParametricVariation<T>* origParVar = dynamic_cast<ParametricVariation<T>*>(m_VariationList.GetVariation(item->Id()));
QWidget* itemWidget = tree->itemWidget(item, 1);//Get the widget for the item.
if (VariationTreeDoubleSpinBox<T>* spinBox = dynamic_cast<VariationTreeDoubleSpinBox<T>*>(itemWidget))//Cast the widget to the VariationTreeDoubleSpinBox type. if (VariationTreeDoubleSpinBox<T>* spinBox = dynamic_cast<VariationTreeDoubleSpinBox<T>*>(tree->itemWidget(item, 1)))//Get the widget for the item, and cast the widget to the VariationTreeDoubleSpinBox type.
{ {
spinBox->SetValueStealth(var ? var->m_Weight : 0);//If the variation was present, set the spin box to its weight, else zero. spinBox->SetValueStealth(var ? var->m_Weight : 0);//If the variation was present, set the spin box to its weight, else zero.
item->setBackgroundColor(0, var ? QColor(200, 200, 200) : QColor(255, 255, 255));//Ensure background is always white if the value goes to zero, else gray if var present. item->setBackgroundColor(0, var ? QColor(200, 200, 200) : QColor(255, 255, 255));//Ensure background is always white if the value goes to zero, else gray if var present.

View File

@ -136,7 +136,7 @@ void Fractorium::OnXaosFromToToggled(bool checked)
void Fractorium::FillXaosTable() void Fractorium::FillXaosTable()
{ {
int spinHeight = 20; int spinHeight = 20;
QWidget* w;
ui.XaosTable->setRowCount(m_Controller->XformCount());//This will grow or shrink the number of rows and call the destructor for previous DoubleSpinBoxes. ui.XaosTable->setRowCount(m_Controller->XformCount());//This will grow or shrink the number of rows and call the destructor for previous DoubleSpinBoxes.
for (int i = 0; i < m_Controller->XformCount(); i++) for (int i = 0; i < m_Controller->XformCount(); i++)
@ -150,7 +150,16 @@ void Fractorium::FillXaosTable()
ui.XaosTable->setItem(i, 0, xformNameItem); ui.XaosTable->setItem(i, 0, xformNameItem);
ui.XaosTable->setCellWidget(i, 1, spinBox); ui.XaosTable->setCellWidget(i, 1, spinBox);
connect(spinBox, SIGNAL(valueChanged(double)), this, SLOT(OnXaosChanged(double)), Qt::QueuedConnection); connect(spinBox, SIGNAL(valueChanged(double)), this, SLOT(OnXaosChanged(double)), Qt::QueuedConnection);
if (i > 0)
w = SetTabOrder(this, w, spinBox);
else
w = spinBox;
} }
w = SetTabOrder(this, w, ui.XaosToRadio);
w = SetTabOrder(this, w, ui.XaosFromRadio);
w = SetTabOrder(this, w, ui.ClearXaosButton);
} }
/// <summary> /// <summary>

View File

@ -477,12 +477,14 @@ void GLEmberController<T>::MousePress(QMouseEvent* e)
//The user has selected an xform by clicking on it, so update the main GUI by selecting this xform in the combo box. //The user has selected an xform by clicking on it, so update the main GUI by selecting this xform in the combo box.
m_Fractorium->CurrentXform(xformIndex); m_Fractorium->CurrentXform(xformIndex);
//Update selected xform dot. //Draw large yellow dot on select or drag.
bool pre = m_Fractorium->ui.PreAffineGroupBox->isChecked(); m_GL->glPointSize(6.0f);
bool post = m_Fractorium->ui.PostAffineGroupBox->isChecked(); m_GL->glBegin(GL_POINTS);
m_GL->glColor4f(1.0f, 1.0f, 0.5f, 1.0f);
DrawAffines(pre, post); m_GL->glVertex2f(m_DragHandlePos.x, m_DragHandlePos.y);
m_GL->update(); m_GL->glEnd();
m_GL->glPointSize(1.0f);//Restore point size.
m_GL->repaint();
} }
else//Nothing was selected. else//Nothing was selected.
{ {

View File

@ -52,6 +52,9 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="tabShape"> <property name="tabShape">
<enum>QTabWidget::Triangular</enum> <enum>QTabWidget::Triangular</enum>
</property> </property>
@ -728,6 +731,26 @@ in interactive mode for each mouse movement</string>
<header>TableWidget.h</header> <header>TableWidget.h</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<tabstops>
<tabstop>EarlyClipCheckBox</tabstop>
<tabstop>YAxisUpCheckBox</tabstop>
<tabstop>TransparencyCheckBox</tabstop>
<tabstop>OpenCLCheckBox</tabstop>
<tabstop>DoublePrecisionCheckBox</tabstop>
<tabstop>ShowAllXformsCheckBox</tabstop>
<tabstop>PlatformCombo</tabstop>
<tabstop>DeviceCombo</tabstop>
<tabstop>ThreadCountSpin</tabstop>
<tabstop>CpuSubBatchSpin</tabstop>
<tabstop>OpenCLSubBatchSpin</tabstop>
<tabstop>CpuFilteringLogRadioButton</tabstop>
<tabstop>CpuFilteringDERadioButton</tabstop>
<tabstop>OpenCLFilteringLogRadioButton</tabstop>
<tabstop>OpenCLFilteringDERadioButton</tabstop>
<tabstop>OptionsXmlSavingTable</tabstop>
<tabstop>OptionsIdentityTable</tabstop>
<tabstop>OptionsButtonBox</tabstop>
</tabstops>
<resources/> <resources/>
<connections> <connections>
<connection> <connection>

View File

@ -21,10 +21,12 @@ public:
/// Constructor that takes a pointer to a QTreeWidget as the parent /// Constructor that takes a pointer to a QTreeWidget as the parent
/// and passes it to the base. /// and passes it to the base.
/// </summary> /// </summary>
/// <param name="id">The ID of the variation this widget will represent</param>
/// <param name="parent">The parent widget</param> /// <param name="parent">The parent widget</param>
VariationTreeWidgetItem(QTreeWidget* parent = 0) VariationTreeWidgetItem(eVariationId id, QTreeWidget* parent = 0)
: QTreeWidgetItem(parent) : QTreeWidgetItem(parent)
{ {
m_Id = id;
} }
/// <summary> /// <summary>
@ -32,13 +34,16 @@ public:
/// and passes it to the base. /// and passes it to the base.
/// This is used for making sub items for parametric variation parameters. /// This is used for making sub items for parametric variation parameters.
/// </summary> /// </summary>
/// <param name="id">The ID of the variation this widget will represent</param>
/// <param name="parent">The parent widget</param> /// <param name="parent">The parent widget</param>
VariationTreeWidgetItem(QTreeWidgetItem* parent = 0) VariationTreeWidgetItem(eVariationId id, QTreeWidgetItem* parent = 0)
: QTreeWidgetItem(parent) : QTreeWidgetItem(parent)
{ {
m_Id = id;
} }
virtual ~VariationTreeWidgetItem() { } virtual ~VariationTreeWidgetItem() { }
eVariationId Id() { return m_Id; }
private: private:
/// <summary> /// <summary>
@ -86,4 +91,6 @@ private:
return false; return false;
} }
eVariationId m_Id;
}; };