diff --git a/stuff/config/current.txt b/stuff/config/current.txt index 9810bda..d88e4b1 100644 --- a/stuff/config/current.txt +++ b/stuff/config/current.txt @@ -1327,30 +1327,40 @@ "STD_iwa_BokehAdvancedFx.hardness1" "Source1 Hardness" "STD_iwa_BokehAdvancedFx.depth_ref1" "Depth Image" "STD_iwa_BokehAdvancedFx.depthRange1" "Source1 Depth Range" + "STD_iwa_BokehAdvancedFx.fillGap1" "Fill Gap" + "STD_iwa_BokehAdvancedFx.doMedian1" "Use Median" "STD_iwa_BokehAdvancedFx.distance2" "Source2 Distance" "STD_iwa_BokehAdvancedFx.bokeh_adjustment2" "Source2 Bokeh Adjustment" "STD_iwa_BokehAdvancedFx.hardness2" "Source2 Hardness" "STD_iwa_BokehAdvancedFx.depth_ref2" "Depth Image" "STD_iwa_BokehAdvancedFx.depthRange2" "Source2 Depth Range" + "STD_iwa_BokehAdvancedFx.fillGap2" "Fill Gap" + "STD_iwa_BokehAdvancedFx.doMedian2" "Use Median" "STD_iwa_BokehAdvancedFx.distance3" "Source3 Distance" "STD_iwa_BokehAdvancedFx.bokeh_adjustment3" "Source3 Bokeh Adjustment" "STD_iwa_BokehAdvancedFx.hardness3" "Source3 Hardness" "STD_iwa_BokehAdvancedFx.depth_ref3" "Depth Image" "STD_iwa_BokehAdvancedFx.depthRange3" "Source3 Depth Range" + "STD_iwa_BokehAdvancedFx.fillGap3" "Fill Gap" + "STD_iwa_BokehAdvancedFx.doMedian3" "Use Median" "STD_iwa_BokehAdvancedFx.distance4" "Source4 Distance" "STD_iwa_BokehAdvancedFx.bokeh_adjustment4" "Source4 Bokeh Adjustment" "STD_iwa_BokehAdvancedFx.hardness4" "Source4 Hardness" "STD_iwa_BokehAdvancedFx.depth_ref4" "Depth Image" "STD_iwa_BokehAdvancedFx.depthRange4" "Source4 Depth Range" + "STD_iwa_BokehAdvancedFx.fillGap4" "Fill Gap" + "STD_iwa_BokehAdvancedFx.doMedian4" "Use Median" "STD_iwa_BokehAdvancedFx.distance5" "Source5 Distance" "STD_iwa_BokehAdvancedFx.bokeh_adjustment5" "Source5 Bokeh Adjustment" "STD_iwa_BokehAdvancedFx.hardness5" "Source5 Hardness" "STD_iwa_BokehAdvancedFx.depth_ref5" "Depth Image" "STD_iwa_BokehAdvancedFx.depthRange5" "Source5 Depth Range" + "STD_iwa_BokehAdvancedFx.fillGap5" "Fill Gap" + "STD_iwa_BokehAdvancedFx.doMedian5" "Use Median" "STD_iwa_TimeCodeFx" "TimeCode Iwa" "STD_iwa_TimeCodeFx.displayType" "Display Type" diff --git a/stuff/profiles/layouts/fxs/STD_iwa_BokehAdvancedFx.xml b/stuff/profiles/layouts/fxs/STD_iwa_BokehAdvancedFx.xml index cb4f562..b12f23e 100644 --- a/stuff/profiles/layouts/fxs/STD_iwa_BokehAdvancedFx.xml +++ b/stuff/profiles/layouts/fxs/STD_iwa_BokehAdvancedFx.xml @@ -11,7 +11,11 @@ distance1 bokeh_adjustment1 hardness1 - depth_ref1 + + depth_ref1 + fillGap1 + doMedian1 + depthRange1 @@ -19,7 +23,11 @@ distance2 bokeh_adjustment2 hardness2 - depth_ref2 + + depth_ref2 + fillGap2 + doMedian2 + depthRange2 @@ -27,7 +35,11 @@ distance3 bokeh_adjustment3 hardness3 - depth_ref3 + + depth_ref3 + fillGap3 + doMedian3 + depthRange3 @@ -35,7 +47,11 @@ distance4 bokeh_adjustment4 hardness4 - depth_ref4 + + depth_ref4 + fillGap4 + doMedian4 + depthRange4 @@ -43,7 +59,11 @@ distance5 bokeh_adjustment5 hardness5 - depth_ref5 + + depth_ref5 + fillGap5 + doMedian5 + depthRange5 @@ -55,6 +75,27 @@ hardness4 hardness5 + + fillGap1 + doMedian1 + + + fillGap2 + doMedian2 + + + fillGap3 + doMedian3 + + + fillGap4 + doMedian4 + + + fillGap5 + doMedian5 + + diff --git a/toonz/sources/stdfx/igs_rotate_blur.cpp b/toonz/sources/stdfx/igs_rotate_blur.cpp index 3a4b51b..4e0684a 100644 --- a/toonz/sources/stdfx/igs_rotate_blur.cpp +++ b/toonz/sources/stdfx/igs_rotate_blur.cpp @@ -362,8 +362,8 @@ int igs::rotate_blur::reference_margin( const double blur_radius, /* ぼかしの始まる半径 */ const double spin_radius, /* ゼロ以上でspin指定となり、 かつぼかし強弱の一定になる半径となる */ - const int type // 0: Accelerator, 1: Uniform Angle, 2: Uniform Length -) { + const int type, // 0: Accelerator, 1: Uniform Angle, 2: Uniform Length + const double ellipse_aspect_ratio) { /* 強度のないとき、なにもしない */ if (degree <= 0.0) { return 0; @@ -402,5 +402,13 @@ int igs::rotate_blur::reference_margin( margin1 = margin2; } + // Consider ellipse deformation. + // Instead of precise computing, return the maximum possible value. + if (ellipse_aspect_ratio != 1.0) { + double axis_x = 2.0 * ellipse_aspect_ratio / (ellipse_aspect_ratio + 1.0); + double axis_y = axis_x / ellipse_aspect_ratio; + margin1 *= std::max(axis_x, axis_y); + } + return static_cast(ceil(margin1)); } diff --git a/toonz/sources/stdfx/igs_rotate_blur.h b/toonz/sources/stdfx/igs_rotate_blur.h index 4bb1d1b..37e4c8f 100644 --- a/toonz/sources/stdfx/igs_rotate_blur.h +++ b/toonz/sources/stdfx/igs_rotate_blur.h @@ -44,8 +44,8 @@ IGS_ROTATE_BLUR_EXPORT int reference_margin( const double blur_radius, /* ぼかしの始まる半径 */ const double spin_radius, /* ゼロ以上でspin指定となり、 かつぼかし強弱の一定になる半径となる */ - const int type // 0: Accelerator, 1: Uniform Angle, 2: Uniform Length -); + const int type, // 0: Accelerator, 1: Uniform Angle, 2: Uniform Length + const double ellipse_aspect_ratio = 1.0); } // namespace rotate_blur } // namespace igs diff --git a/toonz/sources/stdfx/ino_spin_blur.cpp b/toonz/sources/stdfx/ino_spin_blur.cpp index dc59acd..74027b1 100644 --- a/toonz/sources/stdfx/ino_spin_blur.cpp +++ b/toonz/sources/stdfx/ino_spin_blur.cpp @@ -86,8 +86,8 @@ public: static_cast(ceil(bBox.getLy())), static_cast(ceil(bBox.getLx())), center, this->m_blur->getValue(frame), this->m_radius->getValue(frame) * scale, - ((0 < this->m_type->getValue()) ? 0.0 : (bBox.getLy() / 2.0)), - this->m_type->getValue()); + bBox.getLy() / 2.0, this->m_type->getValue(), + this->m_ellipse_aspect_ratio->getValue(frame)); } void get_render_enlarge(const double frame, const TAffine affine, TRectD &bBox) { diff --git a/toonz/sources/stdfx/iwa_bokeh_advancedfx.cpp b/toonz/sources/stdfx/iwa_bokeh_advancedfx.cpp index 7fd6e43..f3c4b39 100644 --- a/toonz/sources/stdfx/iwa_bokeh_advancedfx.cpp +++ b/toonz/sources/stdfx/iwa_bokeh_advancedfx.cpp @@ -144,6 +144,8 @@ Iwa_BokehAdvancedFx::Iwa_BokehAdvancedFx() m_layerParams[layer].m_hardness = TDoubleParamP(0.3); m_layerParams[layer].m_depth_ref = TIntParamP(0); m_layerParams[layer].m_depthRange = TDoubleParamP(1.0); + m_layerParams[layer].m_fillGap = TBoolParamP(true); + m_layerParams[layer].m_doMedian = TBoolParamP(false); std::string str = QString("Source%1").arg(layer + 1).toStdString(); addInputPort(str, m_layerParams[layer].m_source); @@ -158,6 +160,10 @@ Iwa_BokehAdvancedFx::Iwa_BokehAdvancedFx() m_layerParams[layer].m_depth_ref); bindParam(this, QString("depthRange%1").arg(layer + 1).toStdString(), m_layerParams[layer].m_depthRange); + bindParam(this, QString("fillGap%1").arg(layer + 1).toStdString(), + m_layerParams[layer].m_fillGap); + bindParam(this, QString("doMedian%1").arg(layer + 1).toStdString(), + m_layerParams[layer].m_doMedian); m_layerParams[layer].m_distance->setValueRange(0.0, 1.0); m_layerParams[layer].m_bokehAdjustment->setValueRange(0.0, 2.0); @@ -303,8 +309,8 @@ void Iwa_BokehAdvancedFx::doCompute(TTile& tile, double frame, m_layerParams[index].m_bokehAdjustment->getValue(frame); layerValue.depthRange = m_layerParams[index].m_depthRange->getValue(frame); layerValue.distancePrecision = 10; - layerValue.fillGap = true; - layerValue.doMedian = false; + layerValue.fillGap = m_layerParams[index].m_fillGap->getValue(); + layerValue.doMedian = m_layerParams[index].m_doMedian->getValue(); layerValues.append(layerValue); } diff --git a/toonz/sources/stdfx/iwa_bokeh_advancedfx.h b/toonz/sources/stdfx/iwa_bokeh_advancedfx.h index 06d03c8..fa29d7d 100644 --- a/toonz/sources/stdfx/iwa_bokeh_advancedfx.h +++ b/toonz/sources/stdfx/iwa_bokeh_advancedfx.h @@ -41,6 +41,8 @@ protected: TIntParamP m_depth_ref; // port index of depth reference image TDoubleParamP m_depthRange; // distance range varies depends on the // brightness of the reference image (0-1) + TBoolParamP m_fillGap; + TBoolParamP m_doMedian; }; std::array m_layerParams; diff --git a/toonz/sources/toonzlib/outputproperties.cpp b/toonz/sources/toonzlib/outputproperties.cpp index a0a3473..6568f8f 100644 --- a/toonz/sources/toonzlib/outputproperties.cpp +++ b/toonz/sources/toonzlib/outputproperties.cpp @@ -164,6 +164,8 @@ TPropertyGroup *TOutputProperties::getFileFormatProperties(std::string ext) { TPropertyGroup *ret = Tiio::makeWriterProperties(ext); m_formatProperties[ext] = ret; return ret; + } else if (ext == "mov" || ext == "3gp") { + return it->second; } else { // Try to merge settings instead of overriding them TPropertyGroup *ret = Tiio::makeWriterProperties(ext); diff --git a/toonz/sources/toonzqt/fxsettings.cpp b/toonz/sources/toonzqt/fxsettings.cpp index 7a00ba2..40bc869 100644 --- a/toonz/sources/toonzqt/fxsettings.cpp +++ b/toonz/sources/toonzqt/fxsettings.cpp @@ -102,6 +102,36 @@ inputFx); } } */ + +// find the field by parameter name and register the field and its label widget +bool findItemByParamName(QLayout *layout, std::string name, + QList &ret) { + for (int i = 0; i < layout->count(); i++) { + QLayoutItem *item = layout->itemAt(i); + if (!item) continue; + if (item->widget()) { + ParamField *pf = dynamic_cast(item->widget()); + if (pf && pf->getParamName().toStdString() == name) { + ret.push_back(pf); + if (i > 0 && layout->itemAt(i - 1)->widget()) { + QLabel *label = + dynamic_cast(layout->itemAt(i - 1)->widget()); + if (label) ret.push_back(label); + } + return true; + } + // the widget may be a container of another layout + else if (item->widget()->layout()) { + if (findItemByParamName(item->widget()->layout(), name, ret)) + return true; + } + } else if (item->layout()) { + if (findItemByParamName(item->layout(), name, ret)) return true; + } + } + return false; +}; + } // namespace //============================================================================= @@ -369,52 +399,15 @@ void ParamsPage::setPageField(TIStream &is, const TFxP &fx, bool isVertical) { std::string name; is >> name; is.matchEndTag(); - for (int r = 0; r < m_mainLayout->rowCount(); r++) { - QLayoutItem *li = m_mainLayout->itemAtPosition(r, 1); - if (!li) continue; - QWidget *w = li->widget(); - if (!w) continue; - ParamField *pf = dynamic_cast(w); - if (pf) { - if (pf->getParamName().toStdString() == name) { - if (tagName == "controller") - controller_bpf = dynamic_cast(pf); - else if (tagName == "on") { - on_items.push_back(w); - on_items.push_back( - m_mainLayout->itemAtPosition(r, 0)->widget()); - } else if (tagName == "off") { - off_items.push_back(w); - off_items.push_back( - m_mainLayout->itemAtPosition(r, 0)->widget()); - } - } - } - /*-- 入れ子のLayoutも1段階探す --*/ - else { - QGridLayout *gridLay = dynamic_cast(w->layout()); - if (!gridLay) continue; - for (int r_s = 0; r_s < gridLay->rowCount(); r_s++) { - QLayoutItem *li_s = gridLay->itemAtPosition(r_s, 1); - if (!li_s) continue; - ParamField *pf_s = dynamic_cast(li_s->widget()); - if (pf_s) { - if (pf_s->getParamName().toStdString() == name) { - if (tagName == "controller") - controller_bpf = dynamic_cast(pf_s); - else if (tagName == "on") { - on_items.push_back(pf_s); - on_items.push_back( - gridLay->itemAtPosition(r_s, 0)->widget()); - } else if (tagName == "off") { - off_items.push_back(pf_s); - off_items.push_back( - gridLay->itemAtPosition(r_s, 0)->widget()); - } - } - } - } - } + + QList widgets; + if (findItemByParamName(m_mainLayout, name, widgets)) { + if (tagName == "controller") { + controller_bpf = dynamic_cast(widgets[0]); + } else if (tagName == "on") + on_items.append(widgets); + else if (tagName == "off") + off_items.append(widgets); } } else throw TException("unexpected tag " + tagName); @@ -866,8 +859,8 @@ void ParamsPageSet::addParamsPage(ParamsPage *page, const char *name) { /*-- このFxで最大サイズのページに合わせてダイアログをリサイズ --*/ QSize pagePreferredSize = page->getPreferredSize(); m_preferredSize = m_preferredSize.expandedTo( - pagePreferredSize + QSize(m_tabBarContainer->height() + 2, - 2)); /*-- 2は上下左右のマージン --*/ + pagePreferredSize + QSize(m_tabBarContainer->height() + 2, + 2)); /*-- 2は上下左右のマージン --*/ QScrollArea *pane = new QScrollArea(this); pane->setWidgetResizable(true); @@ -970,8 +963,8 @@ void ParamsPageSet::createPage(TIStream &is, const TFxP &fx, int index) { /*-- このFxで最大サイズのページに合わせてダイアログをリサイズ --*/ QSize pagePreferredSize = paramsPage->getPreferredSize(); m_preferredSize = m_preferredSize.expandedTo( - pagePreferredSize + QSize(m_tabBarContainer->height() + 2, - 2)); /*-- 2は上下左右のマージン --*/ + pagePreferredSize + QSize(m_tabBarContainer->height() + 2, + 2)); /*-- 2は上下左右のマージン --*/ QScrollArea *scrollAreaPage = new QScrollArea(this); scrollAreaPage->setWidgetResizable(true); @@ -996,7 +989,7 @@ void ParamsPageSet::recomputePreferredSize() { if (!page) continue; QSize pagePreferredSize = page->getPreferredSize(); newSize = newSize.expandedTo(pagePreferredSize + - QSize(m_tabBarContainer->height() + 2, 2)); + QSize(m_tabBarContainer->height() + 2, 2)); } if (!newSize.isEmpty()) { m_preferredSize = newSize; @@ -1235,7 +1228,7 @@ FxSettings::FxSettings(QWidget *parent, const TPixel32 &checkCol1, //---signal-slot connections bool ret = true; ret = ret && connect(m_paramViewer, SIGNAL(currentFxParamChanged()), - SLOT(updateViewer())); + SLOT(updateViewer())); ret = ret && connect(m_viewer, SIGNAL(pointPositionChanged(int, const TPointD &)), SLOT(onPointChanged(int, const TPointD &)));