2014-07-08 03:11:14 -04:00
# include "FractoriumPch.h"
# include "FractoriumEmberController.h"
# include "Fractorium.h"
# include "GLEmberController.h"
/// <summary>
/// Constructor which initializes the non-templated members contained in this class.
/// The renderer, other templated members and GUI setup will be done in the templated derived controller class.
/// </summary>
/// <param name="fractorium">Pointer to the main window.</param>
FractoriumEmberControllerBase : : FractoriumEmberControllerBase ( Fractorium * fractorium )
2017-02-26 12:34:43 -05:00
: m_PaletteList ( PaletteList < float > : : Instance ( ) )
2014-07-08 03:11:14 -04:00
{
Timing t ;
m_Fractorium = fractorium ;
m_Rand = QTIsaac < ISAAC_SIZE , ISAAC_INT > ( ISAAC_INT ( t . Tic ( ) ) , ISAAC_INT ( t . Tic ( ) * 2 ) , ISAAC_INT ( t . Tic ( ) * 3 ) ) ; //Ensure a different rand seed on each instance.
2016-04-03 21:55:12 -04:00
m_RenderTimer = make_unique < QTimer > ( m_Fractorium ) ;
2014-07-08 03:11:14 -04:00
m_RenderTimer - > setInterval ( 0 ) ;
2016-02-12 00:38:21 -05:00
m_Fractorium - > connect ( m_RenderTimer . get ( ) , SIGNAL ( timeout ( ) ) , SLOT ( IdleTimer ( ) ) ) ;
2016-04-03 21:55:12 -04:00
m_RenderRestartTimer = make_unique < QTimer > ( m_Fractorium ) ;
2016-02-12 00:38:21 -05:00
m_Fractorium - > connect ( m_RenderRestartTimer . get ( ) , SIGNAL ( timeout ( ) ) , SLOT ( StartRenderTimer ( ) ) ) ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
/// Destructor which stops rendering and deletes the timers.
/// All other memory is cleared automatically through the use of STL.
/// </summary>
FractoriumEmberControllerBase : : ~ FractoriumEmberControllerBase ( )
{
StopRenderTimer ( true ) ;
2016-02-12 00:38:21 -05:00
m_RenderTimer - > stop ( ) ;
m_RenderRestartTimer - > stop ( ) ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
/// Constructor which passes the main window parameter to the base, initializes the templated members contained in this class.
/// Then sets up the parts of the GUI that require templated Widgets, such as the variations tree and the palette table.
/// Note the renderer is not setup here automatically. Instead, it must be manually created by the caller later.
/// </summary>
/// <param name="fractorium">Pointer to the main window.</param>
template < typename T >
FractoriumEmberController < T > : : FractoriumEmberController ( Fractorium * fractorium )
2016-02-18 21:58:24 -05:00
: FractoriumEmberControllerBase ( fractorium ) ,
m_VariationList ( VariationList < T > : : Instance ( ) )
2014-07-08 03:11:14 -04:00
{
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
size_t b = 0 ;
2016-04-03 21:55:12 -04:00
m_GLController = make_unique < GLEmberController < T > > ( fractorium , fractorium - > ui . GLDisplay , this ) ;
2016-06-11 20:47:03 -04:00
m_LibraryPreviewRenderer = make_unique < TreePreviewRenderer < T > > ( this , m_Fractorium - > ui . LibraryTree , m_EmberFile ) ;
m_SequencePreviewRenderer = make_unique < TreePreviewRenderer < T > > ( this , m_Fractorium - > ui . SequenceTree , m_SequenceFile ) ;
2017-02-26 12:34:43 -05:00
m_PaletteList - > Clear ( ) ;
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
m_Fractorium - > ui . PaletteFilenameCombo - > clear ( ) ;
2015-04-08 21:23:29 -04:00
//Initial combo change event to fill the palette table will be called automatically later.
2015-12-31 16:41:59 -05:00
//Look hard for a palette.
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
auto paths = GetDefaultPaths ( ) ;
2016-02-12 00:38:21 -05:00
for ( auto & path : paths )
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
b | = InitPaletteList ( path ) ;
if ( b )
2016-02-12 00:38:21 -05:00
{
2017-02-26 12:34:43 -05:00
m_SheepTools = make_unique < SheepTools < T , float > > ( m_PaletteList - > Name ( 0 ) , new EmberNs : : Renderer < T , float > ( ) ) ;
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
}
else
{
QString allPaths ;
for ( auto & path : paths )
allPaths + = path + " \r \n " ;
allPaths = QString ( " No palettes found in paths: \r \n " ) + allPaths + " \r \n Exiting. " ;
std : : runtime_error ex ( allPaths . toStdString ( ) ) ;
throw ex ;
2015-12-31 16:41:59 -05:00
}
2015-04-08 21:23:29 -04:00
2017-02-26 12:34:43 -05:00
if ( m_PaletteList - > Size ( ) > = 1 ) //Only add the user palette if the folder already had a palette, which means we'll be using this folder.
if ( m_PaletteList - > AddEmptyPaletteFile ( ( GetDefaultUserPath ( ) + " /user-palettes.xml " ) . toStdString ( ) ) )
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
m_Fractorium - > ui . PaletteFilenameCombo - > addItem ( " user-palettes.xml " ) ;
2016-02-12 00:38:21 -05:00
2014-07-08 03:11:14 -04:00
BackgroundChanged ( QColor ( 0 , 0 , 0 ) ) ; //Default to black.
ClearUndo ( ) ;
}
/// <summary>
/// Empty destructor that does nothing.
/// </summary>
template < typename T >
FractoriumEmberController < T > : : ~ FractoriumEmberController ( ) { }
/// <summary>
/// Setters for embers, ember files and palettes which convert between float and double types.
/// These are used to preserve the current ember/file when switching between renderers.
/// Note that some precision will be lost when going from double to float.
/// </summary>
2016-04-13 23:59:57 -04:00
template < typename T > void FractoriumEmberController < T > : : SetEmber ( const Ember < float > & ember , bool verbatim , bool updatePointer ) { SetEmberPrivate < float > ( ember , verbatim , updatePointer ) ; }
2014-10-14 11:53:15 -04:00
template < typename T > void FractoriumEmberController < T > : : CopyEmber ( Ember < float > & ember , std : : function < void ( Ember < float > & ember ) > perEmberOperation ) { ember = m_Ember ; perEmberOperation ( ember ) ; }
2016-06-11 20:47:03 -04:00
template < typename T > void FractoriumEmberController < T > : : SetEmberFile ( const EmberFile < float > & emberFile , bool move ) { move ? m_EmberFile = std : : move ( emberFile ) : m_EmberFile = emberFile ; }
template < typename T > void FractoriumEmberController < T > : : CopyEmberFile ( EmberFile < float > & emberFile , bool sequence , std : : function < void ( Ember < float > & ember ) > perEmberOperation )
2014-10-14 11:53:15 -04:00
{
2016-06-11 20:47:03 -04:00
if ( sequence )
{
emberFile . m_Filename = m_SequenceFile . m_Filename ;
CopyCont ( emberFile . m_Embers , m_SequenceFile . m_Embers , perEmberOperation ) ;
}
else
{
emberFile . m_Filename = m_EmberFile . m_Filename ;
CopyCont ( emberFile . m_Embers , m_EmberFile . m_Embers , perEmberOperation ) ;
}
2014-10-14 11:53:15 -04:00
}
2014-07-08 03:11:14 -04:00
template < typename T > void FractoriumEmberController < T > : : SetTempPalette ( const Palette < float > & palette ) { m_TempPalette = palette ; }
template < typename T > void FractoriumEmberController < T > : : CopyTempPalette ( Palette < float > & palette ) { palette = m_TempPalette ; }
# ifdef DO_DOUBLE
2016-04-13 23:59:57 -04:00
template < typename T > void FractoriumEmberController < T > : : SetEmber ( const Ember < double > & ember , bool verbatim , bool updatePointer ) { SetEmberPrivate < double > ( ember , verbatim , updatePointer ) ; }
2014-10-14 11:53:15 -04:00
template < typename T > void FractoriumEmberController < T > : : CopyEmber ( Ember < double > & ember , std : : function < void ( Ember < double > & ember ) > perEmberOperation ) { ember = m_Ember ; perEmberOperation ( ember ) ; }
2016-06-11 20:47:03 -04:00
template < typename T > void FractoriumEmberController < T > : : SetEmberFile ( const EmberFile < double > & emberFile , bool move ) { move ? m_EmberFile = std : : move ( emberFile ) : m_EmberFile = emberFile ; }
template < typename T > void FractoriumEmberController < T > : : CopyEmberFile ( EmberFile < double > & emberFile , bool sequence , std : : function < void ( Ember < double > & ember ) > perEmberOperation )
2014-10-14 11:53:15 -04:00
{
2016-06-11 20:47:03 -04:00
if ( sequence )
{
emberFile . m_Filename = m_SequenceFile . m_Filename ;
CopyCont ( emberFile . m_Embers , m_SequenceFile . m_Embers , perEmberOperation ) ;
}
else
{
emberFile . m_Filename = m_EmberFile . m_Filename ;
CopyCont ( emberFile . m_Embers , m_EmberFile . m_Embers , perEmberOperation ) ;
}
2014-10-14 11:53:15 -04:00
}
2014-07-08 03:11:14 -04:00
template < typename T > void FractoriumEmberController < T > : : SetTempPalette ( const Palette < double > & palette ) { m_TempPalette = palette ; }
template < typename T > void FractoriumEmberController < T > : : CopyTempPalette ( Palette < double > & palette ) { palette = m_TempPalette ; }
# endif
template < typename T > Ember < T > * FractoriumEmberController < T > : : CurrentEmber ( ) { return & m_Ember ; }
2014-10-14 11:53:15 -04:00
template < typename T >
void FractoriumEmberController < T > : : ConstrainDimensions ( Ember < T > & ember )
{
2016-02-13 20:24:51 -05:00
ember . m_FinalRasW = std : : min < int > ( m_Fractorium - > ui . GLDisplay - > MaxTexSize ( ) , int ( ember . m_FinalRasW ) ) ;
ember . m_FinalRasH = std : : min < int > ( m_Fractorium - > ui . GLDisplay - > MaxTexSize ( ) , int ( ember . m_FinalRasH ) ) ;
2014-10-14 11:53:15 -04:00
}
2014-07-08 03:11:14 -04:00
/// <summary>
/// Set the ember at the specified index from the currently opened file as the current Ember.
/// Clears the undo state.
/// Resets the rendering process.
/// </summary>
/// <param name="index">The index in the file from which to retrieve the ember</param>
2016-04-13 23:59:57 -04:00
/// <param name="verbatim">If true, do not overwrite temporal samples, quality or supersample value, else overwrite.</param>
2014-07-08 03:11:14 -04:00
template < typename T >
2016-04-13 23:59:57 -04:00
void FractoriumEmberController < T > : : SetEmber ( size_t index , bool verbatim )
2014-07-08 03:11:14 -04:00
{
2014-10-14 11:53:15 -04:00
if ( index < m_EmberFile . Size ( ) )
2014-07-08 03:11:14 -04:00
{
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
m_Fractorium - > SelectLibraryItem ( index ) ;
2014-07-08 03:11:14 -04:00
ClearUndo ( ) ;
2016-04-13 23:59:57 -04:00
SetEmber ( * m_EmberFile . Get ( index ) , verbatim , true ) ;
2014-07-08 03:11:14 -04:00
}
}
/// <summary>
/// Wrapper to call a function, then optionally add the requested action to the rendering queue.
/// </summary>
/// <param name="func">The function to call</param>
2015-03-21 18:27:37 -04:00
/// <param name="updateRender">True to update renderer, else false. Default: true.</param>
2015-12-31 19:00:36 -05:00
/// <param name="action">The action to add to the rendering queue. Default: eProcessAction::FULL_RENDER.</param>
2014-07-08 03:11:14 -04:00
template < typename T >
2016-05-02 19:54:56 -04:00
void FractoriumEmberController < T > : : Update ( std : : function < void ( void ) > func , bool updateRender , eProcessAction action )
2014-07-08 03:11:14 -04:00
{
func ( ) ;
if ( updateRender )
UpdateRender ( action ) ;
}
2016-05-02 19:54:56 -04:00
/// <summary>
/// Wrapper to call a function on the current ember and optionally all other embers in the file.
/// Then optionally add the requested action to the rendering queue.
/// </summary>
/// <param name="func">The function to call</param>
/// <param name="updateRender">True to update renderer, else false. Default: true.</param>
/// <param name="action">The action to add to the rendering queue. Default: eProcessAction::FULL_RENDER.</param>
/// <param name="applyAll">True to apply the action to all embers in the file in addition to the curent one, false to apply the action only to the current one.</param>
template < typename T >
void FractoriumEmberController < T > : : UpdateAll ( std : : function < void ( Ember < T > & ember ) > func , bool updateRender , eProcessAction action , bool applyAll )
{
func ( m_Ember ) ;
if ( applyAll )
for ( auto & it : m_EmberFile . m_Embers )
func ( it ) ;
if ( updateRender )
UpdateRender ( action ) ;
}
2014-07-08 03:11:14 -04:00
/// <summary>
2015-04-27 01:11:56 -04:00
/// Wrapper to call a function on the specified xforms, then optionally add the requested action to the rendering queue.
/// If no xforms are selected via the checkboxes, and the update type is UPDATE_SELECTED, then the function will be called only on the currently selected xform.
2016-02-02 20:51:58 -05:00
/// If the update type is UPDATE_CURRENT_AND_SELECTED, and the current is not among those selected, then the function will be called on the currently selected xform as well.
2014-07-08 03:11:14 -04:00
/// </summary>
/// <param name="func">The function to call</param>
2016-01-04 19:50:15 -05:00
/// <param name="updateType">Whether to apply this update operation on the current, all or selected xforms. Default: eXformUpdate::UPDATE_CURRENT.</param>
2014-11-04 20:38:20 -05:00
/// <param name="updateRender">True to update renderer, else false. Default: true.</param>
2015-12-31 19:00:36 -05:00
/// <param name="action">The action to add to the rendering queue. Default: eProcessAction::FULL_RENDER.</param>
2014-07-08 03:11:14 -04:00
template < typename T >
2015-04-27 01:11:56 -04:00
void FractoriumEmberController < T > : : UpdateXform ( std : : function < void ( Xform < T > * ) > func , eXformUpdate updateType , bool updateRender , eProcessAction action )
2014-07-08 03:11:14 -04:00
{
2016-02-13 20:24:51 -05:00
int i = 0 ;
2015-04-27 01:11:56 -04:00
bool isCurrentFinal = m_Ember . IsFinalXform ( CurrentXform ( ) ) ;
bool doFinal = updateType ! = eXformUpdate : : UPDATE_SELECTED_EXCEPT_FINAL & & updateType ! = eXformUpdate : : UPDATE_ALL_EXCEPT_FINAL ;
switch ( updateType )
2014-07-08 03:11:14 -04:00
{
2015-04-27 01:11:56 -04:00
case eXformUpdate : : UPDATE_CURRENT :
{
2016-02-02 20:51:58 -05:00
if ( auto xform = CurrentXform ( ) )
2015-04-27 01:11:56 -04:00
func ( xform ) ;
}
break ;
2016-02-02 20:51:58 -05:00
case eXformUpdate : : UPDATE_CURRENT_AND_SELECTED :
{
bool currentDone = false ;
auto current = CurrentXform ( ) ;
while ( auto xform = m_Ember . GetTotalXform ( i ) )
{
2016-12-05 22:04:33 -05:00
if ( i < m_Fractorium - > m_XformSelections . size ( ) )
2016-02-02 20:51:58 -05:00
{
2016-12-05 22:04:33 -05:00
if ( auto w = m_Fractorium - > m_XformSelections [ i ] )
2016-02-02 20:51:58 -05:00
{
if ( w - > isChecked ( ) )
{
func ( xform ) ;
if ( xform = = current )
currentDone = true ;
}
}
}
i + + ;
}
if ( ! currentDone ) //Current was not among those selected, so apply to it.
func ( current ) ;
}
break ;
2015-04-27 01:11:56 -04:00
case eXformUpdate : : UPDATE_SELECTED :
case eXformUpdate : : UPDATE_SELECTED_EXCEPT_FINAL :
{
bool anyUpdated = false ;
2016-02-02 20:51:58 -05:00
while ( auto xform = ( doFinal ? m_Ember . GetTotalXform ( i ) : m_Ember . GetXform ( i ) ) )
2015-04-27 01:11:56 -04:00
{
2016-12-05 22:04:33 -05:00
if ( i < m_Fractorium - > m_XformSelections . size ( ) )
2015-04-27 01:11:56 -04:00
{
2016-12-05 22:04:33 -05:00
if ( auto w = m_Fractorium - > m_XformSelections [ i ] )
2015-04-27 01:11:56 -04:00
{
if ( w - > isChecked ( ) )
{
func ( xform ) ;
anyUpdated = true ;
}
}
}
i + + ;
}
2014-07-08 03:11:14 -04:00
2015-04-27 01:11:56 -04:00
if ( ! anyUpdated ) //None were selected, so just apply to the current.
if ( doFinal | | ! isCurrentFinal ) //If do final, call func regardless. If not, only call if current is not final.
2016-02-02 20:51:58 -05:00
if ( auto xform = CurrentXform ( ) )
2015-04-27 01:11:56 -04:00
func ( xform ) ;
}
break ;
case eXformUpdate : : UPDATE_ALL :
{
2016-02-02 20:51:58 -05:00
while ( auto xform = m_Ember . GetTotalXform ( i + + ) )
2015-04-27 01:11:56 -04:00
func ( xform ) ;
}
break ;
case eXformUpdate : : UPDATE_ALL_EXCEPT_FINAL :
default :
{
2016-02-02 20:51:58 -05:00
while ( auto xform = m_Ember . GetXform ( i + + ) )
2015-04-27 01:11:56 -04:00
func ( xform ) ;
}
break ;
2014-07-08 03:11:14 -04:00
}
2015-04-27 01:11:56 -04:00
if ( updateRender )
UpdateRender ( action ) ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
/// Set the current ember, but use GUI values for the fields which make sense to
/// keep the same between ember selection changes.
/// Note the extra template parameter U allows for assigning ember of different types.
/// Resets the rendering process.
/// </summary>
/// <param name="ember">The ember to set as the current</param>
2015-07-15 23:27:32 -04:00
/// <param name="verbatim">If true, do not overwrite temporal samples, quality or supersample value, else overwrite.</param>
2016-04-13 23:59:57 -04:00
/// <param name="updatePointer">If true, update the current ember pointer to the address of the one passed in.</param>
2014-07-08 03:11:14 -04:00
template < typename T >
template < typename U >
2016-04-13 23:59:57 -04:00
void FractoriumEmberController < T > : : SetEmberPrivate ( const Ember < U > & ember , bool verbatim , bool updatePointer )
2014-07-08 03:11:14 -04:00
{
if ( ember . m_Name ! = m_Ember . m_Name )
m_LastSaveCurrent = " " ;
2015-12-31 16:41:59 -05:00
2015-01-02 18:11:36 -05:00
size_t w = m_Ember . m_FinalRasW ; //Cache values for use below.
size_t h = m_Ember . m_FinalRasH ;
2014-07-08 03:11:14 -04:00
m_Ember = ember ;
2016-04-13 23:59:57 -04:00
if ( updatePointer )
m_EmberFilePointer = & ember ;
2014-07-08 03:11:14 -04:00
if ( ! verbatim )
{
m_Ember . m_TemporalSamples = 1 ; //Change once animation is supported.
m_Ember . m_Quality = m_Fractorium - > m_QualitySpin - > value ( ) ;
m_Ember . m_Supersample = m_Fractorium - > m_SupersampleSpin - > value ( ) ;
}
2015-12-31 16:41:59 -05:00
static EmberToXml < T > writer ; //Save parameters of last full render just in case there is a crash.
2017-02-26 12:34:43 -05:00
auto path = GetDefaultUserPath ( ) ;
QDir dir ( path ) ;
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
if ( ! dir . exists ( ) )
dir . mkpath ( " . " ) ;
2017-02-26 12:34:43 -05:00
string filename = path . toStdString ( ) + " /last.flame " ;
2016-05-02 19:54:56 -04:00
writer . Save ( filename . c_str ( ) , m_Ember , 0 , true , true , false , true , true ) ;
2015-01-02 18:11:36 -05:00
m_GLController - > ResetMouseState ( ) ;
2015-04-27 01:11:56 -04:00
FillXforms ( ) ; //Must do this first because the palette setup in FillParamTablesAndPalette() uses the xforms combo.
2014-07-08 03:11:14 -04:00
FillParamTablesAndPalette ( ) ;
2016-03-28 21:49:10 -04:00
FillCurvesControl ( ) ;
2015-07-15 23:27:32 -04:00
FillSummary ( ) ;
2015-01-02 18:11:36 -05:00
//If a resize happened, this won't do anything because the new size is not reflected in the scroll area yet.
2015-12-31 16:41:59 -05:00
//However, it will have been taken care of in SyncSizes() in that case, so it's ok.
2015-01-02 18:11:36 -05:00
//This is for when a new ember with the same size was loaded. If it was larger than the scroll area, and was scrolled, re-center it.
if ( m_Ember . m_FinalRasW = = w & & m_Ember . m_FinalRasH = = h )
m_Fractorium - > CenterScrollbars ( ) ;
2014-12-11 00:50:15 -05:00
}
2016-06-11 20:47:03 -04:00
/// <summary>
/// Thin derivation to handle preview rendering multiple embers previews to a tree.
/// </summary>
/// <param name="start">The 0-based index to start rendering previews for</param>
/// <param name="end">The 0-based index which is one beyond the last ember to render a preview for</param>
template < typename T >
void TreePreviewRenderer < T > : : PreviewRenderFunc ( uint start , uint end )
{
auto f = m_Controller - > m_Fractorium ;
m_PreviewRenderer . EarlyClip ( f - > m_Settings - > EarlyClip ( ) ) ;
m_PreviewRenderer . YAxisUp ( f - > m_Settings - > YAxisUp ( ) ) ;
m_PreviewRenderer . Transparency ( f - > m_Settings - > Transparency ( ) ) ;
m_PreviewRenderer . ThreadCount ( std : : max ( 1u , Timing : : ProcessorCount ( ) - 1 ) ) ; //Leave one processor free so the GUI can breathe.
if ( auto top = m_Tree - > topLevelItem ( 0 ) )
{
size_t i = start ;
for ( auto b = Advance ( m_EmberFile . m_Embers . begin ( ) , start ) ; m_PreviewRun & & i < end & & b ! = m_EmberFile . m_Embers . end ( ) ; + + b , + + i )
{
m_PreviewEmber = * b ;
m_PreviewEmber . SyncSize ( ) ;
m_PreviewEmber . SetSizeAndAdjustScale ( PREVIEW_SIZE , PREVIEW_SIZE , false , eScaleType : : SCALE_WIDTH ) ;
m_PreviewEmber . m_TemporalSamples = 1 ;
m_PreviewEmber . m_Quality = 25 ;
m_PreviewEmber . m_Supersample = 1 ;
m_PreviewRenderer . SetEmber ( m_PreviewEmber ) ;
if ( m_PreviewRenderer . Run ( m_PreviewFinalImage ) = = eRenderStatus : : RENDER_OK )
{
if ( auto treeItem = dynamic_cast < EmberTreeWidgetItemBase * > ( top - > child ( int ( i ) ) ) )
{
//It is critical that Qt::BlockingQueuedConnection is passed because this is running on a different thread than the UI.
//This ensures the events are processed in order as each preview is updated, and that control does not return here
//until the update is complete.
QMetaObject : : invokeMethod ( f , " SetLibraryTreeItemData " , Qt : : BlockingQueuedConnection ,
Q_ARG ( EmberTreeWidgetItemBase * , treeItem ) ,
Q_ARG ( vector < byte > & , m_PreviewFinalImage ) ,
Q_ARG ( uint , PREVIEW_SIZE ) ,
Q_ARG ( uint , PREVIEW_SIZE ) ) ;
}
}
}
}
}
2014-12-11 00:50:15 -05:00
template class FractoriumEmberController < float > ;
2016-06-11 20:47:03 -04:00
template class PreviewRenderer < float > ;
template class TreePreviewRenderer < float > ;
2014-12-11 00:50:15 -05:00
# ifdef DO_DOUBLE
template class FractoriumEmberController < double > ;
2016-06-11 20:47:03 -04:00
template class PreviewRenderer < double > ;
template class TreePreviewRenderer < double > ;
2014-12-11 00:50:15 -05:00
# endif