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/filefield.h b/toonz/sources/include/toonzqt/filefield.h index f5a65f8..944f2d1 100644 --- a/toonz/sources/include/toonzqt/filefield.h +++ b/toonz/sources/include/toonzqt/filefield.h @@ -53,6 +53,8 @@ class DVAPI FileField : public QWidget { QStringList m_filters; QFileDialog::FileMode m_fileMode; QString m_windowTitle; + QString m_descriptionText; // if the initial text is not path, set the string + // here and prevent browsing protected: // used in the child class for CleanupSettings QPushButton *m_fileBrowseButton; @@ -73,7 +75,7 @@ public: static BrowserPopupController *m_browserPopupController; FileField(QWidget *parent = 0, QString path = QString(), - bool readOnly = false); + bool readOnly = false, bool doNotBrowseInitialPath = false); ~FileField() {} /*! Set what the user may select in the file dialog: 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..7ed582e 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); } @@ -522,7 +529,7 @@ QFrame *ConvertPopup::createTlvSettings() { m_tlvMode = new QComboBox(); m_unpaintedFolderLabel = new QLabel(tr("Unpainted File Folder:")); m_unpaintedFolder = - new DVGui::FileField(0, QString(tr("Same as Painted")), true); + new DVGui::FileField(0, QString(tr("Same as Painted")), true, true); m_suffixLabel = new QLabel(tr(" Unpainted File Suffix:")); m_unpaintedSuffix = new DVGui::LineEdit("_np"); m_applyAutoclose = new QCheckBox(tr("Apply Autoclose")); @@ -531,8 +538,12 @@ QFrame *ConvertPopup::createTlvSettings() { m_appendDefaultPalette = new QCheckBox(tr("Append Default Palette")); m_antialias = new QComboBox(); m_antialiasIntensity = new DVGui::IntLineEdit(0, 50, 0, 100); - m_palettePath = new DVGui::FileField(0, QString(CreateNewPalette), true); - m_tolerance = new DVGui::IntLineEdit(0, 0, 0, 255); + m_palettePath = + new DVGui::FileField(0, QString(CreateNewPalette), true, 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); @@ -585,8 +596,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 +609,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 +667,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 +1077,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 +1195,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/filefield.cpp b/toonz/sources/toonzqt/filefield.cpp index 3a32da2..1832f08 100644 --- a/toonz/sources/toonzqt/filefield.cpp +++ b/toonz/sources/toonzqt/filefield.cpp @@ -18,7 +18,8 @@ FileField::BrowserPopupController *FileField::m_browserPopupController = 0; // FileField //----------------------------------------------------------------------------- -FileField::FileField(QWidget *parent, QString path, bool readOnly) +FileField::FileField(QWidget *parent, QString path, bool readOnly, + bool doNotBrowseInitialPath) : QWidget(parent) , m_filters(QStringList()) , m_fileMode(QFileDialog::DirectoryOnly) @@ -33,6 +34,9 @@ FileField::FileField(QWidget *parent, QString path, bool readOnly) m_fileBrowseButton->setMinimumSize(20, WidgetHeight); m_fileBrowseButton->setObjectName("PushButton_NoPadding"); + // if the initial text is not path, set the string here and prevent browsing + if (doNotBrowseInitialPath) m_descriptionText = path; + QHBoxLayout *mainLayout = new QHBoxLayout(); mainLayout->setMargin(0); mainLayout->setSpacing(1); @@ -90,7 +94,7 @@ void FileField::browseDirectory() { if (!m_browserPopupController) return; m_browserPopupController->openPopup( m_filters, (m_fileMode == QFileDialog::DirectoryOnly), - m_lastSelectedPath); + (m_lastSelectedPath == m_descriptionText) ? "" : m_lastSelectedPath); if (m_browserPopupController->isExecute()) directory = m_browserPopupController->getPath(); 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());