diff --git a/toonz/sources/include/toonz/Naa2TlvConverter.h b/toonz/sources/include/toonz/Naa2TlvConverter.h index efe5765..e15fd38 100644 --- a/toonz/sources/include/toonz/Naa2TlvConverter.h +++ b/toonz/sources/include/toonz/Naa2TlvConverter.h @@ -146,7 +146,8 @@ public: return -1; } - TToonzImageP makeTlv(bool transparentSyntheticInks); + TToonzImageP makeTlv(bool transparentSyntheticInks, + bool removeUnusedStyles = false); TVectorImageP vectorize(const TToonzImageP &ti); TVectorImageP vectorize(const TRaster32P &ras); diff --git a/toonz/sources/include/toonzqt/imageutils.h b/toonz/sources/include/toonzqt/imageutils.h index 357706d..6c73ebe 100644 --- a/toonz/sources/include/toonzqt/imageutils.h +++ b/toonz/sources/include/toonzqt/imageutils.h @@ -111,8 +111,10 @@ void DVAPI convertNaa2Tlv( FrameTaskNotifier *frameNotifier, //!< Observer class for frame success notifications. TPalette *palette = - 0); //!< Special conversion function from an antialiased level to tlv. - //! \sa Function ImageUtils::convert(). + 0, //!< Special conversion function from an antialiased level to tlv. + //! \sa Function ImageUtils::convert(). + bool removeUnusedStyles = + false); //! Remove unused styles from input palette. double DVAPI getQuantizedZoomFactor(double zf, bool forward); diff --git a/toonz/sources/toonz/convertpopup.cpp b/toonz/sources/toonz/convertpopup.cpp index 97ac0e6..30c184e 100644 --- a/toonz/sources/toonz/convertpopup.cpp +++ b/toonz/sources/toonz/convertpopup.cpp @@ -55,6 +55,8 @@ TEnv::IntVar ConvertPopupRemoveDot("ConvertPopupRemoveDot", 1); TEnv::IntVar ConvertPopupSaveToNopaint("ConvertPopupSaveToNopaint", 1); TEnv::IntVar ConvertPopupAppendDefaultPalette( "ConvertPopupAppendDefaultPalette", 0); +TEnv::IntVar ConvertPopupRemoveUnusedStyles("ConvertPopupRemoveUnusedStyles", + 0); //============================================================================= // convertPopup @@ -200,7 +202,8 @@ void ConvertPopup::Converter::convertLevel( // no AA source (retas) TPaletteP palette = popup->readUserProvidedPalette(); ImageUtils::convertNaa2Tlv(sourceFileFullPath, dstFileFullPath, from, to, - m_parent->m_notifier, palette.getPointer()); + m_parent->m_notifier, palette.getPointer(), + m_parent->m_removeUnusedStyles->isChecked()); } else { convertLevelWithConvert2Tlv(sourceFileFullPath); } @@ -441,6 +444,7 @@ ConvertPopup::ConvertPopup(bool specifyInput) m_removeDotBeforeFrameNumber->setChecked(ConvertPopupRemoveDot != 0); m_saveBackupToNopaint->setChecked(ConvertPopupSaveToNopaint != 0); m_appendDefaultPalette->setChecked(ConvertPopupAppendDefaultPalette != 0); + m_removeUnusedStyles->setChecked(ConvertPopupRemoveUnusedStyles != 0); //--- signal-slot connections qRegisterMetaType("TFilePath"); @@ -470,6 +474,9 @@ ConvertPopup::ConvertPopup(bool specifyInput) ret = ret && connect(m_convertFileFld, SIGNAL(pathChanged()), this, SLOT(onFileInChanged())); + // update unable/enable of checkboxes + onTlvModeSelected(m_tlvMode->currentText()); + assert(ret); } @@ -534,6 +541,9 @@ QFrame *ConvertPopup::createTlvSettings() { m_palettePath = new DVGui::FileField(0, QString(CreateNewPalette), true); m_tolerance = new DVGui::IntLineEdit(0, 0, 0, 255); + m_removeUnusedStyles = + new QCheckBox(tr("Remove Unused Styles from Input Palette")); + m_unpaintedFolder->setFileMode(QFileDialog::DirectoryOnly); m_unpaintedSuffix->setMaximumWidth(40); QStringList items1; @@ -585,8 +595,9 @@ QFrame *ConvertPopup::createTlvSettings() { Qt::AlignRight | Qt::AlignVCenter); gridLay->addWidget(m_tolerance, 4, 3); - gridLay->addWidget(m_appendDefaultPalette, 5, 1, 1, 3); - gridLay->addWidget(m_saveBackupToNopaint, 6, 1, 1, 3); + gridLay->addWidget(m_removeUnusedStyles, 5, 1, 1, 3); + gridLay->addWidget(m_appendDefaultPalette, 6, 1, 1, 3); + gridLay->addWidget(m_saveBackupToNopaint, 7, 1, 1, 3); } gridLay->setColumnStretch(0, 0); gridLay->setColumnStretch(1, 1); @@ -597,6 +608,9 @@ QFrame *ConvertPopup::createTlvSettings() { bool ret = true; ret = ret && connect(m_antialias, SIGNAL(currentIndexChanged(int)), this, SLOT(onAntialiasSelected(int))); + ret = ret && connect(m_palettePath, SIGNAL(pathChanged()), this, + SLOT(onPalettePathChanged())); + assert(ret); frame->setVisible(false); @@ -652,8 +666,13 @@ void ConvertPopup::onTlvModeSelected(const QString &tlvMode) { m_suffixLabel->setEnabled(usesTwoImages); m_unpaintedSuffix->setEnabled(usesTwoImages); m_antialias->setEnabled(TlvMode_PaintedFromNonAA != tlvMode); - m_palettePath->setEnabled(TlvMode_PaintedFromNonAA != tlvMode); + // m_palettePath->setEnabled(TlvMode_PaintedFromNonAA != tlvMode); m_tolerance->setEnabled(TlvMode_PaintedFromNonAA != tlvMode); + m_appendDefaultPalette->setEnabled(TlvMode_PaintedFromNonAA != tlvMode); + + m_removeUnusedStyles->setEnabled(TlvMode_PaintedFromNonAA == tlvMode && + m_palettePath->getPath() != + CreateNewPalette); m_saveBackupToNopaint->setEnabled(TlvMode_Unpainted == tlvMode); } @@ -1057,6 +1076,7 @@ void ConvertPopup::apply() { ConvertPopupSaveToNopaint = m_saveBackupToNopaint->isChecked() ? 1 : 0; ConvertPopupAppendDefaultPalette = m_appendDefaultPalette->isChecked() ? 1 : 0; + ConvertPopupRemoveUnusedStyles = m_removeUnusedStyles->isChecked() ? 1 : 0; // parameters are ok: close the dialog first close(); @@ -1174,6 +1194,14 @@ void ConvertPopup::onFormatChanged(const QString &ext) { //------------------------------------------------------------------- +void ConvertPopup::onPalettePathChanged() { + m_removeUnusedStyles->setEnabled( + m_tlvMode->currentText() == TlvMode_PaintedFromNonAA && + m_palettePath->getPath() != CreateNewPalette); +} + +//------------------------------------------------------------------- + bool ConvertPopup::isSaveTlvBackupToNopaintActive() { return m_fileFormat->currentText() == TlvExtension /*-- tlvが選択されている --*/ diff --git a/toonz/sources/toonz/convertpopup.h b/toonz/sources/toonz/convertpopup.h index cc4ff5a..b779a07 100644 --- a/toonz/sources/toonz/convertpopup.h +++ b/toonz/sources/toonz/convertpopup.h @@ -87,6 +87,7 @@ public slots: void onLevelConverted(const TFilePath &fullPath); void onFormatChanged(const QString &); + void onPalettePathChanged(); protected: Convert2Tlv *makeTlvConverter(const TFilePath &sourceFilePath); @@ -104,7 +105,7 @@ private: DVGui::ColorField *m_bgColorField; QFrame *m_tlvFrame; QCheckBox *m_applyAutoclose, *m_removeDotBeforeFrameNumber, - *m_saveBackupToNopaint, *m_appendDefaultPalette; + *m_saveBackupToNopaint, *m_appendDefaultPalette, *m_removeUnusedStyles; DVGui::CheckBox *m_skip; QComboBox *m_antialias, *m_tlvMode, *m_fileFormat; QLabel *m_bgColorLabel, *m_suffixLabel, *m_unpaintedFolderLabel, diff --git a/toonz/sources/toonzlib/Naa2TlvConverter.cpp b/toonz/sources/toonzlib/Naa2TlvConverter.cpp index f740f7b..d0a5e6e 100644 --- a/toonz/sources/toonzlib/Naa2TlvConverter.cpp +++ b/toonz/sources/toonzlib/Naa2TlvConverter.cpp @@ -1005,7 +1005,8 @@ int Naa2TlvConverter::measureThickness(int x0, int y0) { //----------------------------------------------------------------------------- -TToonzImageP Naa2TlvConverter::makeTlv(bool transparentSyntheticInks) { +TToonzImageP Naa2TlvConverter::makeTlv(bool transparentSyntheticInks, + bool removeUnusedStyles) { if (!m_valid || m_colors.empty() || m_regions.empty() || !m_regionRas) return TToonzImageP(); int lx = m_regionRas->getLx(); @@ -1025,8 +1026,9 @@ TToonzImageP Naa2TlvConverter::makeTlv(bool transparentSyntheticInks) { if (cs->getMainColor() != color) cs = 0; } if (cs == 0) { - styleId = palette->getPage(0)->addStyle(color); - cs = palette->getStyle(styleId); + styleId = palette->addStyle(color); + palette->getPage(0)->addStyle(styleId); + cs = palette->getStyle(styleId); } styleIds.append(styleId); } @@ -1035,6 +1037,21 @@ TToonzImageP Naa2TlvConverter::makeTlv(bool transparentSyntheticInks) { // int synteticInkStyleId = palette->getPage(0)->addStyle(TPixel32(0,0,0,0)); // styleIds.append(synteticInkStyleId); + // Remove unused styles from input palette + if (removeUnusedStyles) { + for (int p = palette->getPageCount() - 1; p >= 0; p--) { + TPalette::Page *page = palette->getPage(p); + for (int s = page->getStyleCount() - 1; s >= 0; s--) { + int styleId = page->getStyleId(s); + if (styleId == -1) continue; + // check if the style is used or not + if (!styleIds.contains(styleId)) page->removeStyle(s); + } + // erase empty page + if (page->getStyleCount() == 0) palette->erasePage(p); + } + } + for (int y = 0; y < ly; y++) { unsigned short *workScanLine = m_regionRas->pixels(y); TPixelCM32 *outScanLine = ras->pixels(y); diff --git a/toonz/sources/toonzqt/imageutils.cpp b/toonz/sources/toonzqt/imageutils.cpp index 24fcf11..06b67b6 100644 --- a/toonz/sources/toonzqt/imageutils.cpp +++ b/toonz/sources/toonzqt/imageutils.cpp @@ -632,7 +632,8 @@ void convert(const TFilePath &source, const TFilePath &dest, void convertNaa2Tlv(const TFilePath &source, const TFilePath &dest, const TFrameId &from, const TFrameId &to, - FrameTaskNotifier *frameNotifier, TPalette *palette) { + FrameTaskNotifier *frameNotifier, TPalette *palette, + bool removeUnusedStyles) { std::string dstExt = dest.getType(), srcExt = source.getType(); // Load source level structure @@ -671,8 +672,8 @@ void convertNaa2Tlv(const TFilePath &source, const TFilePath &dest, converter.process(raster); - if (TToonzImageP dstImg = - converter.makeTlv(false)) // Opaque synthetic inks + if (TToonzImageP dstImg = converter.makeTlv( + false, removeUnusedStyles)) // Opaque synthetic inks { if (converter.getPalette() == 0) converter.setPalette(dstImg->getPalette());