From 2c0f507302d68ea566fab7a1c8657c48d9466aa0 Mon Sep 17 00:00:00 2001 From: shun_iwasawa Date: Sep 11 2017 02:03:30 +0000 Subject: color filter available on render and vector levels --- diff --git a/stuff/config/loc/日本語/toonz.qm b/stuff/config/loc/日本語/toonz.qm index 7bd214a..1cb3d38 100644 Binary files a/stuff/config/loc/日本語/toonz.qm and b/stuff/config/loc/日本語/toonz.qm differ diff --git a/stuff/config/loc/日本語/toonzlib.qm b/stuff/config/loc/日本語/toonzlib.qm index 09163d1..b5b4850 100644 Binary files a/stuff/config/loc/日本語/toonzlib.qm and b/stuff/config/loc/日本語/toonzlib.qm differ diff --git a/toonz/sources/common/tcolor/tcolorfunctions.cpp b/toonz/sources/common/tcolor/tcolorfunctions.cpp index 95f7112..757c485 100644 --- a/toonz/sources/common/tcolor/tcolorfunctions.cpp +++ b/toonz/sources/common/tcolor/tcolorfunctions.cpp @@ -75,3 +75,17 @@ bool TOnionFader::getParameters(Parameters &p) const { p.m_cM = m_color.m; return true; } + +//--------------------------------------- + +TPixel32 TColumnColorFilterFunction::operator()(const TPixel32 &color) const { + int r = 255 - (255 - color.r) * (255 - m_colorScale.r) / 255; + int g = 255 - (255 - color.g) * (255 - m_colorScale.g) / 255; + int b = 255 - (255 - color.b) * (255 - m_colorScale.b) / 255; + return TPixel32(r, g, b, color.m * m_colorScale.m / 255); +} + +bool TColumnColorFilterFunction::getParameters(Parameters &p) const { + assert(false); + return true; +} diff --git a/toonz/sources/common/tfx/unaryFx.cpp b/toonz/sources/common/tfx/unaryFx.cpp index 4c71c8b..5ff3584 100644 --- a/toonz/sources/common/tfx/unaryFx.cpp +++ b/toonz/sources/common/tfx/unaryFx.cpp @@ -7,6 +7,7 @@ #include "trasterfx.h" #include "tflash.h" #include "tfxparam.h" +#include "tparamset.h" //#define ALLOW_SHEAR @@ -161,6 +162,58 @@ void TRasterFx::compute(TFlash &flash, int frame) { FX_IDENTIFIER_IS_HIDDEN(NaAffineFx, "naAffineFx") //================================================================== +// ColumnColorFilterFx +//================================================================== + +ColumnColorFilterFx::ColumnColorFilterFx() : m_colorFilter(TPixel::Black) { + setName(L"ColumnColorFilterFx"); + addInputPort("source", m_port); +} + +bool ColumnColorFilterFx::doGetBBox(double frame, TRectD &bBox, + const TRenderSettings &info) { + if (!m_port.isConnected()) return false; + TRasterFxP fx = m_port.getFx(); + assert(fx); + bool ret = fx->doGetBBox(frame, bBox, info); + return ret; +} + +void ColumnColorFilterFx::doCompute(TTile &tile, double frame, + const TRenderSettings &ri) { + if (!m_port.isConnected()) return; + + if (!TRaster32P(tile.getRaster()) && !TRaster64P(tile.getRaster())) + throw TException("AffineFx unsupported pixel type"); + + TRasterFxP src = m_port.getFx(); + src->compute(tile, frame, ri); + + TRop::applyColorScale(tile.getRaster(), m_colorFilter); +} + +std::string ColumnColorFilterFx::getAlias(double frame, + const TRenderSettings &info) const { + std::string alias = getFxType(); + alias += "["; + if (m_port.isConnected()) { + TRasterFxP ifx = m_port.getFx(); + assert(ifx); + alias += ifx->getAlias(frame, info); + } + alias += ","; + + return alias + std::to_string(m_colorFilter.r) + "," + + std::to_string(m_colorFilter.g) + "," + + std::to_string(m_colorFilter.b) + "," + + std::to_string(m_colorFilter.m) + "]"; +} + +//-------------------------------------------------- + +FX_IDENTIFIER_IS_HIDDEN(ColumnColorFilterFx, "columnColorFilterFx") + +//================================================================== // Geometric Fx //================================================================== diff --git a/toonz/sources/common/trop/toperators.cpp b/toonz/sources/common/trop/toperators.cpp index 76f47f8..23c1053 100644 --- a/toonz/sources/common/trop/toperators.cpp +++ b/toonz/sources/common/trop/toperators.cpp @@ -1621,6 +1621,67 @@ void TRop::whiteTransp(const TRasterP &ras) { //----------------------------------------------------------------------------- +void TRop::applyColorScale(const TRasterP &ras, const TPixel32 &colorScale) { + ras->lock(); + + TRop::depremultiply(ras); + + TRaster32P ras32 = ras; + int maxCh = TPixel32::maxChannelValue; + if (ras32) { + TPixel32 *endPix, *upPix = 0, *upRow = ras32->pixels(); + TPixel32 *lastPix = + upRow + ras32->getWrap() * (ras32->getLy() - 1) + ras32->getLx(); + + while (upPix < lastPix) { + upPix = upRow; + endPix = upPix + ras32->getLx(); + while (upPix < endPix) { + int maxCh = TPixel32::maxChannelValue; + int r = maxCh - (maxCh - (*upPix).r) * (maxCh - colorScale.r) / maxCh; + int g = maxCh - (maxCh - (*upPix).g) * (maxCh - colorScale.g) / maxCh; + int b = maxCh - (maxCh - (*upPix).b) * (maxCh - colorScale.b) / maxCh; + int m = (*upPix).m * colorScale.m / maxCh; + *upPix = TPixel32(r, g, b, m); + ++upPix; + } + upRow += ras32->getWrap(); + } + } else { + TRaster64P ras64 = ras; + if (ras64) { + TPixel64 *endPix, *upPix = 0, *upRow = ras64->pixels(); + TPixel64 *lastPix = + upRow + ras64->getWrap() * (ras64->getLy() - 1) + ras64->getLx(); + + int maxCh64 = TPixel64::maxChannelValue; + while (upPix < lastPix) { + upPix = upRow; + endPix = upPix + ras64->getLx(); + while (upPix < endPix) { + int r = + maxCh64 - (maxCh64 - (*upPix).r) * (maxCh - colorScale.r) / maxCh; + int g = + maxCh64 - (maxCh64 - (*upPix).g) * (maxCh - colorScale.g) / maxCh; + int b = + maxCh64 - (maxCh64 - (*upPix).b) * (maxCh - colorScale.b) / maxCh; + int m = (*upPix).m * colorScale.m / maxCh; + *upPix = TPixel64(r, g, b, m); + ++upPix; + } + upRow += ras64->getWrap(); + } + } else { + ras->unlock(); + throw TException("TRop::premultiply invalid raster type"); + } + } + TRop::premultiply(ras); + ras->unlock(); +} + +//----------------------------------------------------------------------------- + template const double *premultiplyTable() { static double *table = 0; diff --git a/toonz/sources/include/tbasefx.h b/toonz/sources/include/tbasefx.h index 17355f7..f4d3cc5 100644 --- a/toonz/sources/include/tbasefx.h +++ b/toonz/sources/include/tbasefx.h @@ -37,4 +37,35 @@ public: std::string getPluginId() const override { return "Base"; } }; +//****************************************************************************** +// ColumnColorFilterFx declaration +//****************************************************************************** + +class ColumnColorFilterFx final : public TBaseRasterFx { + FX_DECLARATION(ColumnColorFilterFx) + TPixel32 m_colorFilter; + +protected: + TRasterFxPort m_port; + +public: + ColumnColorFilterFx(); + + ~ColumnColorFilterFx(){}; + + bool canHandle(const TRenderSettings &info, double frame) override { + return true; + } + + bool doGetBBox(double frame, TRectD &bBox, + const TRenderSettings &info) override; + + void doCompute(TTile &tile, double frame, const TRenderSettings &ri) override; + + void setColorFilter(TPixel32 color) { m_colorFilter = color; } + + std::string getAlias(double frame, + const TRenderSettings &info) const override; +}; + #endif // TBASEFX_INCLUDED diff --git a/toonz/sources/include/tcolorfunctions.h b/toonz/sources/include/tcolorfunctions.h index 4b68c5c..9cd449b 100644 --- a/toonz/sources/include/tcolorfunctions.h +++ b/toonz/sources/include/tcolorfunctions.h @@ -110,4 +110,21 @@ public: bool getParameters(Parameters &p) const override; }; +//----------------------------------------------------------------------------- + +class DVAPI TColumnColorFilterFunction final : public TColorFunction { + TPixel32 m_colorScale; + +public: + TColumnColorFilterFunction() : m_colorScale() {} + TColumnColorFilterFunction(const TPixel32 &color) : m_colorScale(color) {} + + TColorFunction *clone() const override { + return new TColumnColorFilterFunction(m_colorScale); + } + + TPixel32 operator()(const TPixel32 &color) const override; + bool getParameters(Parameters &p) const override; +}; + #endif diff --git a/toonz/sources/include/tfxutil.h b/toonz/sources/include/tfxutil.h index 5cb83e5..e672781 100644 --- a/toonz/sources/include/tfxutil.h +++ b/toonz/sources/include/tfxutil.h @@ -27,6 +27,8 @@ DVAPI TFxP makeAffine(const TFxP &arg, const TAffine &aff); DVAPI TFxP makeBlur(const TFxP &arg, double value); +DVAPI TFxP makeColumnColorFilter(const TFxP &arg, TPixel32 colorScale); + DVAPI TFxP makeRadialGradient(/*TPixel32 color*/); enum { NO_KEYFRAMES = 0, ALL_KEYFRAMES = 1, SOME_KEYFRAMES = -1 }; diff --git a/toonz/sources/include/toonz/sceneproperties.h b/toonz/sources/include/toonz/sceneproperties.h index 33396c2..2c2c6b6 100644 --- a/toonz/sources/include/toonz/sceneproperties.h +++ b/toonz/sources/include/toonz/sceneproperties.h @@ -75,6 +75,8 @@ private: //! Xsheet Note Color, color number = 7. QList m_notesColor; + bool m_columnColorFilterOnRender; + public: /*! The constructor creates: @@ -247,6 +249,17 @@ and height. */ void setFieldGuideAspectRatio(double ar); + /* Returns whether the column color filter and transparency is available also + * in render */ + bool isColumnColorFilterOnRenderEnabled() const { + return m_columnColorFilterOnRender; + } + + /* Activate / deactivate the column color filter in render */ + void enableColumnColorFilterOnRender(bool on) { + m_columnColorFilterOnRender = on; + } + //! Substitutes current cameras with those stored in the specified stage tree. void cloneCamerasFrom(TStageObjectTree *stageObjects); diff --git a/toonz/sources/include/toonz/txshcolumn.h b/toonz/sources/include/toonz/txshcolumn.h index 0d01c15..80e5aaf 100644 --- a/toonz/sources/include/toonz/txshcolumn.h +++ b/toonz/sources/include/toonz/txshcolumn.h @@ -7,6 +7,9 @@ #include "tpersist.h" #include "traster.h" +#include +#include + #undef DVAPI #undef DVVAR #ifdef TOONZLIB_EXPORTS @@ -64,7 +67,20 @@ class DVAPI TXshColumn : public TColumnHeader, public TPersist { int m_colorTag; // Usato solo in tabkids UCHAR m_opacity; - int m_filterColorId; +public: + enum FilterColor { + FilterNone = 0, + FilterRed, + FilterGreen, + FilterBlue, + FilterDarkYellow, + FilterDarkCyan, + FilterDarkMagenta, + FilterAmount + }; + +private: + FilterColor m_filterColorId; protected: enum { @@ -97,7 +113,7 @@ Constructs a TXshColumn with default value. , m_xsheet(0) , m_colorTag(0) , m_opacity(255) - , m_filterColorId(0) {} + , m_filterColorId(FilterNone) {} enum ColumnType { eLevelType = 0, @@ -244,8 +260,11 @@ Set column color tag to \b colorTag. m_colorTag = colorTag; } // Usato solo in tabkids - int getFilterColorId() const { return m_filterColorId; } - void setFilterColorId(int id) { m_filterColorId = id; } + FilterColor getFilterColorId() const { return m_filterColorId; } + void setFilterColorId(FilterColor id) { m_filterColorId = id; } + TPixel32 getFilterColor(); + static QPair getFilterInfo(FilterColor key); + static void initColorFilters(); }; #ifdef _WIN32 diff --git a/toonz/sources/include/trop.h b/toonz/sources/include/trop.h index 434a7ed..e9dc7a7 100644 --- a/toonz/sources/include/trop.h +++ b/toonz/sources/include/trop.h @@ -294,6 +294,10 @@ DVAPI void depremultiply(const TRasterP &ras); //! all white pixels are set to transparent DVAPI void whiteTransp(const TRasterP &ras); +//! apply color filter and semi-transparency of column to the render result +// implemented in toperators.cpp +DVAPI void applyColorScale(const TRasterP &ras, const TPixel32 &colorScale); + DVAPI TRasterP shrink(TRasterP rin, int shrink); //! Make a \b gamma correct in the \b raster diff --git a/toonz/sources/tnzbase/tfxutil.cpp b/toonz/sources/tnzbase/tfxutil.cpp index b04bd4d..48b9199 100644 --- a/toonz/sources/tnzbase/tfxutil.cpp +++ b/toonz/sources/tnzbase/tfxutil.cpp @@ -106,6 +106,7 @@ TFxP TFxUtil::makeAffine(const TFxP &arg, const TAffine &aff) { assert(!"Could not connect ports!"); return fx; } + //------------------------------------------------------------------- TFxP TFxUtil::makeBlur(const TFxP &arg, double blurValue) { @@ -119,6 +120,17 @@ TFxP TFxUtil::makeBlur(const TFxP &arg, double blurValue) { //------------------------------------------------------------------- +TFxP TFxUtil::makeColumnColorFilter(const TFxP &arg, TPixel32 colorScale) { + ColumnColorFilterFx *colorFilterfx = new ColumnColorFilterFx(); + assert(colorFilterfx); + colorFilterfx->setColorFilter(colorScale); + if (!colorFilterfx->connect("source", arg.getPointer())) + assert(!"Could not connect ports!"); + return colorFilterfx; +} + +//------------------------------------------------------------------- + int TFxUtil::getKeyframeStatus(const TFxP &fx, int frame) { bool keyframed = false, notKeyframed = false; for (int i = 0; i < fx->getParams()->getParamCount(); i++) { diff --git a/toonz/sources/toonz/scenesettingspopup.cpp b/toonz/sources/toonz/scenesettingspopup.cpp index d3c7ba7..83a25b1 100644 --- a/toonz/sources/toonz/scenesettingspopup.cpp +++ b/toonz/sources/toonz/scenesettingspopup.cpp @@ -117,6 +117,13 @@ SceneSettingsPopup::SceneSettingsPopup() m_markerIntervalFld = new DVGui::IntLineEdit(this, distance, 0); m_startFrameFld = new DVGui::IntLineEdit(this, offset); + // Whether the column color filter and transparency is available also in + // render + m_colorFilterOnRenderCB = new DVGui::CheckBox( + tr("Enable Column Color Filter and Transparency for Rendering"), this); + m_colorFilterOnRenderCB->setChecked( + sprop->isColumnColorFilterOnRenderEnabled()); + // layout QGridLayout *mainLayout = new QGridLayout(); mainLayout->setMargin(10); @@ -154,13 +161,16 @@ SceneSettingsPopup::SceneSettingsPopup() mainLayout->addWidget(new QLabel(tr(" Start Frame:"), this), 5, 2, Qt::AlignRight | Qt::AlignVCenter); mainLayout->addWidget(m_startFrameFld, 5, 3); + + // Use Color Filter and Transparency for Rendering + mainLayout->addWidget(m_colorFilterOnRenderCB, 6, 0, 1, 4); } mainLayout->setColumnStretch(0, 0); mainLayout->setColumnStretch(1, 0); mainLayout->setColumnStretch(2, 0); mainLayout->setColumnStretch(3, 0); mainLayout->setColumnStretch(4, 1); - mainLayout->setRowStretch(6, 1); + mainLayout->setRowStretch(7, 1); setLayout(mainLayout); // signal-slot connections @@ -188,6 +198,9 @@ SceneSettingsPopup::SceneSettingsPopup() SLOT(onMakerIntervalEditingFinished())); ret = ret && connect(m_startFrameFld, SIGNAL(editingFinished()), this, SLOT(onStartFrameEditingFinished())); + // Use Color Filter and Transparency for Rendering + ret = ret && connect(m_colorFilterOnRenderCB, SIGNAL(stateChanged(int)), this, + SLOT(onColorFilterOnRenderChanged())); assert(ret); } @@ -345,6 +358,14 @@ void SceneSettingsPopup::setBgColor(const TPixel32 &bgColor, bool isDragging) { TApp::instance()->getCurrentScene()->notifySceneChanged(); } +//----------------------------------------------------------------------------- + +void SceneSettingsPopup::onColorFilterOnRenderChanged() { + TSceneProperties *sprop = getProperties(); + sprop->enableColumnColorFilterOnRender(m_colorFilterOnRenderCB->isChecked()); + TApp::instance()->getCurrentScene()->notifySceneChanged(); +} + //============================================================================= OpenPopupCommandHandler openSceneSettingsPopup( diff --git a/toonz/sources/toonz/scenesettingspopup.h b/toonz/sources/toonz/scenesettingspopup.h index 1160f13..ecd487a 100644 --- a/toonz/sources/toonz/scenesettingspopup.h +++ b/toonz/sources/toonz/scenesettingspopup.h @@ -8,6 +8,7 @@ #include "toonzqt/intfield.h" #include "toonzqt/doublefield.h" #include "toonzqt/colorfield.h" +#include "toonzqt/checkbox.h" // forward declaration class TSceneProperties; @@ -32,6 +33,8 @@ class SceneSettingsPopup final : public QDialog { DVGui::IntLineEdit *m_markerIntervalFld; DVGui::IntLineEdit *m_startFrameFld; + DVGui::CheckBox *m_colorFilterOnRenderCB; + TSceneProperties *getProperties() const; public: @@ -56,6 +59,8 @@ public slots: void onStartFrameEditingFinished(); void setBgColor(const TPixel32 &value, bool isDragging); + + void onColorFilterOnRenderChanged(); }; #endif // SCENESETTINGSPOPUP_H diff --git a/toonz/sources/toonz/xshcolumnviewer.cpp b/toonz/sources/toonz/xshcolumnviewer.cpp index 83e405d..b48c669 100644 --- a/toonz/sources/toonz/xshcolumnviewer.cpp +++ b/toonz/sources/toonz/xshcolumnviewer.cpp @@ -103,11 +103,10 @@ bool containsRasterLevel(TColumnSelection *selection) { return false; } -const QIcon getColorChipIcon(const int id) { - static QList colors = {Qt::red, Qt::green, Qt::blue, - Qt::darkYellow, Qt::darkCyan, Qt::darkMagenta}; +const QIcon getColorChipIcon(TPixel32 color) { + QColor qCol((int)color.r, (int)color.g, (int)color.b, (int)color.m); QPixmap pixmap(12, 12); - pixmap.fill(colors.at(id - 1)); + pixmap.fill(qCol); return QIcon(pixmap); } @@ -898,7 +897,7 @@ void ColumnArea::DrawHeader::drawFilterColor() const { QRect filterColorRect = o->rect(PredefinedRect::FILTER_COLOR).translated(orig); p.drawPixmap(filterColorRect, - getColorChipIcon(column->getFilterColorId()).pixmap(12, 12)); + getColorChipIcon(column->getFilterColor()).pixmap(12, 12)); } void ColumnArea::DrawHeader::drawSoundIcon(bool isPlaying) const { @@ -1431,20 +1430,16 @@ static QFont font("Helvetica", 7, QFont::Normal); m_value->setFont(font);*/ m_filterColorCombo = new QComboBox(this); - m_filterColorCombo->addItem(tr("None"), 0); - m_filterColorCombo->addItem(getColorChipIcon(1), tr("Red"), 1); - m_filterColorCombo->addItem(getColorChipIcon(2), tr("Green"), 2); - m_filterColorCombo->addItem(getColorChipIcon(3), tr("Blue"), 3); - m_filterColorCombo->addItem(getColorChipIcon(4), tr("DarkYellow"), 4); - m_filterColorCombo->addItem(getColorChipIcon(5), tr("DarkCyan"), 5); - m_filterColorCombo->addItem(getColorChipIcon(6), tr("DarkMagenta"), 6); - // For now the color filter affects only for Raster and ToonzRaser levels. - // TODO: Make this property to affect vector levels as well. - m_filterColorCombo->setToolTip( - tr("N.B. Filter doesn't affect vector levels")); + for (int f = 0; f < (int)TXshColumn::FilterAmount; f++) { + QPair info = + TXshColumn::getFilterInfo((TXshColumn::FilterColor)f); + if ((TXshColumn::FilterColor)f == TXshColumn::FilterNone) + m_filterColorCombo->addItem(info.first, f); + else + m_filterColorCombo->addItem(getColorChipIcon(info.second), info.first, f); + } QLabel *filterLabel = new QLabel(tr("Filter:"), this); - filterLabel->setToolTip(tr("N.B. Filter doesn't affect vector levels")); QVBoxLayout *mainLayout = new QVBoxLayout(); mainLayout->setMargin(3); @@ -1523,7 +1518,7 @@ void ColumnTransparencyPopup::onValueChanged(const QString &str) { //---------------------------------------------------------------- void ColumnTransparencyPopup::onFilterColorChanged(int id) { - m_column->setFilterColorId(id); + m_column->setFilterColorId((TXshColumn::FilterColor)id); TApp::instance()->getCurrentScene()->notifySceneChanged(); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); ((ColumnArea *)parent())->update(); diff --git a/toonz/sources/toonzlib/scenefx.cpp b/toonz/sources/toonzlib/scenefx.cpp index cfe2ed2..cd764da 100644 --- a/toonz/sources/toonzlib/scenefx.cpp +++ b/toonz/sources/toonzlib/scenefx.cpp @@ -847,6 +847,16 @@ PlacedFx FxBuilder::makePF(TLevelColumnFx *lcfx) { } } + // Apply column's color filter and semi-transparency for rendering + TXshLevelColumn *column = lcfx->getColumn(); + if (m_scene->getProperties()->isColumnColorFilterOnRenderEnabled() && + (column->getFilterColorId() != TXshColumn::FilterNone || + (column->isCamstandVisible() && column->getOpacity() != 255))) { + TPixel32 colorScale = column->getFilterColor(); + colorScale.m = column->getOpacity(); + pf.m_fx = TFxUtil::makeColumnColorFilter(pf.m_fx, colorScale); + } + return pf; } else return PlacedFx(); diff --git a/toonz/sources/toonzlib/sceneproperties.cpp b/toonz/sources/toonzlib/sceneproperties.cpp index 8b142ef..1c3a2e9 100644 --- a/toonz/sources/toonzlib/sceneproperties.cpp +++ b/toonz/sources/toonzlib/sceneproperties.cpp @@ -36,7 +36,8 @@ TSceneProperties::TSceneProperties() , m_fullcolorSubsampling(1) , m_tlvSubsampling(1) , m_fieldGuideSize(16) - , m_fieldGuideAspectRatio(1.77778) { + , m_fieldGuideAspectRatio(1.77778) + , m_columnColorFilterOnRender(false) { // Default color m_notesColor.push_back(TPixel32(255, 235, 140)); m_notesColor.push_back(TPixel32(255, 160, 120)); @@ -80,13 +81,14 @@ void TSceneProperties::assign(const TSceneProperties *sprop) { for (int i = 0; i < (int)m_cameras.size(); i++) m_cameras[i] = new TCamera(*m_cameras[i]); } - m_bgColor = sprop->m_bgColor; - m_markerDistance = sprop->m_markerDistance; - m_markerOffset = sprop->m_markerOffset; - m_fullcolorSubsampling = sprop->m_fullcolorSubsampling; - m_tlvSubsampling = sprop->m_tlvSubsampling; - m_fieldGuideSize = sprop->m_fieldGuideSize; - m_fieldGuideAspectRatio = sprop->m_fieldGuideAspectRatio; + m_bgColor = sprop->m_bgColor; + m_markerDistance = sprop->m_markerDistance; + m_markerOffset = sprop->m_markerOffset; + m_fullcolorSubsampling = sprop->m_fullcolorSubsampling; + m_tlvSubsampling = sprop->m_tlvSubsampling; + m_fieldGuideSize = sprop->m_fieldGuideSize; + m_fieldGuideAspectRatio = sprop->m_fieldGuideAspectRatio; + m_columnColorFilterOnRender = sprop->m_columnColorFilterOnRender; int i; for (i = 0; i < m_notesColor.size(); i++) m_notesColor.replace(i, sprop->getNoteColor(i)); @@ -295,6 +297,7 @@ void TSceneProperties::saveData(TOStream &os) const { os.child("markers") << m_markerDistance << m_markerOffset; os.child("subsampling") << m_fullcolorSubsampling << m_tlvSubsampling; os.child("fieldguide") << m_fieldGuideSize << m_fieldGuideAspectRatio; + if (m_columnColorFilterOnRender) os.child("columnColorFilterOnRender") << 1; os.openChild("noteColors"); for (i = 0; i < m_notesColor.size(); i++) os << m_notesColor.at(i); @@ -339,6 +342,10 @@ void TSceneProperties::loadData(TIStream &is, bool isLoadingProject) { is >> m_fullcolorSubsampling >> m_tlvSubsampling; } else if (tagName == "fieldguide") { is >> m_fieldGuideSize >> m_fieldGuideAspectRatio; + } else if (tagName == "columnColorFilterOnRender") { + int val; + is >> val; + enableColumnColorFilterOnRender(val == 1); } else if (tagName == "safearea") { double dummy1, dummy2; is >> dummy1 >> dummy2; diff --git a/toonz/sources/toonzlib/stage.cpp b/toonz/sources/toonzlib/stage.cpp index 22146b8..44801ac 100644 --- a/toonz/sources/toonzlib/stage.cpp +++ b/toonz/sources/toonzlib/stage.cpp @@ -96,35 +96,6 @@ void updateOnionSkinSize(const PlayerSet &players) { bool descending(int i, int j) { return (i > j); } //---------------------------------------------------------------- - -TPixel32 getFilterColorFromId(int id) { - switch (id) { - case 0: - return TPixel::Black; - break; - case 1: - return TPixel::Red; - break; - case 2: - return TPixel::Green; - break; - case 3: - return TPixel::Blue; - break; - case 4: - return TPixel(128, 128, 0); - break; - case 5: - return TPixel(0, 128, 128); - break; - case 6: - return TPixel(128, 0, 128); - break; - } - return TPixel::Black; -} - -//---------------------------------------------------------------- } //============================================================================= @@ -396,7 +367,7 @@ void StageBuilder::addCell(PlayerSet &players, ToonzScene *scene, TXsheet *xsh, player.m_ancestorColumnIndex = m_ancestorColumnIndex; player.m_masks = m_masks; player.m_opacity = column->getOpacity(); - player.m_filterColor = getFilterColorFromId(column->getFilterColorId()); + player.m_filterColor = column->getFilterColor(); if (m_subXSheetStack.empty()) { player.m_z = columnZ; diff --git a/toonz/sources/toonzlib/stagevisitor.cpp b/toonz/sources/toonzlib/stagevisitor.cpp index 87339fc..29ccf07 100644 --- a/toonz/sources/toonzlib/stagevisitor.cpp +++ b/toonz/sources/toonzlib/stagevisitor.cpp @@ -822,6 +822,10 @@ void RasterPainter::onVectorImage(TVectorImage *vi, c[3] = 0.0; cf = new TGenericColorFunction(m, c); + } else if (player.m_filterColor != TPixel::Black) { + TPixel32 colorScale = player.m_filterColor; + colorScale.m = player.m_opacity; + cf = new TColumnColorFilterFunction(colorScale); } else if (player.m_opacity < 255) cf = new TTranspFader(player.m_opacity / 255.0); diff --git a/toonz/sources/toonzlib/tcolumnfx.cpp b/toonz/sources/toonzlib/tcolumnfx.cpp index 9b83cd1..d26220d 100644 --- a/toonz/sources/toonzlib/tcolumnfx.cpp +++ b/toonz/sources/toonzlib/tcolumnfx.cpp @@ -1141,6 +1141,7 @@ void TLevelColumnFx::doCompute(TTile &tile, double frame, filler.rectFill(appRas->getBounds(), params, false); ras = appRas; } + } else if (ti) { // Colormap case @@ -1215,6 +1216,7 @@ void TLevelColumnFx::doCompute(TTile &tile, double frame, int prevFrame = palette->getFrame(); palette->setFrame((int)frame); + TTile auxtile(TRaster32P(inTile.getRaster()->getSize()), inTile.m_pos); TRop::convert(auxtile, inTile, palette, false, true); palette->setFrame(prevFrame); diff --git a/toonz/sources/toonzlib/txshcolumn.cpp b/toonz/sources/toonzlib/txshcolumn.cpp index e1f2890..f954736 100644 --- a/toonz/sources/toonzlib/txshcolumn.cpp +++ b/toonz/sources/toonzlib/txshcolumn.cpp @@ -18,6 +18,12 @@ #include "toonz/preferences.h" #include "toonz/txshleveltypes.h" +#include + +namespace { +QMap> filterColors; +}; + //============================================================================= // TXshCellColumn @@ -605,3 +611,41 @@ void TXshColumn::setIsMask(bool on) { else m_status &= ~mask; } + +//----------------------------------------------------------------------------- + +void TXshColumn::initColorFilters() { + static bool _firstTime = true; + if (!_firstTime) return; + filterColors[TXshColumn::FilterNone] = + QPair(QObject::tr("None"), TPixel::Black); + filterColors[TXshColumn::FilterRed] = + QPair(QObject::tr("Red"), TPixel::Red); + filterColors[TXshColumn::FilterGreen] = + QPair(QObject::tr("Green"), TPixel::Green); + filterColors[TXshColumn::FilterBlue] = + QPair(QObject::tr("Blue"), TPixel::Blue); + filterColors[TXshColumn::FilterDarkYellow] = + QPair(QObject::tr("DarkYellow"), TPixel(128, 128, 0)); + filterColors[TXshColumn::FilterDarkCyan] = + QPair(QObject::tr("DarkCyan"), TPixel(0, 128, 128)); + filterColors[TXshColumn::FilterDarkMagenta] = + QPair(QObject::tr("DarkMagenta"), TPixel(128, 0, 128)); + _firstTime = false; +} + +//----------------------------------------------------------------------------- + +TPixel32 TXshColumn::getFilterColor() { + return TXshColumn::getFilterInfo(m_filterColorId).second; +} + +//----------------------------------------------------------------------------- + +QPair TXshColumn::getFilterInfo( + TXshColumn::FilterColor key) { + TXshColumn::initColorFilters(); + if (!filterColors.contains(key)) + return QPair(QObject::tr("None"), TPixel::Black); + return filterColors.value(key); +} \ No newline at end of file diff --git a/toonz/sources/toonzlib/txshlevelcolumn.cpp b/toonz/sources/toonzlib/txshlevelcolumn.cpp index 98dba0a..a6aeec2 100644 --- a/toonz/sources/toonzlib/txshlevelcolumn.cpp +++ b/toonz/sources/toonzlib/txshlevelcolumn.cpp @@ -116,7 +116,7 @@ void TXshLevelColumn::loadData(TIStream &is) { } else if (tagName == "filter_color_id") { int id; is >> id; - setFilterColorId(id); + setFilterColorId((TXshColumn::FilterColor)id); } else if (tagName == "cells") { while (is.openChild(tagName)) { if (tagName == "cell") { diff --git a/toonz/sources/translations/japanese/toonz.ts b/toonz/sources/translations/japanese/toonz.ts index a0549e0..9ff1a70 100644 --- a/toonz/sources/translations/japanese/toonz.ts +++ b/toonz/sources/translations/japanese/toonz.ts @@ -9442,6 +9442,10 @@ Please commit or revert changes first. Start Frame: 開始フレーム: + + Enable Column Color Filter and Transparency for Rendering + 列のメインビューア表示の不透明度とカラーフィルタの設定をレンダリングにも用いる + SceneViewerContextMenu @@ -10761,35 +10765,35 @@ Please refer to the user guide for details. XsheetGUI::ColumnTransparencyPopup None - なし + なし Red - + Green - + Blue - + DarkYellow - 暗い黄色 + 暗い黄色 DarkCyan - 暗いシアン + 暗いシアン DarkMagenta - 暗いマゼンタ + 暗いマゼンタ N.B. Filter doesn't affect vector levels - ※ カラーフィルタはベクターレベルには適用されません + ※ カラーフィルタはベクターレベルには適用されません Filter: diff --git a/toonz/sources/translations/japanese/toonzlib.ts b/toonz/sources/translations/japanese/toonzlib.ts index 561a255..661e72f 100644 --- a/toonz/sources/translations/japanese/toonzlib.ts +++ b/toonz/sources/translations/japanese/toonzlib.ts @@ -352,6 +352,34 @@ Can't save 保存できません : + + None + なし + + + Red + + + + Green + + + + Blue + + + + DarkYellow + 暗い黄色 + + + DarkCyan + 暗いシアン + + + DarkMagenta + 暗いマゼンタ + TScriptBinding::CenterlineVectorizer