mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-01-22 05:30:06 -05:00
90ec5b8246
-Show common folder locations such as documents, downloads, pictures in the sidebar in all file dialogs. -Warning message about exceeding memory in final render dialog now suggests strips as the solution to the problem. -Strips now has a tooltip explaining what it does. -Allow more digits in the spinners on the color section the flame tab. -Add manually adjustable size spinners in the final render dialog. Percentage scale and absolute size are fully synced. -Default prefix in final render is now the filename when doing animations (coming from sequence section of the library tab). -Changed the elliptic variation back to using a less precise version for float, and a more precise version for double. The last release had it always using double. -New applied xaos table that shows a read-only view of actual weights by taking the base xform weights and multiplying them by the xaos values. -New table in the xaos tab that gives a graphical representation of the probability that each xform is chosen, with and without xaos. -Add button to transpose the xaos rows and columns. -Add support for importing .chaos files from Chaotica. --Pasting back to Chaotica will work for most, but not all, variations due to incompatible parameter names in some. -Curves are now splines instead of Bezier. This adds compatibility with Chaotica, but breaks it for Apophysis. Xmls are still pastable, but the color curves will look different. --The curve editor on the palette tab can now add points by clicking on the lines and remove points by clicking on the points themselves, just like Chaotica. --Splines are saved in four new xml fields: overall_curve, red_curve, green_curve and blue_curve. -Allow for specifying the percentage of a sub batch each thread should iterate through per kernel call when running with OpenCL. This gives a roughly 1% performance increase due to having to make less kernel calls while iterating. --This field is present for interactive editing (where it's not very useful) and in the final render dialog. --On the command line, this is specified as --sbpctth for EmberRender and EmberAnimate. -Allow double clicking to toggle the supersample field in the flame tab between 1 and 2 for easily checking the effect of the field. -When showing affine values as polar coordinates, show angles normalized to 360 to match Chaotica. -Fuse Count spinner now toggles between 15 and 100 when double clicking for easily checking the effect of the field. -Added field for limiting the range in the x and y direction that the initial points are chosen from. -Added a field called K2 which is an alternative way to set brightness, ignored when zero. --This has no effect for many variations, but hs a noticeable effect for some. -Added new variations: arcsech arcsech2 arcsinh arctanh asteria block bwraps_rand circlecrop2 coth_spiral crackle2 depth_blur depth_blur2 depth_gaussian depth_gaussian2 depth_ngon depth_ngon2 depth_sine depth_sine2 dragonfire dspherical dust excinis exp2 flipx flowerdb foci_p gaussian glynnia2 glynnsim4 glynnsim5 henon henon hex_rand hex_truchet hypershift lazyjess lens lozi lozi modulusx modulusy oscilloscope2 point_symmetry pointsymmetry projective pulse rotate scry2 shift smartshape spher squares starblur2 swirl3 swirl3r tanh_spiral target0 target2 tile_hlp truchet_glyph truchet_inv truchet_knot unicorngaloshen vibration vibration2 --hex_truchet, hex_rand should always use double. They are extremely sensitive. --Bug fixes: -Bounds sign was flipped for x coordinate of world space when center was not zero. -Right clicking and dragging spinner showed menu on mouse up, even if it was very far away. -Text boxes for size in final render dialog were hard to type in. Same bug as xform weight used to be so fix the same way. -Fix spelling to be plural in toggle color speed box. -Stop using the blank user palette to generate flames. Either put colored palettes in it, or exclude it from randoms. -Clicking the random palette button for a palette file with only one palette in it would freeze the program. -Clicking none scale in final render did not re-render the preview. -Use less precision on random xaos. No need for 12 decimal places. -The term sub batch is overloaded in the options dialog. Change the naming and tooltip of those settings for cpu and opencl. --Also made clear in the tooltip for the default opencl quality setting that the value is per device. -The arrows spinner in palette editor appears like a read-only label. Made it look like a spinner. -Fix border colors for various spin boxes and table headers in the style sheet. Requires reload. -Fix a bug in the bwraps variation which would produce different results than Chaotica and Apophysis. -Synth was allowed to be selected for random flame generation when using an Nvidia card but it shouldn't have been because Nvidia has a hard time compiling synth. -A casting bug in the OpenCL kernels for log scaling and density filtering was preventing successful compilations on Intel iGPUs. Fixed even though we don't support anything other than AMD and Nvidia. -Palette rotation (click and drag) position was not being reset when loading a new flame. -When the xform circles were hidden, opening and closing the options dialog would improperly reshow them. -Double click toggle was broken on integer spin boxes. -Fixed tab order of some controls. -Creating a palette from a jpg in the palette editor only produced a single color. --Needed to package imageformats/qjpeg.dll with the Windows installer. -The basic memory benchmark test flame was not really testing memory. Make it more spread out. -Remove the temporal samples field from the flame tab, it was never used because it's only an animation parameter which is specified in the final render dialog or on the command line with EmberAnimate. --Code changes: -Add IsEmpty() to Palette to determine if a palette is all black. -Attempt to avoid selecting a blank palette in PaletteList::GetRandomPalette(). -Add function ScanForChaosNodes() and some associated helper functions in XmlToEmber. -Make variation param name correction be case insensitive in XmlToEmber. -Report error when assigning a variation param value in XmlToEmber. -Add SubBatchPercentPerThread() method to RendererCL. -Override enterEvent() and leaveEvent() in DoubleSpinBox and SpinBox to prevent the context menu from showing up on right mouse up after already leaving the spinner. -Filtering the mouse wheel event in TableWidget no longer appears to be needed. It was probably an old Qt bug that has been fixed. -Gui/ember syncing code in the final render dialog needed to be reworked to accommodate absolute sizes.
694 lines
30 KiB
C++
694 lines
30 KiB
C++
#pragma once
|
|
|
|
#include "EmberFile.h"
|
|
#include "DoubleSpinBox.h"
|
|
#include "GLEmberController.h"
|
|
|
|
/// <summary>
|
|
/// FractoriumEmberControllerBase and FractoriumEmberController<T> classes.
|
|
/// </summary>
|
|
|
|
/// <summary>
|
|
/// An enum representing the type of edit being done.
|
|
/// </summary>
|
|
enum class eEditUndoState : et { REGULAR_EDIT, UNDO_REDO, EDIT_UNDO };
|
|
|
|
/// <summary>
|
|
/// An enum representing which xforms an update should be applied to.
|
|
/// </summary>
|
|
enum class eXformUpdate : et { UPDATE_SPECIFIC, UPDATE_CURRENT, UPDATE_SELECTED, UPDATE_CURRENT_AND_SELECTED, UPDATE_SELECTED_EXCEPT_FINAL, UPDATE_ALL, UPDATE_ALL_EXCEPT_FINAL };
|
|
|
|
/// <summary>
|
|
/// An enum representing the type of synchronizing to do between the list of Embers kept in memory
|
|
/// and the widgets in the library tree.
|
|
/// </summary>
|
|
enum eLibraryUpdate { INDEX = 1, NAME = 2, POINTER = 4 };
|
|
|
|
/// <summary>
|
|
/// FractoriumEmberController and Fractorium need each other, but each can't include the other.
|
|
/// So Fractorium includes this file, and Fractorium is declared as a forward declaration here.
|
|
/// </summary>
|
|
class Fractorium;
|
|
template <typename T> class PreviewRenderer;
|
|
template <typename T> class TreePreviewRenderer;
|
|
|
|
#define PREVIEW_SIZE 256
|
|
#define UNDO_SIZE 128
|
|
|
|
/// <summary>
|
|
/// FractoriumEmberControllerBase serves as a non-templated base class with virtual
|
|
/// functions which will be overridden in a derived class that takes a template parameter.
|
|
/// The controller serves as a way to access both the Fractorium GUI and the underlying ember
|
|
/// objects through an interface that doesn't require template argument, but does allow
|
|
/// templated objects to be used underneath.
|
|
/// Note that there are a few functions which access a templated object, so for those both
|
|
/// versions for float and double must be provided, then overridden in the templated derived
|
|
/// class. It's definitely a design flaw, but C++ doesn't offer any alternative since
|
|
/// templated virtual functions are not supported.
|
|
/// The functions not implemented in this file can be found in the GUI files which use them.
|
|
/// </summary>
|
|
class FractoriumEmberControllerBase : public RenderCallback
|
|
{
|
|
friend Fractorium;
|
|
|
|
public:
|
|
FractoriumEmberControllerBase(Fractorium* fractorium);
|
|
FractoriumEmberControllerBase(const FractoriumEmberControllerBase& controller) = delete;
|
|
virtual ~FractoriumEmberControllerBase();
|
|
|
|
//Embers.
|
|
virtual void SetEmber(const Ember<float>& ember, bool verbatim, bool updatePointer) { }
|
|
virtual void CopyEmber(Ember<float>& ember, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) { }//Uncomment default lambdas once LLVM fixes a crash in their compiler with default lambda parameters.//TODO
|
|
virtual void SetEmberFile(const EmberFile<float>& emberFile, bool move) { }
|
|
virtual void CopyEmberFile(EmberFile<float>& emberFile, bool sequence, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) { }
|
|
virtual void SetTempPalette(const Palette<float>& palette) { }
|
|
virtual void CopyTempPalette(Palette<float>& palette) { }
|
|
#ifdef DO_DOUBLE
|
|
virtual void SetEmber(const Ember<double>& ember, bool verbatim, bool updatePointer) { }
|
|
virtual void CopyEmber(Ember<double>& ember, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) { }
|
|
virtual void SetEmberFile(const EmberFile<double>& emberFile, bool move) { }
|
|
virtual void CopyEmberFile(EmberFile<double>& emberFile, bool sequence, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) { }
|
|
virtual void SetTempPalette(const Palette<double>& palette) { }
|
|
virtual void CopyTempPalette(Palette<double>& palette) { }
|
|
#endif
|
|
virtual void SetEmber(size_t index, bool verbatim) { }
|
|
virtual void AddXform() { }
|
|
virtual void AddLinkedXform() { }
|
|
virtual void DuplicateXform() { }
|
|
virtual void ClearXform() { }
|
|
virtual void DeleteXforms() { }
|
|
virtual void AddFinalXform() { }
|
|
virtual bool UseFinalXform() { return false; }
|
|
virtual size_t XformCount() const { return 0; }
|
|
virtual size_t TotalXformCount() const { return 0; }
|
|
virtual QString Name() const { return ""; }
|
|
virtual void Name(const string& s) { }
|
|
virtual size_t FinalRasW() const { return 0; }
|
|
virtual void FinalRasW(size_t w) { }
|
|
virtual size_t FinalRasH() const { return 0; }
|
|
virtual void FinalRasH(size_t h) { }
|
|
virtual size_t Index() const { return 0; }
|
|
virtual void AddSymmetry(int sym, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) { }
|
|
virtual void CalcNormalizedWeights() { }
|
|
|
|
//Menu.
|
|
virtual void NewFlock(size_t count) { }//File.
|
|
virtual void NewEmptyFlameInCurrentFile() { }
|
|
virtual void NewRandomFlameInCurrentFile() { }
|
|
virtual void CopyFlameInCurrentFile() { }
|
|
virtual void OpenAndPrepFiles(const QStringList& filenames, bool append) { }
|
|
virtual void SaveCurrentAsXml() { }
|
|
virtual void SaveEntireFileAsXml() { }
|
|
virtual uint SaveCurrentToOpenedFile(bool render = true) { return 0; }
|
|
virtual void SaveCurrentFileOnShutdown() { }
|
|
virtual void Undo() { }//Edit.
|
|
virtual void Redo() { }
|
|
virtual void CopyXml() { }
|
|
virtual void CopyAllXml() { }
|
|
virtual void PasteXmlAppend() { }
|
|
virtual void PasteXmlOver() { }
|
|
virtual void CopySelectedXforms() { }
|
|
virtual void PasteSelectedXforms() { }
|
|
virtual void CopyKernel() { }
|
|
virtual void AddReflectiveSymmetry() { }//Tools.
|
|
virtual void AddRotationalSymmetry() { }
|
|
virtual void AddBothSymmetry() { }
|
|
virtual void Flatten() { }
|
|
virtual void Unflatten() { }
|
|
virtual void ClearFlame() { }
|
|
|
|
//Toolbar.
|
|
|
|
//Library.
|
|
virtual void SyncLibrary(eLibraryUpdate update) { }
|
|
virtual void FillLibraryTree(int selectIndex = -1) { }
|
|
virtual void UpdateLibraryTree() { }
|
|
virtual void EmberTreeItemChanged(QTreeWidgetItem* item, int col) { }
|
|
virtual void EmberTreeItemDoubleClicked(QTreeWidgetItem* item, int col) { }
|
|
virtual void RenderLibraryPreviews(uint start = UINT_MAX, uint end = UINT_MAX) { }
|
|
virtual void RenderSequencePreviews(uint start = UINT_MAX, uint end = UINT_MAX) { }
|
|
virtual void SequenceTreeItemChanged(QTreeWidgetItem* item, int col) { }
|
|
virtual void StopLibraryPreviewRender() { }
|
|
virtual void StopSequencePreviewRender() { }
|
|
virtual void StopAllPreviewRenderers() { }
|
|
virtual void MoveLibraryItems(const QModelIndexList& items, int destRow) { }
|
|
virtual void Delete(const vector<pair<size_t, QTreeWidgetItem*>>& v) { }
|
|
virtual void FillSequenceTree() { }
|
|
virtual void SequenceGenerateButtonClicked() { }
|
|
virtual void SequenceSaveButtonClicked() { }
|
|
virtual void SequenceOpenButtonClicked() { }
|
|
|
|
//Params.
|
|
virtual void SetCenter(double x, double y) { }
|
|
virtual void FillParamTablesAndPalette() { }
|
|
virtual void BrightnessChanged(double d) { }
|
|
virtual void GammaChanged(double d) { }
|
|
virtual void GammaThresholdChanged(double d) { }
|
|
virtual void VibrancyChanged(double d) { }
|
|
virtual void HighlightPowerChanged(double d) { }
|
|
virtual void K2Changed(double d) { }
|
|
virtual void PaletteModeChanged(uint i) { }
|
|
virtual void WidthChanged(uint i) { }
|
|
virtual void HeightChanged(uint i) { }
|
|
virtual void ResizeAndScale(int width, int height, eScaleType scaleType) { }
|
|
virtual void CenterXChanged(double d) { }
|
|
virtual void CenterYChanged(double d) { }
|
|
virtual void ScaleChanged(double d) { }
|
|
virtual void ZoomChanged(double d) { }
|
|
virtual void RotateChanged(double d) { }
|
|
virtual void ZPosChanged(double d) { }
|
|
virtual void PerspectiveChanged(double d) { }
|
|
virtual void PitchChanged(double d) { }
|
|
virtual void YawChanged(double d) { }
|
|
virtual void DepthBlurChanged(double d) { }
|
|
virtual void SpatialFilterWidthChanged(double d) { }
|
|
virtual void SpatialFilterTypeChanged(const QString& text) { }
|
|
virtual void TemporalFilterWidthChanged(double d) { }
|
|
virtual void TemporalFilterTypeChanged(const QString& text) { }
|
|
virtual void DEFilterMinRadiusWidthChanged(double d) { }
|
|
virtual void DEFilterMaxRadiusWidthChanged(double d) { }
|
|
virtual void DEFilterCurveWidthChanged(double d) { }
|
|
virtual void SbsChanged(int d) { }
|
|
virtual void FuseChanged(int d) { }
|
|
virtual void RandRangeChanged(double d) { }
|
|
virtual void QualityChanged(double d) { }
|
|
virtual void SupersampleChanged(int d) { }
|
|
virtual void AffineInterpTypeChanged(int i) { }
|
|
virtual void InterpTypeChanged(int i) { }
|
|
virtual void BackgroundChanged(const QColor& color) { }
|
|
virtual void ClearColorCurves(int i) { }
|
|
virtual void ColorCurveChanged(int curveIndex, int pointInxed, const QPointF& point) { }
|
|
virtual void ColorCurvesPointAdded(size_t curveIndex, const QPointF& point) { }
|
|
virtual void ColorCurvesPointRemoved(size_t curveIndex, int pointIndex) { }
|
|
|
|
//Xforms.
|
|
virtual void CurrentXformComboChanged(int index) { }
|
|
virtual void XformWeightChanged(double d) { }
|
|
virtual void EqualizeWeights() { }
|
|
virtual void XformNameChanged(int row, int col) { }
|
|
virtual void XformAnimateChanged(int state) { }
|
|
virtual void FillXforms(int index = 0) { }
|
|
virtual void UpdateXformName(int index) { }
|
|
|
|
//Xforms Affine.
|
|
virtual void AffineSetHelper(double d, int index, bool pre) { }
|
|
virtual void FlipXforms(bool horizontal, bool vertical, bool pre) { }
|
|
virtual void RotateXformsByAngle(double angle, bool pre) { }
|
|
virtual void MoveXforms(double x, double y, bool pre) { }
|
|
virtual void ScaleXforms(double scale, bool pre) { }
|
|
virtual void ResetXformsAffine(bool pre) { }
|
|
virtual void CopyXformsAffine(bool pre) { }
|
|
virtual void PasteXformsAffine(bool pre) { }
|
|
virtual void RandomXformsAffine(bool pre) { }
|
|
virtual void FillBothAffines() { }
|
|
virtual void SwapAffines() { }
|
|
double LockedScale() { return m_LockedScale; }
|
|
double LockedX() { return m_LockedX; }
|
|
double LockedY() { return m_LockedY; }
|
|
void LockedScale(double scale) { m_LockedScale = scale; }
|
|
virtual void InitLockedScale() { }
|
|
|
|
//Xforms Color.
|
|
virtual void XformColorIndexChanged(double d, bool updateRender, bool updateSpinner, bool updateScroll, eXformUpdate update = eXformUpdate::UPDATE_SELECTED, size_t index = 0) { }
|
|
virtual void RandomColorIndicesButtonClicked() { }
|
|
virtual void ToggleColorIndicesButtonClicked() { }
|
|
virtual void RandomColorSpeedButtonClicked() { }
|
|
virtual void ToggleColorSpeedsButtonClicked() { }
|
|
virtual void XformColorSpeedChanged(double d) { }
|
|
virtual void XformOpacityChanged(double d) { }
|
|
virtual void XformDirectColorChanged(double d) { }
|
|
virtual void SoloXformCheckBoxStateChanged(int state, int index) { }
|
|
virtual QColor ColorIndexToQColor(double d) { return QColor(); }
|
|
|
|
//Xforms Variations.
|
|
virtual void Filter(const QString& text) { }
|
|
virtual void SetupVariationsTree() { }
|
|
virtual void ClearVariationsTree() { }
|
|
virtual void VariationSpinBoxValueChanged(double d) { }
|
|
virtual void FilteredVariations() { }
|
|
virtual void FillVariationTreeWithCurrentXform() { }
|
|
|
|
//Xforms Selection.
|
|
virtual QString MakeXformCaption(size_t i) { return ""; }
|
|
|
|
//Xaos.
|
|
virtual void FillXaos() { }
|
|
virtual void FillAppliedXaos() { }
|
|
virtual void XaosChanged(int x, int y, double val) { }
|
|
virtual void ClearXaos() { }
|
|
virtual void RandomXaos() { }
|
|
virtual void AddLayer(int xforms) { }
|
|
virtual void TransposeXaos() { }
|
|
|
|
//Palette.
|
|
virtual size_t InitPaletteList(const QString& s) { return 0; }
|
|
virtual bool FillPaletteTable(const string& s) { return false; }
|
|
virtual void ApplyPaletteToEmber() { }
|
|
virtual void PaletteAdjust() { }
|
|
virtual void PaletteCellClicked(int row, int col) { }
|
|
virtual void SetBasePaletteAndAdjust(const Palette<float>& palette) { }
|
|
virtual void PaletteEditorButtonClicked() { }
|
|
QImage& FinalPaletteImage() { return m_FinalPaletteImage; }
|
|
|
|
//Info.
|
|
virtual void FillSummary() { }
|
|
|
|
//Rendering/progress.
|
|
virtual bool Render() { return false; }
|
|
virtual bool CreateRenderer(eRendererType renderType, const vector<pair<size_t, size_t>>& devices, bool updatePreviews, bool shared = true) { return false; }
|
|
virtual uint SizeOfT() const { return 0; }
|
|
virtual void ClearUndo() { }
|
|
virtual void DeleteRenderer() { }
|
|
virtual GLEmberControllerBase* GLController() { return nullptr; }
|
|
virtual void Pause(bool pause);
|
|
virtual bool Paused();
|
|
bool RenderTimerRunning();
|
|
void StartRenderTimer();
|
|
void DelayedStartRenderTimer();
|
|
void StopRenderTimer(bool wait);
|
|
void ClearFinalImages();
|
|
void Shutdown();
|
|
void UpdateRender(eProcessAction action = eProcessAction::FULL_RENDER);
|
|
void SaveCurrentRender(const QString& filename, const EmberImageComments& comments, vector<v4F>& pixels, size_t width, size_t height, bool png16Bit, bool transparency);
|
|
RendererBase* Renderer() { return m_Renderer.get(); }
|
|
vector<v4F>* FinalImage() { return &(m_FinalImage); }
|
|
vector<v4F>* PreviewFinalImage() { return &m_PreviewFinalImage; }
|
|
EmberStats Stats() { return m_Stats; }
|
|
eProcessState ProcessState() { return m_Renderer.get() ? m_Renderer->ProcessState() : eProcessState::NONE; }
|
|
|
|
protected:
|
|
//Rendering/progress.
|
|
void AddProcessAction(eProcessAction action);
|
|
eProcessAction CondenseAndClearProcessActions();
|
|
|
|
//Non-templated members.
|
|
bool m_Rendering = false;
|
|
bool m_LastEditWasUndoRedo;
|
|
vector<pair<size_t, size_t>> m_Devices;
|
|
size_t m_SubBatchCount = 1;//Will be ovewritten by the options on first render.
|
|
uint m_FailedRenders = 0;
|
|
size_t m_UndoIndex = 0;
|
|
double m_LockedScale = 1;
|
|
double m_LockedX = 0;
|
|
double m_LockedY = 0;
|
|
eRendererType m_RenderType = eRendererType::CPU_RENDERER;
|
|
eEditUndoState m_EditState;
|
|
GLuint m_OutputTexID = 0;
|
|
Timing m_RenderElapsedTimer;
|
|
EmberStats m_Stats;
|
|
QImage m_FinalPaletteImage;
|
|
QString m_LastSaveAll;
|
|
QString m_LastSaveCurrent;
|
|
string m_CurrentPaletteFilePath;
|
|
std::recursive_mutex m_Cs;
|
|
std::thread m_WriteThread;
|
|
vector<v4F> m_FinalImage;
|
|
vector<v4F> m_PreviewFinalImage;
|
|
vector<eProcessAction> m_ProcessActions;
|
|
vector<eVariationId> m_FilteredVariations;
|
|
unique_ptr<EmberNs::RendererBase> m_Renderer;
|
|
QTIsaac<ISAAC_SIZE, ISAAC_INT> m_Rand;
|
|
Fractorium* m_Fractorium;
|
|
Palette<float> m_TempPalette;
|
|
std::unique_ptr<QTimer> m_RenderTimer;
|
|
std::unique_ptr<QTimer> m_RenderRestartTimer;
|
|
shared_ptr<PaletteList<float>> m_PaletteList;
|
|
shared_ptr<OpenCLInfo> m_Info = OpenCLInfo::Instance();
|
|
};
|
|
|
|
/// <summary>
|
|
/// Templated derived class which implements all interaction functionality between the embers
|
|
/// of a specific template type and the GUI.
|
|
/// Switching between template arguments requires complete re-creation of the controller and the
|
|
/// underlying renderer. Switching between CPU and OpenCL only requires re-creation of the renderer.
|
|
/// </summary>
|
|
template<typename T>
|
|
class FractoriumEmberController : public FractoriumEmberControllerBase
|
|
{
|
|
friend PreviewRenderer<T>;
|
|
friend TreePreviewRenderer<T>;
|
|
|
|
public:
|
|
FractoriumEmberController(Fractorium* fractorium);
|
|
FractoriumEmberController(const FractoriumEmberController<T>& controller) = delete;
|
|
virtual ~FractoriumEmberController();
|
|
|
|
//Embers.
|
|
virtual void SetEmber(const Ember<float>& ember, bool verbatim, bool updatePointer) override;
|
|
virtual void CopyEmber(Ember<float>& ember, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) override;
|
|
virtual void SetEmberFile(const EmberFile<float>& emberFile, bool move) override;
|
|
virtual void CopyEmberFile(EmberFile<float>& emberFile, bool sequence, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) override;
|
|
virtual void SetTempPalette(const Palette<float>& palette) override;
|
|
virtual void CopyTempPalette(Palette<float>& palette) override;
|
|
#ifdef DO_DOUBLE
|
|
virtual void SetEmber(const Ember<double>& ember, bool verbatim, bool updatePointer) override;
|
|
virtual void CopyEmber(Ember<double>& ember, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) override;
|
|
virtual void SetEmberFile(const EmberFile<double>& emberFile, bool move) override;
|
|
virtual void CopyEmberFile(EmberFile<double>& emberFile, bool sequence, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) override;
|
|
virtual void SetTempPalette(const Palette<double>& palette) override;
|
|
virtual void CopyTempPalette(Palette<double>& palette) override;
|
|
#endif
|
|
virtual void SetEmber(size_t index, bool verbatim) override;
|
|
virtual void AddXform() override;
|
|
virtual void AddLinkedXform() override;
|
|
virtual void DuplicateXform() override;
|
|
virtual void ClearXform() override;
|
|
virtual void DeleteXforms() override;
|
|
virtual void AddFinalXform() override;
|
|
virtual bool UseFinalXform() override { return m_Ember.UseFinalXform(); }
|
|
virtual size_t XformCount() const override { return m_Ember.XformCount(); }
|
|
virtual size_t TotalXformCount() const override { return m_Ember.TotalXformCount(); }
|
|
virtual QString Name() const override { return QString::fromStdString(m_Ember.m_Name); }
|
|
virtual void Name(const string& s) override { m_Ember.m_Name = s; }
|
|
virtual size_t FinalRasW() const override { return m_Ember.m_FinalRasW; }
|
|
virtual void FinalRasW(size_t w) override { m_Ember.m_FinalRasW = w; }
|
|
virtual size_t FinalRasH() const override { return m_Ember.m_FinalRasH; }
|
|
virtual void FinalRasH(size_t h) override { m_Ember.m_FinalRasH = h; }
|
|
virtual size_t Index() const override { return m_Ember.m_Index; }
|
|
virtual void AddSymmetry(int sym, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override { m_Ember.AddSymmetry(sym, rand); }
|
|
virtual void CalcNormalizedWeights() override { m_Ember.CalcNormalizedWeights(m_NormalizedWeights); }
|
|
void ConstrainDimensions(Ember<T>& ember);
|
|
Ember<T>* CurrentEmber();
|
|
|
|
//Menu.
|
|
virtual void NewFlock(size_t count) override;
|
|
virtual void NewEmptyFlameInCurrentFile() override;
|
|
virtual void NewRandomFlameInCurrentFile() override;
|
|
virtual void CopyFlameInCurrentFile() override;
|
|
virtual void OpenAndPrepFiles(const QStringList& filenames, bool append) override;
|
|
virtual void SaveCurrentAsXml() override;
|
|
virtual void SaveEntireFileAsXml() override;
|
|
virtual uint SaveCurrentToOpenedFile(bool render = true) override;
|
|
virtual void SaveCurrentFileOnShutdown() override;
|
|
virtual void Undo() override;
|
|
virtual void Redo() override;
|
|
virtual void CopyXml() override;
|
|
virtual void CopyAllXml() override;
|
|
virtual void PasteXmlAppend() override;
|
|
virtual void PasteXmlOver() override;
|
|
virtual void CopySelectedXforms() override;
|
|
virtual void PasteSelectedXforms() override;
|
|
virtual void CopyKernel() override;
|
|
virtual void AddReflectiveSymmetry() override;
|
|
virtual void AddRotationalSymmetry() override;
|
|
virtual void AddBothSymmetry() override;
|
|
virtual void Flatten() override;
|
|
virtual void Unflatten() override;
|
|
virtual void ClearFlame() override;
|
|
|
|
//Toolbar.
|
|
|
|
//Library.
|
|
virtual void SyncLibrary(eLibraryUpdate update) override;
|
|
virtual void FillLibraryTree(int selectIndex = -1) override;
|
|
virtual void UpdateLibraryTree() override;
|
|
virtual void MoveLibraryItems(const QModelIndexList& items, int destRow) override;
|
|
virtual void Delete(const vector<pair<size_t, QTreeWidgetItem*>>& v) override;
|
|
virtual void EmberTreeItemChanged(QTreeWidgetItem* item, int col) override;
|
|
virtual void EmberTreeItemDoubleClicked(QTreeWidgetItem* item, int col) override;
|
|
void RenderPreviews(QTreeWidget* tree, TreePreviewRenderer<T>* renderer, EmberFile<T>& file, uint start = UINT_MAX, uint end = UINT_MAX);
|
|
virtual void RenderLibraryPreviews(uint start = UINT_MAX, uint end = UINT_MAX) override;
|
|
virtual void RenderSequencePreviews(uint start = UINT_MAX, uint end = UINT_MAX) override;
|
|
virtual void SequenceTreeItemChanged(QTreeWidgetItem* item, int col) override;
|
|
virtual void StopLibraryPreviewRender() override;
|
|
virtual void StopSequencePreviewRender() override;
|
|
virtual void StopAllPreviewRenderers() override;
|
|
virtual void FillSequenceTree() override;
|
|
virtual void SequenceGenerateButtonClicked() override;
|
|
virtual void SequenceSaveButtonClicked() override;
|
|
virtual void SequenceOpenButtonClicked() override;
|
|
|
|
//Params.
|
|
virtual void SetCenter(double x, double y) override;
|
|
virtual void FillParamTablesAndPalette() override;
|
|
virtual void BrightnessChanged(double d) override;
|
|
virtual void GammaChanged(double d) override;
|
|
virtual void GammaThresholdChanged(double d) override;
|
|
virtual void VibrancyChanged(double d) override;
|
|
virtual void HighlightPowerChanged(double d) override;
|
|
virtual void K2Changed(double d) override;
|
|
virtual void PaletteModeChanged(uint i) override;
|
|
virtual void WidthChanged(uint i) override;
|
|
virtual void HeightChanged(uint i) override;
|
|
virtual void ResizeAndScale(int width, int height, eScaleType scaleType) override;
|
|
virtual void CenterXChanged(double d) override;
|
|
virtual void CenterYChanged(double d) override;
|
|
virtual void ScaleChanged(double d) override;
|
|
virtual void ZoomChanged(double d) override;
|
|
virtual void RotateChanged(double d) override;
|
|
virtual void ZPosChanged(double d) override;
|
|
virtual void PerspectiveChanged(double d) override;
|
|
virtual void PitchChanged(double d) override;
|
|
virtual void YawChanged(double d) override;
|
|
virtual void DepthBlurChanged(double d) override;
|
|
virtual void SpatialFilterWidthChanged(double d) override;
|
|
virtual void SpatialFilterTypeChanged(const QString& text) override;
|
|
virtual void TemporalFilterWidthChanged(double d) override;
|
|
virtual void TemporalFilterTypeChanged(const QString& text) override;
|
|
virtual void DEFilterMinRadiusWidthChanged(double d) override;
|
|
virtual void DEFilterMaxRadiusWidthChanged(double d) override;
|
|
virtual void DEFilterCurveWidthChanged(double d) override;
|
|
virtual void SbsChanged(int d) override;
|
|
virtual void FuseChanged(int d) override;
|
|
virtual void RandRangeChanged(double d) override;
|
|
virtual void QualityChanged(double d) override;
|
|
virtual void SupersampleChanged(int d) override;
|
|
virtual void AffineInterpTypeChanged(int index) override;
|
|
virtual void InterpTypeChanged(int index) override;
|
|
virtual void BackgroundChanged(const QColor& col) override;
|
|
virtual void ClearColorCurves(int i) override;
|
|
virtual void ColorCurveChanged(int curveIndex, int pointInxed, const QPointF& point) override;
|
|
virtual void ColorCurvesPointAdded(size_t curveIndex, const QPointF& point) override;
|
|
virtual void ColorCurvesPointRemoved(size_t curveIndex, int pointIndex) override;
|
|
|
|
//Xforms.
|
|
virtual void CurrentXformComboChanged(int index) override;
|
|
virtual void XformWeightChanged(double d) override;
|
|
virtual void EqualizeWeights() override;
|
|
virtual void XformNameChanged(int row, int col) override;
|
|
virtual void XformAnimateChanged(int state) override;
|
|
virtual void FillXforms(int index = 0) override;
|
|
virtual void UpdateXformName(int index) override;
|
|
void FillWithXform(Xform<T>* xform);
|
|
Xform<T>* CurrentXform();
|
|
void UpdateXform(std::function<void(Xform<T>*, size_t, size_t)> func, eXformUpdate updateType = eXformUpdate::UPDATE_CURRENT, bool updateRender = true, eProcessAction action = eProcessAction::FULL_RENDER, size_t index = 0);
|
|
|
|
//Xforms Affine.
|
|
virtual void AffineSetHelper(double d, int index, bool pre) override;
|
|
virtual void FlipXforms(bool horizontal, bool vertical, bool pre) override;
|
|
virtual void RotateXformsByAngle(double angle, bool pre) override;
|
|
virtual void MoveXforms(double x, double y, bool pre) override;
|
|
virtual void ScaleXforms(double scale, bool pre) override;
|
|
virtual void ResetXformsAffine(bool pre) override;
|
|
virtual void CopyXformsAffine(bool pre) override;
|
|
virtual void PasteXformsAffine(bool pre) override;
|
|
virtual void RandomXformsAffine(bool pre) override;
|
|
virtual void FillBothAffines() override;
|
|
virtual void SwapAffines() override;
|
|
virtual void InitLockedScale() override;
|
|
void FillAffineWithXform(Xform<T>* xform, bool pre);
|
|
void ChangeLockedScale(T value);
|
|
T AffineScaleCurrentToLocked();
|
|
T AffineScaleLockedToCurrent();
|
|
|
|
//Xforms Color.
|
|
virtual void XformColorIndexChanged(double d, bool updateRender, bool updateSpinner, bool updateScroll, eXformUpdate update = eXformUpdate::UPDATE_SELECTED, size_t index = 0) override;
|
|
virtual void RandomColorIndicesButtonClicked() override;
|
|
virtual void ToggleColorIndicesButtonClicked() override;
|
|
virtual void RandomColorSpeedButtonClicked() override;
|
|
virtual void ToggleColorSpeedsButtonClicked() override;
|
|
virtual void XformColorSpeedChanged(double d) override;
|
|
virtual void XformOpacityChanged(double d) override;
|
|
virtual void XformDirectColorChanged(double d) override;
|
|
virtual void SoloXformCheckBoxStateChanged(int state, int index) override;
|
|
virtual QColor ColorIndexToQColor(double d) override;
|
|
void FillColorWithXform(Xform<T>* xform);
|
|
|
|
//Xforms Variations.
|
|
virtual void Filter(const QString& text) override;
|
|
virtual void SetupVariationsTree() override;
|
|
virtual void ClearVariationsTree() override;
|
|
virtual void VariationSpinBoxValueChanged(double d) override;
|
|
virtual void FilteredVariations() override;
|
|
virtual void FillVariationTreeWithCurrentXform() override;
|
|
void FillVariationTreeWithXform(Xform<T>* xform);
|
|
|
|
//Xforms Xaos.
|
|
virtual void FillXaos() override;
|
|
virtual void FillAppliedXaos() override;
|
|
virtual void XaosChanged(int x, int y, double val) override;
|
|
virtual void ClearXaos() override;
|
|
virtual void RandomXaos() override;
|
|
virtual void AddLayer(int xforms) override;
|
|
virtual void TransposeXaos() override;
|
|
|
|
//Xforms Selection.
|
|
virtual QString MakeXformCaption(size_t i) override;
|
|
bool XformCheckboxAt(int i, std::function<void(QCheckBox*)> func);
|
|
bool XformCheckboxAt(Xform<T>* xform, std::function<void(QCheckBox*)> func);
|
|
|
|
//Palette.
|
|
virtual size_t InitPaletteList(const QString& s) override;
|
|
virtual bool FillPaletteTable(const string& s) override;
|
|
virtual void ApplyPaletteToEmber() override;
|
|
virtual void PaletteAdjust() override;
|
|
virtual void PaletteCellClicked(int row, int col) override;
|
|
virtual void SetBasePaletteAndAdjust(const Palette<float>& palette) override;
|
|
virtual void PaletteEditorButtonClicked() override;
|
|
|
|
//Info.
|
|
virtual void FillSummary() override;
|
|
|
|
//Rendering/progress.
|
|
virtual bool Render() override;
|
|
virtual bool CreateRenderer(eRendererType renderType, const vector<pair<size_t, size_t>>& devices, bool updatePreviews, bool shared = true) override;
|
|
virtual uint SizeOfT() const override { return sizeof(T); }
|
|
virtual int ProgressFunc(Ember<T>& ember, void* foo, double fraction, int stage, double etaMs) override;
|
|
virtual void ClearUndo() override;
|
|
virtual GLEmberControllerBase* GLController() override { return m_GLController.get(); }
|
|
virtual void DeleteRenderer() override;
|
|
|
|
private:
|
|
//Embers.
|
|
void ApplyXmlSavingTemplate(Ember<T>& ember);
|
|
template <typename U> void SetEmberPrivate(const Ember<U>& ember, bool verbatim, bool updatePointer);
|
|
|
|
//Params.
|
|
void ParamsToEmber(Ember<T>& ember);
|
|
|
|
//Xforms.
|
|
void SetNormalizedWeightText(Xform<T>* xform);
|
|
bool IsFinal(Xform<T>* xform);
|
|
|
|
//Xforms Color.
|
|
void FillCurvesControl();
|
|
|
|
//Palette.
|
|
void UpdateAdjustedPaletteGUI(Palette<float>& palette);
|
|
|
|
//Rendering/progress.
|
|
void Update(std::function<void (void)> func, bool updateRender = true, eProcessAction action = eProcessAction::FULL_RENDER);
|
|
void UpdateAll(std::function<void (Ember<T>&, bool)> func, bool updateRender = true, eProcessAction action = eProcessAction::FULL_RENDER, bool applyAll = false);
|
|
bool SyncSizes();
|
|
|
|
//Templated members.
|
|
bool m_PreviewRunning = false;
|
|
vector<T> m_TempOpacities;
|
|
vector<T> m_NormalizedWeights;
|
|
Ember<T> m_Ember;
|
|
Ember<T>* m_EmberFilePointer = nullptr;
|
|
EmberFile<T> m_EmberFile;
|
|
EmberFile<T> m_SequenceFile;
|
|
deque<Ember<T>> m_UndoList;
|
|
vector<Xform<T>> m_CopiedXforms;
|
|
Xform<T> m_CopiedFinalXform;
|
|
Affine2D<T> m_CopiedAffine;
|
|
shared_ptr<VariationList<T>> m_VariationList;
|
|
unique_ptr<SheepTools<T, float>> m_SheepTools;
|
|
unique_ptr<GLEmberController<T>> m_GLController;
|
|
unique_ptr<TreePreviewRenderer<T>> m_LibraryPreviewRenderer;
|
|
unique_ptr<TreePreviewRenderer<T>> m_SequencePreviewRenderer;
|
|
};
|
|
|
|
/// <summary>
|
|
/// Base class for encapsulating a preview renderer which will be used
|
|
/// in such places as the main library tree, the sequence tree and the
|
|
/// single preview thumbnail shown in the final render dialog.
|
|
/// Derived classes will implement PreviewRenderFunc() to handle the rendering
|
|
/// functionality specific to their previews.
|
|
/// </summary>
|
|
template <typename T>
|
|
class PreviewRenderer
|
|
{
|
|
public:
|
|
PreviewRenderer()
|
|
{
|
|
}
|
|
|
|
void Render(uint start, uint end)
|
|
{
|
|
Stop();
|
|
m_PreviewResult = QtConcurrent::run([&](uint s, uint e)
|
|
{
|
|
rlg l(m_PreviewCs);
|
|
m_PreviewRun = true;
|
|
PreviewRenderFunc(s, e);
|
|
m_PreviewRun = false;
|
|
}, start, end);
|
|
}
|
|
|
|
void Stop()
|
|
{
|
|
m_PreviewRun = false;
|
|
m_PreviewRenderer.Abort();
|
|
m_PreviewResult.cancel();
|
|
m_PreviewResult.waitForFinished();
|
|
}
|
|
|
|
bool EarlyClip()
|
|
{
|
|
return m_PreviewRenderer.EarlyClip();
|
|
}
|
|
|
|
bool YAxisUp()
|
|
{
|
|
return m_PreviewRenderer.YAxisUp();
|
|
}
|
|
|
|
bool Running()
|
|
{
|
|
return m_PreviewRun || m_PreviewResult.isRunning();
|
|
}
|
|
|
|
virtual void PreviewRenderFunc(uint start, uint end) {}
|
|
|
|
protected:
|
|
volatile bool m_PreviewRun = false;
|
|
Ember<T> m_PreviewEmber;
|
|
vector<byte> m_PreviewVec;
|
|
vv4F m_PreviewFinalImage;
|
|
EmberNs::Renderer<T, float> m_PreviewRenderer;
|
|
|
|
private:
|
|
QFuture<void> m_PreviewResult;
|
|
std::recursive_mutex m_PreviewCs;
|
|
};
|
|
|
|
/// <summary>
|
|
/// Thin derivation to handle preview rendering multiple embers previews to a tree.
|
|
/// </summary>
|
|
template <typename T>
|
|
class TreePreviewRenderer : public PreviewRenderer<T>
|
|
{
|
|
public:
|
|
using PreviewRenderer<T>::m_PreviewRun;
|
|
using PreviewRenderer<T>::m_PreviewEmber;
|
|
using PreviewRenderer<T>::m_PreviewVec;
|
|
using PreviewRenderer<T>::m_PreviewRenderer;
|
|
using PreviewRenderer<T>::m_PreviewFinalImage;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="TreePreviewRenderer{T}"/> class.
|
|
/// </summary>
|
|
/// <param name="controller">A pointer to the controller this instance is a member of</param>
|
|
/// <param name="tree">A pointer to the tree to render to</param>
|
|
/// <param name="emberFile">A reference to the ember file to render</param>
|
|
TreePreviewRenderer(FractoriumEmberController<T>* controller, QTreeWidget* tree, EmberFile<T>& emberFile) :
|
|
m_Controller(controller),
|
|
m_Tree(tree),
|
|
m_EmberFile(emberFile)
|
|
{
|
|
auto f = m_Controller->m_Fractorium;
|
|
m_PreviewRenderer.Callback(nullptr);
|
|
m_PreviewRenderer.EarlyClip(f->m_Settings->EarlyClip());
|
|
m_PreviewRenderer.YAxisUp(f->m_Settings->YAxisUp());
|
|
}
|
|
|
|
virtual void PreviewRenderFunc(uint start, uint end) override;
|
|
|
|
protected:
|
|
FractoriumEmberController<T>* m_Controller;
|
|
QTreeWidget* m_Tree;
|
|
EmberFile<T>& m_EmberFile;
|
|
};
|