Fractal Architect 4 Help Index

Lua API Reference


Applies to:FA 4

New feature of Fractal Architect 4 !

See Also: Using Lua Scripts

Lua Engine Version

Lua version 5.2.3 interpreter has been added to the app. When you search for info, make sure you specify that Lua version number, as it is continually being updated with no language features / API changes.

Lua Scripting Primer

Ralf Flicker wrote an excellent Lua primer for scripting fractals on the Oxidizer flame fractal app. (No longer maintained by its developer it seems.)

His Oxidizer Lua scripts and Lua Primer can be downloaded here: Tutorial and Example Lua Scripts

Ralf was a brilliant scripter. Tweaked versions of his simil3.lua and simil4.lua scripts are included with Fractal Architect and show the full power of Lua when applied to flame fractal creation.

Lua Engine’s LUAPATH

You may create your own reusable Lua modules to hold reusable Lua functions that you create. Custom scripts will use the Lua require function to load any modules the script wants to use.

Lua require functions search for Lua modules by looking in these directories, in this order:

  1. My Scripts/makeRandom
  2. My Scripts/makeVariants
  3. Factory/makeRandom
  4. Factory/makeVariants

The My Scripts folder’s location is can be changed by pressing the Choose Folder for My Scripts button.

The factory Lua tweak scripts provided with the app includes 2 example Lua modules and some example scripts that use those modules. (See below for more info.)

Builtin Variables Used by the Fractal Architect Lua Runtime

Fractal Architect uses several Lua global variables that it expects scripts to use for sending fractal definitions back to the app.

flame
The Lua table that represents the current fractal being modified.
flames

The list of flame tables that you can add new flames to

(Note the oxidizer_genomes table is actually the same table. It is intended for compatibility with older Oxidizer Lua scripts created specifically for the Oxidizer app).

How a Fractal is Represented in Lua


Fractals in Lua are represented as a single Lua table. That table holds a complex assortment of other tables representing other data structures needed by the fractal definition.

It is recommended that you use the Fractal creation utility functions

(see Utility Functions for Creating Blank Fractals )

to create a empty fractal (instead of setting each and every field shown in the table below).

flame
The table representing the entire fractal

Image parameters
flame.time
flame.width
flame.height
flame.centre_x
flame.center_x    — alternate name
flame.centre_y
flame.center_y    — alternate name
flame.rotate
flame.symmetry
flame.zoom
flame.scale

3D Camera parameters
flame.cam_yaw
flame.cam_pitch
flame.cam_perspective
flame.clipToNDC
flame.cam_dof
flame.cam_zpos
flame.cam_fov
flame.cam_near
flame.cam_orthowide
flame.cam_x
flame.cam_y
flame.cam_z

Color parameters
flame.palette        {string}
flame.hue
flame.brightness
flame.vibrancy
flame.gamma
flame.alpha_gamma
flame.gamma_threshold
flame.background_image_path - image file path - for composite over image rendering mode

flame.colors {tables, one per index}

flame.colors[n].index

flame.colors[n].red

flame.colors[n].green

flame.colors[n].blue

flame.colors[n].alpha

flame.background {table}

flame.background.red

flame.background.green

flame.background.blue

flame.composite_color {table} - for use with compositing render mode (see below)

flame.composite_color.red

flame.composite_color.green

flame.composite_color.blue

Render parameters
flame.render_mode - set to one of “normal”, “compositeOverColor”, “compositeOverImage”, “transparent”
flame.oversample
flame.supersample_width
flame.highlight_power
flame.cpufuse
flame.gpufuse
flame.palette_mode
flame.filter
flame.filter_shape        {string}
flame.quality
flame.estimator_radius

Edit parameters
flame.name {string}
flame.uuid {string}
flame.varsetUuid {string}

Xform parameters
flame.xforms[n].weight
flame.xforms[n].color
flame.xforms[n].symmetry
flame.xforms[n].color_speed
flame.xforms[n].is_finalxform {string}
flame.xforms[n].opacity
flame.xforms[n].rotates
flame.xforms[n].rotates_ignores_symmetry      – for older scripts , rotates looks at symmetry first
flame.xforms[n].var_color

flame.xforms[n].coefs

flame.xforms[n].post

Variations
This is the table for the Normal variation group. It holds a list of variation tables.
One subtable per variation. See examples below

flame.xforms[n].variations {table - one table per variation instance}

flame.xforms[n].variations[v].name
flame.xforms[n].variations[v].weight
flame.xforms[n].variations[v].instance
flame.xforms[n].variations[v]…. variation-parameter-specific string
flame.xforms[n].variations[v].coefs {table - special for matrix variations}

Pre-Variation Groups
This is the table for the Pre variation groups. It holds a list of variation group tables.
One subtable per variation group. See examples below

flame.xforms[n].preVarGroups {table - one table per Pre variation group}

   Each variatin group subtable has a list of variation tables

flame.xforms[n].preVarGroups[g][v].name
flame.xforms[n].preVarGroups[g][v].weight
flame.xforms[n].preVarGroups[g][v].instance
flame.xforms[n].preVarGroups[g][v]…. variation-parameter-specific string
flame.xforms[n].preVarGroups[g][v].coefs {table - special for matrix variations}

Post-Variation Groups
This is the table for the Post variation groups. It holds a list of variation group tables.
One subtable per variation group. See examples below

flame.xforms[n].postVarGroups {table - one table per Post variation group}

   Each variatin group subtable has a list of variation tables

flame.xforms[n].postVarGroups[g][v].name
flame.xforms[n].postVarGroups[g][v].weight
flame.xforms[n].postVarGroups[g][v].instance
flame.xforms[n].postVarGroups[g][v]…. variation-parameter-specific string
flame.xforms[n].postVarGroups[g][v].coefs {table - special for matrix variations}

Final Xform parameters:
flame.finalxform.weight
flame.finalxform.color
flame.finalxform.symmetry
flame.finalxform.is_finalxform {string}
flame.finalxform.coefs
flame.finalxform.post
flame.finalxform.variations
flame.finalxform.variations.name
flame.finalxform.variations.weight
flame.finalxform.variations…. variation-specific string

Color Curve parameters: (optional)
flame.rgb_curve        {table} has one subtable for each x,y curve node
flame.rgb_curve[n].x
flame.rgb_curve[n].y

flame.red_curve       {table} has one subtable for each x,y curve node
flame.red_curve[n].x
flame.red_curve[n].y

flame.green_curve       {table} has one subtable for each x,y curve node
flame.green_curve[n].x
flame.green_curve[n].y

flame.blue_curve       {table} has one subtable for each x,y curve node
flame.blue_curve[n].x
flame.blue_curve[n].y

Examples of Specifying a Variation Instance

flame.xforms[1].variations[2] = { name=“linear”, weight=1. }
Xform #1’s variation#2 is a linear variation with weight of 1.

table.insert(xform.variations({ name=“modulus”, weight=0.5, modulus_x = 2., modulus_y = 3. })
Insert a modulus variation with weight 0.5 and its x parameter of 2 and y parameter of 3.

Examples of Creating a Matrix Variation Group

Here we are creating a “matrix2d” variation instance, randomizing the matrix, then creating a new variation group and appending it onto the variation chain.

matrix2d = { name=“matrix2d”, weight=1., coefs=makeCoefs() }
randomPreMatrix(matrix2d)
table.insert(chain, { matrix2d })


Utility Functions for Creating Blank Fractals

make a new blank fractal
makeBlankFractal(xformCount) – returns table or nil if xformCount == 0
make a Xaos table prepopulated with all from/to values = 1
makeNormalXaos(xformCount) – returns table or nil if xformCount == 0
make a random Color map
makeRandomColors(colorCount) – returns color table on stack or nil on stack if colorCount == 0
make an identity Transformation matrix – returns the table
makeIdentityMatrix() – returns table

identity matrix:

[ 1 0 0 ] where [ a b c ]

[ 0 1 0 ]           [ d e f ]

make a Coefs matrix – returns the table
makeCoefs() – returns table

identity matrix:

[ 1 0 0 ] where [ a b c ]

[ 0 1 0 ]           [ d e f ]

make a new blank xform
makeBlankXform() – returns table
Prepopulated with:
 weight = 1
 color = 0
 symmetry = 0
 opacity = 1
 var_color = 1
 No variations defined - empty variations table is included

make a new blank final xform
makeBlankFinalXform() – returns table
Prepopulated with:
 weight = 1
 color = 0
 symmetry = 0
 opacity = 1
 var_color = 1
 No variations defined - empty variations table is included

Utils.lua

Most Make Fractal scripts will use include this Lua package file. This is how they include the package file.

    require("Utils")

Useful Lua functions in Utils.lua

This file written by Ralf Flicker and used in his scripts and other Lua scripts has some functions to rotate, scale and translate an xform’s Pre triangle. (The Triangle is just a way to graphically show the affect of the matrix transformation.)

Convert Cartesian coordinates to Polar coordinates
c2p (x,y)

Convert Polar coordinates to Cartesian coordinates
p2c (x,y)

Rotate the xform Pre-matrix triangle about its own Triangle origin

affine_rotate (xform,phs)   OR  affine_Prot (xform,phs)

xform - the xform table phs - the rotation amount in degrees units


Rotate the xform Pre-matrix triangle about the World origin

affine_Orot (xform,phs)

xform - the xform table phs - the rotation amount in degrees units


Translate (move) the xform Pre-matrix triangle

affine_translate (xform,x,y)

xform - the xform table x - the translation along the X axis y - the translation along the Y axis


Scale the xform Pre-matrix triangle (relative to the Triangle’s own origin)

affine_scale (xform,sf)

xform - the xform table sf - the scale factor


Rotate the xform Post-matrix triangle about its own Triangle origin

postAffine_rotate (xform,phs)   OR  postAffine_Prot (xform,phs)

xform - the xform table phs - the rotation amount in degrees units


Rotate the xform Post-matrix triangle about the World origin

postAffine_Orot (xform,phs)

xform - the xform table phs - the rotation amount in degrees units


Translate (move) the xform Post-matrix triangle

postAffine_translate (xform,x,y)

xform - the xform table x - the translation along the X axis y - the translation along the Y axis


Scale the xform Post-matrix triangle (relative to the Triangle’s own origin)

postAffine_scale (xform,sf)

xform - the xform table sf - the scale factor


Pick a random variation name from the current variation set.
random_variation()

Randomize the Pre Matrix

randomPreMatrix (xform)

xform - the xform table


Randomize the Post Matrix

randomPostMatrix (xform)

xform - the xform table

Setting/Getting Transformation Matrix Cell Values

The 2 dimensional transformation matrix used by most flame renderers today all have 6 values in each transformation matrix. Each Xform structure in a flame fractal has two transformation matrices: coefs and post.

The Fractal Architect app refers to the Lua coefs matrix table as the Pre matrix, and the Lua post matrix table as the Post matrix.

Special Rule: Matrix variation types have a coefs matrix table too.

NOTE: A little confusion between FA/flam3 and Apophysis notation for the individual transformation matrix fields a - f.
Apophysis uses column order labeling, whereas flam3/Factal Architect uses row order labeling.
The table below shows how to convert between the notations

upper case letters ==> Apophysis

lower case letters ==> flam3 and Fractal Architect

Flam3 labels - row ordered

| a b c |

| d e f |

Apophysis labels - column ordered

| A C E |

| B D F |

Lua Matrix Cell Indexing

|   m[1][1]  m[2][1]  m[3][1]   |

|   m[1][2]  m[2][2]  m[3][2]   |

Each row here all refers to the same matrix cell value:
               coefs.a = coefs[1][1] = coefs.A(coefs) = coefs:A()               
               coefs.b = coefs[2][1] = coefs.C(coefs) = coefs:C()               
               coefs.c = coefs[3][1] = coefs.E(coefs) = coefs:E()
               coefs.d = coefs[1][2] = coefs.B(coefs) = coefs:B()
               coefs.e = coefs[2][2] = coefs.D(coefs) = coefs:D()
               coefs.f = coefs[3][2] = coefs.F(coefs) = coefs:F()

               post.a = post[1][1] = post.A(post) = post:A()
               post.b = post[2][1] = post.C(post) = post:C()
               post.c = post[3][1] = post.E(post) = post:E()
               post.d = post[1][2] = post.B(post) = post:B()
               post.e = post[2][2] = post.D(post) = post:D()
               post.f = post[3][2] = post.F(post) = post:F()

Apophysis-Like Getter/Setter functions

These are the Apophysis-like getter/setter functions to make it easier to port Apophysis scripts to Lua.

get A - returns A
coefs.A(coefs)  OR  coefs:A()
set A - sets the A and also returns it
coefs.A(coefs, A)  OR  coefs:A(A)

get B - returns B
coefs.B(coefs)  OR  coefs:B()
set B - sets the B and also returns it
coefs.B(coefs, B)  OR  coefs:B(B)

get C - returns C
coefs.C(coefs)  OR  coefs:C()
set C - sets the C and also returns it
coefs.C(coefs, C)  OR  coefs:C(C)

get D - returns D
coefs.D(coefs)  OR  coefs:D()
set D - sets the D and also returns it
coefs.D(coefs, D)  OR  coefs:D(D)

get E - returns E
coefs.E(coefs)  OR  coefs:E()
set E - sets the E and also returns it
coefs.E(coefs, E)  OR  coefs:E(E)

get F - returns F
coefs.F(coefs)  OR  coefs:F()
set F - sets the F and also returns it
coefs.F(coefs, F)  OR  coefs:F(F)

Variation Set Related Tables and Builtin Functions


The variationset table holds all of the variations and their parameter info for the app’s current variation set. A variation set determines the variations available to the renderer (for a single fractal render). Fractal Architect can simultaneously render fractals that use different variation sets. However the Random Fractal Generator works uses a single Variation set for creating fractals. (Those fractals will all refer to that variation set.)

Scripts typically use the Variation Set information to learn what variations are available for the current variation set.

The Variationset Lua Table and Its Contents

variationSet
variationSet table (table)
variationSet.name
variationSet’s name (string)
variationSet.uuid
variationSet’s uuid (string)
variationSet.defaultVariation
variationSet’s default variation (string)
variationSet.is3D
variationSet’s is3D (bool)
variationSet.variations
variation subtables indexed by name (table)

variationSet.variationlist
list of variation names (table)
variationSet.variationlist[n]
nth variation’s name (string)

variationSet[n]
list of variation tables (table)
variationSet[n].variation
variation name (string)
variationSet[n].param_count
parameter count (integer)
variationSet[n].param_names
parameter name list for it (table)
variationSet[n].param_names[n]
parameter name (string)
variationSet[n].parame_keys
parameter key list for it (table)
variationSet[n].param_keys[n]
expanded parameter key (string)
expanded parameter name is variationName_parameterName
    for example: “julian” has a “power” parameter, whose expanded name ====> julian_power

Builtin Variation Set Utility Functions

variationSet.filterVariations(variationNamesList)
returns filtered variationNamesList retaining only the variation names supported by this variation set
bool variationSet.hasVariations(variationNamesList)
return whether the input list of variation names is serviced by the current variation set
bool switchToVariationSetWithUuid(uuid)
switch variation set - supply the new variation set’s uuid – returns if it was successful
variation set uuids will always be unique
switchToVariationSetWithName(name)
switch variation set - supply the new variation set’s name – returns if it was successful
it returns the first variation set it finds that matches the name
variation set names are not necessarily unique
switchToFirstVariationSetWithRequiredVariations(varlist)
returns true if a variation set supporting the varlist is found and switched to
for example: switchToFirstVariationSetWithRequiredVariations({“julian”, “linear”})
variationset.variationIs2D( variation_name )
returns whether that variation is a 2D variation
Example Lua code Snippet: to find the parameter names and keys for variation “julian”
-- get the variations table for "julian" and return its name 
varName = variationSet.variations.julian.variation
    OR
varName = variationSet.variations["julian"].variation

-- Print the list of parameter names
 for i, name in variationSet.variations.julian.param_names do
    print(name) 
end

-- Print the list of parameter names
 for i, key  in variationSet.variations.julian.param_keys  do
   print(key)
end

Other new functions defined by Fractal Architect

open the Lua console if it not open already
showLuaConsole()
open the Preview window for fractal - defaults to “flame”
openPreview( [table] )
open the Quicklook window for fractal - defaults to “flame”
quicklook( [table] )
open the standard Variants window for fractal - defaults to “flame”
variants( [table] )
open the Super Variants window for fractal - defaults to “flame”
superVariants( [table] )
open the fractal info viewer for fractal - defaults to “flame”
showInfo( [table] )
open the XML viewer for fractal - defaults to “flame”
showXml( [table] )

math.round() Function (Additional Function for math package)

Round number to nearest integer
math.round(number) – rounds the number to the nearest integer
see round() in standard C library

FA Library - Other Builtin Utility Functions


The FA library has several useful functions for printing out intermediate results

FA.print(string)
Print the string to Lua console.
FA.print_stack()
Print the Lua stack contents to Lua console.
FA.print_item(item)
Print the item’s contents to Lua console.
FA.quality_adjust(adjust)
Multiply the render quality by this quality multiplier
Some fractals need higher than normal render quality. If your scripts creates fractals needing longer render times, this quality multiplier will tell the app to set the render quality higher.

GPU rendering tends to have higher noise at typical preview quality amounts. The multiplier here tells the app to increase the preview render by this quality multiplier.

Other Modules

Fractal Architect provides a couple of very useful factory modules:

GradientsModule.lua - Create/Change Color Gradient

Example usage in a custom Lua script:

In this example, a monochromatic color gradient is created, with a 20% probability of totally random colors being added because no weightRandom parameter is used.

The third line shows how to not have random colors added to the gradient.

local Gradients = require "GradientsModule"
Gradients.monochromaticScheme() -- 20% probability of random color
Gradients.monochromaticScheme(0.) -- 0% probability of random color
Make color gradient using Analogous color scheme.

It has an optional parameter, weightRandom, that determines the probability that a totally random color is added, instead of an analogous one.

Gradients.analogousScheme(weightRandom)

weightRandom - probability that a totally random color will be chosen. Range between 0 and 1 inclusive. Default value = 0.2 (20% probability)

Make color gradient using Complementary color scheme

It has an optional parameter, weightRandom, that determines the probability that a totally random color is added, instead of an analogous one.

Gradients.complementaryScheme(weightRandom)

weightRandom - probability that a totally random color will be chosen. Range between 0 and 1 inclusive. Default value = 0.2 (20% probability)

Make color gradient using Grayscale color scheme

It has an optional parameter, weightRandom, that determines the probability that a totally random color is added, instead of an analogous one.

Gradients.grayscaleScheme(weightRandom)

weightRandom - probability that a totally random color will be chosen. Range between 0 and 1 inclusive. Default value = 0.2 (20% probability)

Make color gradient using Monochromatic color scheme

It has an optional parameter, weightRandom, that determines the probability that a totally random color is added, instead of an analogous one.

Gradients.monochromaticScheme(weightRandom)

weightRandom - probability that a totally random color will be chosen. Range between 0 and 1 inclusive. Default value = 0.2 (20% probability)

Make color gradient using Random color scheme

Gradients.randomColorsScheme()

Rotate color gradient by a random number of color stops

Gradients.rotateGradient()

PrePostVariationsModule.lua - Modify Variations in Pre/Post Variation Groups

Example usage in a custom Lua script:

In this example, we are adding a Julian variation to the Pre Variation Group of every transform (probability of adding it to a transform here is 66.66667%).

local PrePostVariations = require "PrePostVariationsModule"
PrePostVariations.preVarPar(
    { name="julian", weight=2.*math.random(),
      julian_power = math.random(1,3),
      julian_dist  = 0.1 + math.random() * 2.9},
    0.666667) --66.6667% chance of adding Julian variation to Pre variation Group
Randomly insert the group of variation and variation parameters into the first Pre Variation Group of each transform.

PrePostVariations.preVarPar(varpars, weight)

varpars - table containing a list of variation names, variation weights, and their variation parameter values (if any)

weight - probability that the varpars is inserted - should be between 0. and 1 inclusive. Default value = 0.3 (30% probability)

A varpars table must have these fields for a variation’s attributes (see example):
name - variation name
weight - variation weight
optional fully qualified variation parameters i.e. cpow_power = math.random(1, 5)

Randomly insert the group of variation and variation parameters into the first Post Variation Group of each transform.

PrePostVariations.postVarPar(varpars, weight)

varpars - table containing a list of variation names, variation weights, and their variation parameter values (if any)

weight - probability that the varpars is inserted - should be between 0. and 1 inclusive. Default value = 0.3 (30% probability)

Randomly prepend new first Pre-Variation Group to each transform then insert the varpars (group of variation and variation parameters) into the new Pre Variation Group.

PrePostVariations.prependNewPreVarGroup(varpars, weight)

varpars - table containing a list of variation names, variation weights, and their variation parameter values (if any)

weight - probability that the varpars is inserted - should be between 0. and 1 inclusive. Default value = 0.3 (30% probability)

Randomly append new first Pre-Variation Group to each transform then insert the varpars (group of variation and variation parameters) into the new Pre Variation Group.

PrePostVariations.appendNewPreVarGroup(varpars, weight)

varpars - table containing a list of variation names, variation weights, and their variation parameter values (if any)

weight - probability that the varpars is inserted - should be between 0. and 1 inclusive. Default value = 0.3 (30% probability)

Randomly append new first Pre-Variation Group to each transform - but only if the pre var group list is not empty then insert the varpars (group of variation and variation parameters) into the new Pre Variation Group.

PrePostVariations.appendAnotherNewPreVarGroup(varpars, weight)

varpars - table containing a list of variation names, variation weights, and their variation parameter values (if any)

weight - probability that the varpars is inserted - should be between 0. and 1 inclusive. Default value = 0.3 (30% probability)

Randomly prepend new first Post-Variation Group to each transform then insert the varpars (group of variation and variation parameters) into the new Post Variation Group.

PostPostVariations.postpendNewPostVarGroup(varpars, weight)

varpars - table containing a list of variation names, variation weights, and their variation parameter values (if any)

weight - probability that the varpars is inserted - should be between 0. and 1 inclusive. Default value = 0.3 (30% probability)

Randomly append new first Post-Variation Group to each transform then insert the varpars (group of variation and variation parameters) into the new Post Variation Group.

PostPostVariations.appendNewPostVarGroup(varpars, weight)

varpars - table containing a list of variation names, variation weights, and their variation parameter values (if any)

weight - probability that the varpars is inserted - should be between 0. and 1 inclusive. Default value = 0.3 (30% probability)

Randomly append new first Post-Variation Group to each transform - but only if the post var group list is not empty then insert the varpars (group of variation and variation parameters) into the new Post Variation Group.

PostPostVariations.appendAnotherNewPostVarGroup(varpars, weight)

varpars - table containing a list of variation names, variation weights, and their variation parameter values (if any)

weight - probability that the varpars is inserted - should be between 0. and 1 inclusive. Default value = 0.3 (30% probability)