From ba1e5ed922f3bdc35c82c15fbb84f1ec17da5a07 Mon Sep 17 00:00:00 2001 From: Person Date: Sat, 4 Jan 2020 01:02:30 -0800 Subject: [PATCH] --Code changes -Fix up Miche's work on allowing a small subset of parameters to be copied from the main window to the final render dialog when doing save/render again. --- Source/Fractorium/CurvesGraphicsView.cpp | 12 +-- Source/Fractorium/FinalRenderDialog.cpp | 14 +-- Source/Fractorium/FinalRenderDialog.ui | 6 ++ .../Fractorium/FinalRenderEmberController.cpp | 64 +++++++++++--- Source/Fractorium/FractoriumEmberController.h | 10 +-- Source/Fractorium/FractoriumParams.cpp | 88 +++++++++---------- 6 files changed, 120 insertions(+), 74 deletions(-) diff --git a/Source/Fractorium/CurvesGraphicsView.cpp b/Source/Fractorium/CurvesGraphicsView.cpp index 091bd03..ef04912 100644 --- a/Source/Fractorium/CurvesGraphicsView.cpp +++ b/Source/Fractorium/CurvesGraphicsView.cpp @@ -218,17 +218,17 @@ void CurvesGraphicsView::paintEvent(QPaintEvent* e) void CurvesGraphicsView::mousePressEvent(QMouseEvent* e) { QGraphicsView::mousePressEvent(e); - auto thresh = devicePixelRatioF() * 4; - auto findpoint = [&](int x, int y, bool incThresh = false) -> int + auto thresh = devicePixelRatioF() * 4; + auto findpoint = [&](int x, int y, double thresh) -> int { for (int i = 0; i < m_Points[m_Index].size(); i++) { auto item = m_Points[m_Index][i]; auto xdist = std::abs(item->pos().x() - x); auto ydist = std::abs(item->pos().y() - y); - auto threshAgain = incThresh ? thresh * 2 : thresh; + auto threshAgain = thresh; - if (xdist < threshAgain && ydist < threshAgain) + if (xdist < threshAgain && ydist < threshAgain) return i; } @@ -237,12 +237,12 @@ void CurvesGraphicsView::mousePressEvent(QMouseEvent* e) if (e->button() == Qt::RightButton) { - int i = findpoint(e->pos().x(), e->pos().y()); + int i = findpoint(e->pos().x(), e->pos().y(), thresh); if (i != -1) emit PointRemovedSignal(m_Index, i); } - else if (findpoint(e->pos().x(), e->pos().y(), true) == -1) + else if (findpoint(e->pos().x(), e->pos().y(), thresh * 8) == -1) { QRectF rect = scene()->sceneRect(); auto points = m_Points[m_Index]; diff --git a/Source/Fractorium/FinalRenderDialog.cpp b/Source/Fractorium/FinalRenderDialog.cpp index c79c8de..821742d 100644 --- a/Source/Fractorium/FinalRenderDialog.cpp +++ b/Source/Fractorium/FinalRenderDialog.cpp @@ -164,11 +164,11 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(QWidget* p, Qt::WindowF m_StripsSpin->setValue(int(m_Settings->FinalStrips())); Scale(eScaleType(m_Settings->FinalScale())); auto bumpmenu = new QMenu(this); - auto add10 = new QAction("Add 10% quality", this); add10->setProperty("tag", QVariant(0.10)); - auto add25 = new QAction("Add 25% quality", this); add25->setProperty("tag", QVariant(0.25)); - auto add50 = new QAction("Add 50% quality", this); add50->setProperty("tag", QVariant(0.50)); - auto add100 = new QAction("Add 100% quality", this); add100->setProperty("tag", QVariant(1.0)); - auto add200 = new QAction("Add 200% quality", this); add200->setProperty("tag", QVariant(2.0)); + auto add10 = new QAction("Add 10% Quality", this); add10->setProperty("tag", QVariant(0.10)); + auto add25 = new QAction("Add 25% Quality", this); add25->setProperty("tag", QVariant(0.25)); + auto add50 = new QAction("Add 50% Quality", this); add50->setProperty("tag", QVariant(0.50)); + auto add100 = new QAction("Add 100% Quality", this); add100->setProperty("tag", QVariant(1.0)); + auto add200 = new QAction("Add 200% Quality", this); add200->setProperty("tag", QVariant(2.0)); bumpmenu->addAction(add10); bumpmenu->addAction(add25); bumpmenu->addAction(add50); @@ -192,7 +192,7 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(QWidget* p, Qt::WindowF saamenu->addAction(saaexr); ui.FinalRenderSaveAgainAsButton->setMenu(saamenu); ui.FinalRenderSaveAgainAsButton->setProperty("tag", "jpg"); - ui.FinalRenderSaveAgainAsButton->setText("Save again as jpg"); + ui.FinalRenderSaveAgainAsButton->setText("Save Again as jpg"); ui.FinalRenderSaveAgainAsButton->setEnabled(false); connect(ui.FinalRenderSaveAgainAsButton, SIGNAL(clicked()), this, SLOT(OnSaveAgainAsClicked())); connect(ui.FinalRenderBumpQualityStartButton, SIGNAL(clicked()), this, SLOT(OnQualityBumpClicked())); @@ -823,7 +823,7 @@ void FractoriumFinalRenderDialog::OnSaveAgainAsClicked() } else if (act) { - ui.FinalRenderSaveAgainAsButton->setText("Save again as " + act->text()); + ui.FinalRenderSaveAgainAsButton->setText("Save Again as " + act->text()); ui.FinalRenderSaveAgainAsButton->setProperty("tag", act->text()); } } diff --git a/Source/Fractorium/FinalRenderDialog.ui b/Source/Fractorium/FinalRenderDialog.ui index 135920e..bdfecd4 100644 --- a/Source/Fractorium/FinalRenderDialog.ui +++ b/Source/Fractorium/FinalRenderDialog.ui @@ -1194,6 +1194,9 @@ + + <html><head/><body><p>Save the rendered image again using the specified file type.</p><p>This will copy in the values for Brightness, Gamma, Gamma Threshold, Vibrancy, Highlight Power, K2, Spatial Filter Type/Width, MinDE, MaxDE and CurveDE from the main window, and if any have changed, it will perform the filtering and imaging steps of the rendering process again before saving.</p><p>The values will not be copied from the main window if Strips is greater than 1.</p></body></html> + Save Again As @@ -1207,6 +1210,9 @@ + + <html><head/><body><p>Render with the additional quality specified, picking up where the last render left off.</p><p>This will copy in the values for Brightness, Gamma, Gamma Threshold, Vibrancy, Highlight Power, K2, Spatial Filter Type/Width, MinDE, MaxDE and CurveDE from the main window and will apply them in the filtering and imaging steps of the rendering process.</p></body></html> + Add Quality diff --git a/Source/Fractorium/FinalRenderEmberController.cpp b/Source/Fractorium/FinalRenderEmberController.cpp index 70931d0..b3b966e 100644 --- a/Source/Fractorium/FinalRenderEmberController.cpp +++ b/Source/Fractorium/FinalRenderEmberController.cpp @@ -118,6 +118,7 @@ FinalRenderEmberController::FinalRenderEmberController(FractoriumFinalRenderD m_FinishedImageCount.store(0); Pause(false); ResetProgress(); + FirstOrDefaultRenderer()->m_ProgressParameter = reinterpret_cast(¤tStripForProgress);//When animating, only the first (primary) device has a progress parameter. if (!isBump) { @@ -128,7 +129,6 @@ FinalRenderEmberController::FinalRenderEmberController(FractoriumFinalRenderD m_XmlWriter.Save(backup.toStdString().c_str(), *m_Ember, 0, true, false, true, false, false); SyncGuiToRenderer(); - FirstOrDefaultRenderer()->m_ProgressParameter = reinterpret_cast(¤tStripForProgress);//When animating, only the first (primary) device has a progress parameter. m_GuiState.m_Strips = VerifyStrips(m_Ember->m_FinalRasH, m_GuiState.m_Strips, [&](const string & s) { Output(QString::fromStdString(s)); }, //Greater than height. [&](const string & s) { Output(QString::fromStdString(s)); }, //Mod height != 0. @@ -297,7 +297,7 @@ FinalRenderEmberController::FinalRenderEmberController(FractoriumFinalRenderD { m_ImageCount = 1; m_Ember->m_TemporalSamples = 1; - m_Fractorium->m_Controller->ParamsToEmber(*m_Ember, true); // update color and filter params + m_Fractorium->m_Controller->ParamsToEmber(*m_Ember, true);//Update color and filter params from the main window controls, which only affect the filter and/or final accumulation stage. m_Renderer->SetEmber(*m_Ember, isBump ? eProcessAction::KEEP_ITERATING : eProcessAction::FULL_RENDER); m_Renderer->PrepFinalAccumVector(m_FinalImage);//Must manually call this first because it could be erroneously made smaller due to strips if called inside Renderer::Run(). m_Stats.Clear(); @@ -750,21 +750,61 @@ EmberNs::Renderer* FinalRenderEmberController::FirstOrDefaultRender /// /// Save the output of the last rendered image using the existing image output buffer in the renderer. +/// Before rendering, this copies the image coloring/filtering values used in the last step of the rendering +/// process, and performs that part of the render, before saving. /// /// The full path and filename the image was saved to. template QString FinalRenderEmberController::SaveCurrentAgain() { - if (!m_Ember) - return ""; + if (!m_Ember) + return ""; - m_Fractorium->m_Controller->ParamsToEmber(*m_Ember, true); // update color and filter params - m_Run = true; - m_Ember->m_TemporalSamples = 1; - m_Renderer->SetEmber(*m_Ember, eProcessAction::FILTER_AND_ACCUM); - m_Renderer->Run(m_FinalImage, 0, m_GuiState.m_Strips, m_GuiState.m_YAxisUp); - m_Run = false; - return SaveCurrentRender(*m_Ember); + if (m_GuiState.m_Strips == 1) + { + size_t currentStripForProgress = 0; + auto brightness = m_Ember->m_Brightness; + auto gamma = m_Ember->m_Gamma; + auto gammathresh = m_Ember->m_GammaThresh; + auto vibrancy = m_Ember->m_Vibrancy; + auto highlight = m_Ember->m_HighlightPower; + auto k2 = m_Ember->m_K2; + auto sftype = m_Ember->m_SpatialFilterType; + auto sfradius = m_Ember->m_SpatialFilterRadius; + auto minde = m_Ember->m_MinRadDE; + auto maxde = m_Ember->m_MaxRadDE; + auto curvede = m_Ember->m_CurveDE; + m_Fractorium->m_Controller->ParamsToEmber(*m_Ember, true);//Update color and filter params from the main window controls, which only affect the filter and/or final accumulation stage. + auto dofilterandaccum = m_GuiState.m_EarlyClip || + brightness != m_Ember->m_Brightness || + k2 != m_Ember->m_K2 || + minde != m_Ember->m_MinRadDE || + maxde != m_Ember->m_MaxRadDE || + curvede != m_Ember->m_CurveDE; + + //This is sort of a hack outside of the normal rendering process above. + if (dofilterandaccum || + gamma != m_Ember->m_Gamma || + gammathresh != m_Ember->m_GammaThresh || + vibrancy != m_Ember->m_Vibrancy || + highlight != m_Ember->m_HighlightPower || + sftype != m_Ember->m_SpatialFilterType || + sfradius != m_Ember->m_SpatialFilterRadius + ) + { + m_Run = true; + m_FinishedImageCount.store(0); + m_Ember->m_TemporalSamples = 1; + m_Renderer->m_ProgressParameter = reinterpret_cast(¤tStripForProgress);//Need to reset this because it was set to a local variable within the render thread. + m_Renderer->SetEmber(*m_Ember, dofilterandaccum ? eProcessAction::FILTER_AND_ACCUM : eProcessAction::ACCUM_ONLY); + m_Renderer->Run(m_FinalImage, 0, m_GuiState.m_Strips, m_GuiState.m_YAxisUp); + m_FinishedImageCount.fetch_add(1); + HandleFinishedProgress(); + m_Run = false; + } + } + + return SaveCurrentRender(*m_Ember); } /// @@ -868,7 +908,7 @@ void FinalRenderEmberController::HandleFinishedProgress() QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderTotalProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, int((float(finishedCountCached) / float(m_ImageCount)) * 100))); QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderImageCountLabel, "setText", Qt::QueuedConnection, Q_ARG(const QString&, ToString(finishedCountCached) + " / " + ToString(m_ImageCount))); - QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderSaveAgainAsButton, "setEnabled", Qt::QueuedConnection, Q_ARG(bool, !doAll && m_Renderer.get() && m_GuiState.m_Strips == 1)); + QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderSaveAgainAsButton, "setEnabled", Qt::QueuedConnection, Q_ARG(bool, !doAll && m_Renderer.get()));//Can do save again with variable number of strips. QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderBumpQualityStartButton, "setEnabled", Qt::QueuedConnection, Q_ARG(bool, !doAll && m_Renderer.get() && m_GuiState.m_Strips == 1)); } diff --git a/Source/Fractorium/FractoriumEmberController.h b/Source/Fractorium/FractoriumEmberController.h index 1e3f087..2885d2c 100644 --- a/Source/Fractorium/FractoriumEmberController.h +++ b/Source/Fractorium/FractoriumEmberController.h @@ -139,9 +139,9 @@ public: virtual void SequenceOpenButtonClicked() { } //Params. - virtual void ParamsToEmber(Ember& ember, bool basicParams = false) { }; + virtual void ParamsToEmber(Ember& ember, bool imageParamsOnly = false) { }; #ifdef DO_DOUBLE - virtual void ParamsToEmber(Ember& ember, bool basicParams = false) { }; + virtual void ParamsToEmber(Ember& ember, bool imageParamsOnly = false) { }; #endif virtual void SetCenter(double x, double y) { } virtual void FillParamTablesAndPalette() { } @@ -425,9 +425,9 @@ public: virtual void SequenceOpenButtonClicked() override; //Params. - virtual void ParamsToEmber(Ember& ember, bool basicParams = false) override; + virtual void ParamsToEmber(Ember& ember, bool imageParamsOnly = false) override; #ifdef DO_DOUBLE - virtual void ParamsToEmber(Ember& ember, bool basicParams = false) override; + virtual void ParamsToEmber(Ember& ember, bool imageParamsOnly = false) override; #endif virtual void SetCenter(double x, double y) override; virtual void FillParamTablesAndPalette() override; @@ -566,7 +566,7 @@ private: template void SetEmberPrivate(const Ember& ember, bool verbatim, bool updatePointer); //Params. - template void ParamsToEmberPrivate(Ember& ember, bool basicParams); + template void ParamsToEmberPrivate(Ember& ember, bool imageParamsOnly); //Xforms. void SetNormalizedWeightText(Xform* xform); diff --git a/Source/Fractorium/FractoriumParams.cpp b/Source/Fractorium/FractoriumParams.cpp index 7d7c6b1..64c2388 100644 --- a/Source/Fractorium/FractoriumParams.cpp +++ b/Source/Fractorium/FractoriumParams.cpp @@ -828,57 +828,57 @@ void FractoriumEmberController::FillParamTablesAndPalette() /// Copy all GUI widget values on the parameters tab to the passed in ember. /// /// The ember to copy values to. -/// true to get just filter and colors. -template void FractoriumEmberController::ParamsToEmber(Ember& ember, bool basicParams) { ParamsToEmberPrivate(ember, basicParams); } +/// True to get just spatial and density filters plus coloring params. +template void FractoriumEmberController::ParamsToEmber(Ember& ember, bool imageParamsOnly) { ParamsToEmberPrivate(ember, imageParamsOnly); } #ifdef DO_DOUBLE -template void FractoriumEmberController::ParamsToEmber(Ember& ember, bool basicParams) { ParamsToEmberPrivate(ember, basicParams); } +template void FractoriumEmberController::ParamsToEmber(Ember& ember, bool imageParamsOnly) { ParamsToEmberPrivate(ember, imageParamsOnly); } #endif template template -void FractoriumEmberController::ParamsToEmberPrivate(Ember& ember, bool basicParams) +void FractoriumEmberController::ParamsToEmberPrivate(Ember& ember, bool imageParamsOnly) { - ember.m_Brightness = m_Fractorium->m_BrightnessSpin->value();//Color. - ember.m_Gamma = m_Fractorium->m_GammaSpin->value(); - ember.m_GammaThresh = m_Fractorium->m_GammaThresholdSpin->value(); - ember.m_Vibrancy = m_Fractorium->m_VibrancySpin->value(); - ember.m_HighlightPower = m_Fractorium->m_HighlightSpin->value(); - ember.m_K2 = m_Fractorium->m_K2Spin->value(); - ember.m_SpatialFilterRadius = m_Fractorium->m_SpatialFilterWidthSpin->value();//Filter. - ember.m_SpatialFilterType = eSpatialFilterType(m_Fractorium->m_SpatialFilterTypeCombo->currentIndex()); - ember.m_TemporalFilterWidth = m_Fractorium->m_TemporalFilterWidthSpin->value(); - ember.m_TemporalFilterType = eTemporalFilterType(m_Fractorium->m_TemporalFilterTypeCombo->currentIndex()); - ember.m_MinRadDE = m_Fractorium->m_DEFilterMinRadiusSpin->value(); - ember.m_MaxRadDE = m_Fractorium->m_DEFilterMaxRadiusSpin->value(); - ember.m_CurveDE = m_Fractorium->m_DECurveSpin->value(); + ember.m_Brightness = m_Fractorium->m_BrightnessSpin->value();//Color. + ember.m_Gamma = m_Fractorium->m_GammaSpin->value(); + ember.m_GammaThresh = m_Fractorium->m_GammaThresholdSpin->value(); + ember.m_Vibrancy = m_Fractorium->m_VibrancySpin->value(); + ember.m_HighlightPower = m_Fractorium->m_HighlightSpin->value(); + ember.m_K2 = m_Fractorium->m_K2Spin->value(); + ember.m_SpatialFilterRadius = m_Fractorium->m_SpatialFilterWidthSpin->value();//Filter. + ember.m_SpatialFilterType = eSpatialFilterType(m_Fractorium->m_SpatialFilterTypeCombo->currentIndex()); + ember.m_MinRadDE = m_Fractorium->m_DEFilterMinRadiusSpin->value(); + ember.m_MaxRadDE = m_Fractorium->m_DEFilterMaxRadiusSpin->value(); + ember.m_CurveDE = m_Fractorium->m_DECurveSpin->value(); - if(basicParams) - return; + if (imageParamsOnly) + return; - auto color = m_Fractorium->ui.ColorTable->item(5, 1)->backgroundColor(); - ember.m_Background.r = color.red() / 255.0; - ember.m_Background.g = color.green() / 255.0; - ember.m_Background.b = color.blue() / 255.0; - ember.m_PaletteMode = ePaletteMode(m_Fractorium->m_PaletteModeCombo->currentIndex()); - ember.m_FinalRasW = m_Fractorium->m_WidthSpin->value();//Geometry. - ember.m_FinalRasH = m_Fractorium->m_HeightSpin->value(); - ember.m_CenterX = m_Fractorium->m_CenterXSpin->value(); - ember.m_CenterY = ember.m_RotCenterY = m_Fractorium->m_CenterYSpin->value(); - ember.m_PixelsPerUnit = m_Fractorium->m_ScaleSpin->value(); - ember.m_Zoom = m_Fractorium->m_ZoomSpin->value(); - ember.m_Rotate = m_Fractorium->m_RotateSpin->value(); - ember.m_CamZPos = m_Fractorium->m_ZPosSpin->value(); - ember.m_CamPerspective = m_Fractorium->m_PerspectiveSpin->value(); - ember.m_CamPitch = m_Fractorium->m_PitchSpin->value() * DEG_2_RAD_T; - ember.m_CamYaw = m_Fractorium->m_YawSpin->value() * DEG_2_RAD_T; - ember.m_CamDepthBlur = m_Fractorium->m_DepthBlurSpin->value(); - ember.m_SubBatchSize = m_Fractorium->m_SbsSpin->value(); - ember.m_FuseCount = m_Fractorium->m_FuseSpin->value(); - ember.m_RandPointRange = m_Fractorium->m_RandRangeSpin->value(); - ember.m_Quality = m_Fractorium->m_QualitySpin->value(); - ember.m_Supersample = m_Fractorium->m_SupersampleSpin->value(); - ember.m_AffineInterp = eAffineInterp(m_Fractorium->m_AffineInterpTypeCombo->currentIndex()); - ember.m_Interp = eInterp(m_Fractorium->m_InterpTypeCombo->currentIndex()); - ember.SyncSize(); + ember.m_TemporalFilterWidth = m_Fractorium->m_TemporalFilterWidthSpin->value(); + ember.m_TemporalFilterType = eTemporalFilterType(m_Fractorium->m_TemporalFilterTypeCombo->currentIndex()); + auto color = m_Fractorium->ui.ColorTable->item(5, 1)->backgroundColor(); + ember.m_Background.r = color.red() / 255.0; + ember.m_Background.g = color.green() / 255.0; + ember.m_Background.b = color.blue() / 255.0; + ember.m_PaletteMode = ePaletteMode(m_Fractorium->m_PaletteModeCombo->currentIndex()); + ember.m_FinalRasW = m_Fractorium->m_WidthSpin->value();//Geometry. + ember.m_FinalRasH = m_Fractorium->m_HeightSpin->value(); + ember.m_CenterX = m_Fractorium->m_CenterXSpin->value(); + ember.m_CenterY = ember.m_RotCenterY = m_Fractorium->m_CenterYSpin->value(); + ember.m_PixelsPerUnit = m_Fractorium->m_ScaleSpin->value(); + ember.m_Zoom = m_Fractorium->m_ZoomSpin->value(); + ember.m_Rotate = m_Fractorium->m_RotateSpin->value(); + ember.m_CamZPos = m_Fractorium->m_ZPosSpin->value(); + ember.m_CamPerspective = m_Fractorium->m_PerspectiveSpin->value(); + ember.m_CamPitch = m_Fractorium->m_PitchSpin->value() * DEG_2_RAD_T; + ember.m_CamYaw = m_Fractorium->m_YawSpin->value() * DEG_2_RAD_T; + ember.m_CamDepthBlur = m_Fractorium->m_DepthBlurSpin->value(); + ember.m_SubBatchSize = m_Fractorium->m_SbsSpin->value(); + ember.m_FuseCount = m_Fractorium->m_FuseSpin->value(); + ember.m_RandPointRange = m_Fractorium->m_RandRangeSpin->value(); + ember.m_Quality = m_Fractorium->m_QualitySpin->value(); + ember.m_Supersample = m_Fractorium->m_SupersampleSpin->value(); + ember.m_AffineInterp = eAffineInterp(m_Fractorium->m_AffineInterpTypeCombo->currentIndex()); + ember.m_Interp = eInterp(m_Fractorium->m_InterpTypeCombo->currentIndex()); + ember.SyncSize(); } ///