Welcome to Fractal Forums

Fractal Software => Mandelbulber => Topic started by: rmmh on November 13, 2010, 09:27:39 PM




Title: Mandelbulber-Cleanup
Post by: rmmh on November 13, 2010, 09:27:39 PM
Hello,

I like Mandelbulber. It makes really nice images. Unfortunately, the code is hard to modify. I've forked it and started a cleanup project on github: http://github.com/rmmh/mandelbulber-clean/tree/cleanup

Changes so far:

- Switch the build system to CMake
- Refactor callback code
- Use arrays for more stuff (hybridPower1..5 -> hybridPower[5], etc)
- Factor out ParamsAllocMem and ParamsFreeMem
- Move IFS* into sIFS struct

Goals:

- Refactor stuff to the point that adding new formulas is very simple
- Make code easier to understand
- Optimize everything


Title: Re: Mandelbulber-Cleanup
Post by: rmmh on November 14, 2010, 09:33:51 AM
Changes so far:

    start refactoring, collapse callbacks
      use CMake for building, rearrange files for out-of-source building
      use arrays for more stuff
      make sRenderParam RAII
      split up IFS stuff into its own section
      Merge branch 'master' into cleanup
      move fractal calculation stuff from sParamsRender into sFractal
      factor out mandelbox settings into sFractalMandelbox, lowercase sFractalIFS members
      do more pass by value
      use more arrays (RotationX2Gamma -> Rotation[1][0][2]), general cleanups
      template ComputeIterations -- increases speed, especially with larger L1/L2 cache
      pull CalculateDistance/ComputeIterations back out of Fractal class, improve const correctness
      don't use new/delete when it's unnecessary, clean up common_math
      clean up redundant #includes, test some new optimization options


Title: Re: Mandelbulber-Cleanup
Post by: marius on November 14, 2010, 07:43:08 PM
Hello,

I like Mandelbulber. It makes really nice images. Unfortunately, the code is hard to modify. I've forked it and started a cleanup project on github: http://github.com/rmmh/mandelbulber-clean/tree/cleanup

...

Why fork instead of collaborate on http://code.google.com/p/mandelbulber/? Fragmentation has little synergy.


Title: Re: Mandelbulber-Cleanup
Post by: rmmh on November 14, 2010, 08:48:17 PM
Hello,

I like Mandelbulber. It makes really nice images. Unfortunately, the code is hard to modify. I've forked it and started a cleanup project on github: http://github.com/rmmh/mandelbulber-clean/tree/cleanup

...

Why fork instead of collaborate on http://code.google.com/p/mandelbulber/? Fragmentation has little synergy.
I needed somewhere to track my changes, and I don't have commit access to the main repository. Git (or DVCS in general) are better for this-- forking is the natural way for someone to work on large changes to a project, and they can be merged back into the mainline.

The SVN equivalent for a Git "fork" is a "branch".


Title: Re: Mandelbulber-Cleanup
Post by: rmmh on November 15, 2010, 01:50:33 AM
I just finished going through ComputeIterations and CalculateDistance, and managed to completely eliminate the need for an sFractal_ret structure. Compute<int Mode> (formerly ComputeIterations) now returns a double appropriate to Mode, optionally storing the iteration count in an integer. CalculateDistance returns the distance, optionally storing whether it reached the maximum iteration threshold in a boolean.

I'm seeing a ~15% rendering speed increase overall compared to 0.96. ;D


Title: Re: Mandelbulber-Cleanup
Post by: Buddhi on November 22, 2010, 10:35:28 PM
Hi

I have looked at your changes and I'm wondering whether does the keyframe animation still work. You created many structures for separate groups of fractal parameters but you didn't take into consideration how to morph values in keyframe animation mode. When all floating point values was in sParamRenderD there was very easy to interpolate all values using not so complicated code.  I was made in three parts:

       
Code:
 if (Interface_data.keyframeMode)
{
for (int keyNumber = 0; keyNumber < maxKeyNumber; keyNumber++)
{
IndexFilename(filename2, fractParam.file_keyframes, (char*) "fract", keyNumber);

sParamRender fractParamLoaded;
ParamsAllocMem(&fractParamLoaded);
LoadSettings(filename2, fractParamLoaded, NULL, true);
WriteLogDouble("Keyframe loaded", keyNumber);
morph.AddData(keyNumber, (double*) &fractParamLoaded);
IFSToMorph(IFSdouble, &fractParamLoaded);
morphIFS.AddData(keyNumber, IFSdouble);
WriteLogDouble("Keyframe data added to data structures", keyNumber);
ParamsReleaseMem(&fractParamLoaded);
}
printf("Keyframes loaded\n");
}

Code:
//Catmull-Rom interpolation in keyframe animation mode
if (fractParam.animMode && Interface_data.keyframeMode)
{
morph.CatmullRom(index, (double*) &fractParam);
morphIFS.CatmullRom(index, IFSdouble);
WriteLog("Splines calculated");
MorphToIFS(IFSdouble, &fractParam);
if (fractParam.doubles.zoom < 1e-15) fractParam.doubles.zoom = 1e-15;
fractParam.doubles.max_y = 20.0 / fractParam.doubles.zoom;
fractParam.doubles.resolution = 1.0 / fractParam.image_width;
sImageAdjustments imageAdjustments = fractParam.doubles.imageAdjustments;
mainImage->SetImageAdjustments(imageAdjustments);

sprintf(label_text, "Frame: %d, Keyframe %f", index, (double) index / fractParam.framesPerKeyframe);
if (!noGUI) gtk_label_set_text(GTK_LABEL(Interface.label_keyframeInfo), label_text);
WriteLog("Calculated additional data for splines");
}

Code:
void CMorph::CatmullRom(int frame, double *destData)
{
double v1, v2, v3, v4;
int key = frame / framesPerKey;
double factor = (frame % framesPerKey) / (double) framesPerKey;
double factor2 = factor*factor;
double factor3 = factor2*factor;
for (int i = 0; i < dataSize; i++)
{
if (key >= 1) v1 = dataSets[key - 1][i];
else v1 = dataSets[key][i];

if (key < count) v2 = dataSets[key][i];
else v2 = dataSets[count - 1][i];

if (key < count - 1) v3 = dataSets[key + 1][i];
else v3 = dataSets[count - 1][i];

if (key < count - 2) v4 = dataSets[key + 2][i];
else v4 = dataSets[count - 1][i];

//printf("v1=%f, v2=%f, v3=%f, v4=%f\n",v1,v2,v3,v4);

double value = 0.5 * ((2 * v2) + (-v1 + v3) * factor + (2 * v1 - 5 * v2 + 4 * v3 - v4) * factor2 + (-v1 + 3 * v2 - 3 * v3 + v4) * factor3);
output[i]=value;
destData[i] = output[i];
}
}

I think that now it will be much more difficult. First you have to collect all floating point values from all structures into CMorph class, next interpolate them and finally spread again into structures.


Title: Re: Mandelbulber-Cleanup
Post by: Side B on March 17, 2011, 10:08:04 AM
So whatever happened to this attempt?

4 posts, some misinterpretations of the code, alot of hard work and then give up?


Title: Re: Mandelbulber-Cleanup
Post by: Buddhi on March 17, 2011, 05:42:44 PM
Many things have been already done thanks to rmmh