diff --git a/toonz/sources/include/tools/tooloptions.h b/toonz/sources/include/tools/tooloptions.h index 7544f131..c2be6cf1 100644 --- a/toonz/sources/include/tools/tooloptions.h +++ b/toonz/sources/include/tools/tooloptions.h @@ -459,6 +459,7 @@ class PaintbrushToolOptionsBox final : public ToolOptionsBox { ToolOptionCombo *m_colorMode; ToolOptionCheckbox *m_selectiveMode; + ToolOptionCheckbox *m_lockAlphaMode; public: PaintbrushToolOptionsBox(QWidget *parent, TTool *tool, diff --git a/toonz/sources/include/toonz/rasterstrokegenerator.h b/toonz/sources/include/toonz/rasterstrokegenerator.h index 4da1b7ba..e2c7857f 100644 --- a/toonz/sources/include/toonz/rasterstrokegenerator.h +++ b/toonz/sources/include/toonz/rasterstrokegenerator.h @@ -37,6 +37,7 @@ class DVAPI RasterStrokeGenerator { bool m_doAnArc; bool m_isPaletteOrder; // Used in the Draw Order option of Brush Tool, // use style order to define line stacking order + bool m_modifierLockAlpha; QSet m_aboveStyleIds; // Ricalcola i punti in un nuovo sistema di riferimento @@ -50,13 +51,14 @@ class DVAPI RasterStrokeGenerator { public: RasterStrokeGenerator(const TRasterCM32P &raster, Tasks task, ColorType colorType, int styleId, const TThickPoint &p, - bool selective, int selectedStyle, bool keepAntialias, - bool isPaletteOrder = false); + bool selective, int selectedStyle, bool lockAlpha, + bool keepAntialias, bool isPaletteOrder = false); ~RasterStrokeGenerator(); void setRaster(const TRasterCM32P &ras) { m_raster = ras; } void setStyle(int styleId) { m_styleId = styleId; } int getStyleId() const { return m_styleId; } bool isSelective() { return m_selective; } + bool isAlphaLocked() { return m_modifierLockAlpha; } bool isPaletteOrder() { return m_isPaletteOrder; } void setAboveStyleIds(QSet &ids) { m_aboveStyleIds = ids; } diff --git a/toonz/sources/tnztools/fingertool.cpp b/toonz/sources/tnztools/fingertool.cpp index 38fae90a..8a975d3c 100644 --- a/toonz/sources/tnztools/fingertool.cpp +++ b/toonz/sources/tnztools/fingertool.cpp @@ -75,7 +75,7 @@ public: TToonzImageP image = m_level->getFrame(m_frameId, true); TRasterCM32P ras = image->getRaster(); RasterStrokeGenerator m_rasterTrack(ras, FINGER, INK, m_styleId, - m_points[0], m_invert, 0, false); + m_points[0], m_invert, 0, false, false); m_rasterTrack.setPointsSequence(m_points); m_rasterTrack.generateStroke(true); image->setSavebox(image->getSavebox() + @@ -409,7 +409,7 @@ void FingerTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) { m_rasterTrack = new RasterStrokeGenerator( ras, FINGER, INK, styleId, TThickPoint(pos + convert(ras->getCenter()), thickness), - m_invert.getValue(), 0, false); + m_invert.getValue(), 0, false, false); /*-- 作業中Fidを現在のFIDにする --*/ m_workingFrameId = getFrameId(); diff --git a/toonz/sources/tnztools/paintbrushtool.cpp b/toonz/sources/tnztools/paintbrushtool.cpp index 4799e6e8..6ba41576 100644 --- a/toonz/sources/tnztools/paintbrushtool.cpp +++ b/toonz/sources/tnztools/paintbrushtool.cpp @@ -47,6 +47,7 @@ using namespace ToolUtils; TEnv::StringVar PaintBrushColorType("InknpaintPaintBrushColorType", "Areas"); TEnv::IntVar PaintBrushSelective("InknpaintPaintBrushSelective", 0); TEnv::DoubleVar PaintBrushSize("InknpaintPaintBrushSize", 10); +TEnv::IntVar PaintBrushModifierLockAlpha("PaintBrushModifierLockAlpha", 0); //----------------------------------------------------------------------------- @@ -61,22 +62,25 @@ class BrushUndo final : public TRasterUndo { int m_styleId; bool m_selective; ColorType m_colorType; + bool m_modifierLockAlpha; public: BrushUndo(TTileSetCM32 *tileSet, const std::vector &points, ColorType colorType, int styleId, bool selective, - TXshSimpleLevel *level, const TFrameId &frameId) + TXshSimpleLevel *level, const TFrameId &frameId, bool lockAlpha) : TRasterUndo(tileSet, level, frameId, false, false, 0) , m_points(points) , m_styleId(styleId) , m_selective(selective) - , m_colorType(colorType) {} + , m_colorType(colorType) + , m_modifierLockAlpha(lockAlpha) {} void redo() const override { TToonzImageP image = m_level->getFrame(m_frameId, true); TRasterCM32P ras = image->getRaster(); RasterStrokeGenerator m_rasterTrack(ras, PAINTBRUSH, m_colorType, m_styleId, - m_points[0], m_selective, 0, false); + m_points[0], m_selective, 0, + m_modifierLockAlpha, false); m_rasterTrack.setPointsSequence(m_points); m_rasterTrack.generateStroke(true); image->setSavebox(image->getSavebox() + @@ -266,6 +270,8 @@ class PaintBrushTool final : public TTool { 移動している場合に備える --*/ TFrameId m_workingFrameId; + TBoolProperty m_modifierLockAlpha; + public: PaintBrushTool(); @@ -324,7 +330,8 @@ PaintBrushTool::PaintBrushTool() , m_colorType("Mode:") // W_ToolOptions_InkOrPaint , m_onlyEmptyAreas("Selective", false) // W_ToolOptions_Selective , m_firstTime(true) - , m_workingFrameId(TFrameId()) { + , m_workingFrameId(TFrameId()) + , m_modifierLockAlpha("Lock Alpha", false) { m_toolSize.setNonLinearSlider(); m_colorType.addValue(LINES); @@ -336,9 +343,11 @@ PaintBrushTool::PaintBrushTool() m_prop.bind(m_toolSize); m_prop.bind(m_colorType); m_prop.bind(m_onlyEmptyAreas); + m_prop.bind(m_modifierLockAlpha); m_onlyEmptyAreas.setId("Selective"); m_colorType.setId("Mode"); + m_modifierLockAlpha.setId("LockAlpha"); } //----------------------------------------------------------------------------- @@ -352,6 +361,7 @@ void PaintBrushTool::updateTranslation() { m_colorType.setItemUIName(ALL, tr("Lines & Areas")); m_onlyEmptyAreas.setQStringName(tr("Selective", NULL)); + m_modifierLockAlpha.setQStringName(tr("Lock Alpha")); } //------------------------------------------------------------------------------------------------------- @@ -435,6 +445,8 @@ bool PaintBrushTool::onPropertyChanged(std::string propertyName) { // Selective else if (propertyName == m_onlyEmptyAreas.getName()) { PaintBrushSelective = (int)(m_onlyEmptyAreas.getValue()); + if (m_onlyEmptyAreas.getValue() && m_modifierLockAlpha.getValue()) + m_modifierLockAlpha.setValue(false); } // Areas, Lines etc. @@ -444,6 +456,12 @@ bool PaintBrushTool::onPropertyChanged(std::string propertyName) { TTool::getApplication()->getCurrentTool()->notifyToolChanged(); } + // Lock Alpha + else if (propertyName == m_modifierLockAlpha.getName()) { + PaintBrushModifierLockAlpha = (int)(m_modifierLockAlpha.getValue()); + if (m_modifierLockAlpha.getValue() && m_onlyEmptyAreas.getValue()) + m_onlyEmptyAreas.setValue(false); + } return true; } @@ -467,7 +485,8 @@ void PaintBrushTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) { m_rasterTrack = new RasterStrokeGenerator( ras, PAINTBRUSH, m_colorTypeBrush, styleId, TThickPoint(m_mousePos + convert(ras->getCenter()), thickness), - m_onlyEmptyAreas.getValue(), 0, false); + m_onlyEmptyAreas.getValue(), 0, m_modifierLockAlpha.getValue(), + false); /*-- 現在のFidを記憶 --*/ m_workingFrameId = getFrameId(); m_tileSaver->save(m_rasterTrack->getLastRect()); @@ -522,6 +541,7 @@ void PaintBrushTool::onEnter() { m_onlyEmptyAreas.setValue(PaintBrushSelective ? 1 : 0); m_colorType.setValue(::to_wstring(PaintBrushColorType.getValue())); m_toolSize.setValue(PaintBrushSize); + m_modifierLockAlpha.setValue(PaintBrushModifierLockAlpha ? 1 : 0); m_firstTime = false; } double x = m_toolSize.getValue(); @@ -581,7 +601,8 @@ void PaintBrushTool::finishBrush() { TUndoManager::manager()->add(new BrushUndo( m_tileSaver->getTileSet(), m_rasterTrack->getPointsSequence(), m_colorTypeBrush, m_rasterTrack->getStyleId(), - m_rasterTrack->isSelective(), simLevel.getPointer(), frameId)); + m_rasterTrack->isSelective(), simLevel.getPointer(), frameId, + m_rasterTrack->isAlphaLocked())); ToolUtils::updateSaveBox(); /*--- FIdを指定して、描画中にフレームが変わっても、 diff --git a/toonz/sources/tnztools/rastererasertool.cpp b/toonz/sources/tnztools/rastererasertool.cpp index 4667c32b..bdff5c5b 100644 --- a/toonz/sources/tnztools/rastererasertool.cpp +++ b/toonz/sources/tnztools/rastererasertool.cpp @@ -180,7 +180,7 @@ public: TToonzImageP image = m_level->getFrame(m_frameId, true); TRasterCM32P ras = image->getRaster(); RasterStrokeGenerator m_rasterTrack(ras, ERASE, m_colorType, 0, m_points[0], - m_selective, m_colorSelected, + m_selective, m_colorSelected, false, !m_isPencil); m_rasterTrack.setPointsSequence(m_points); m_rasterTrack.generateStroke(m_isPencil); @@ -1079,7 +1079,7 @@ void EraserTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) { if (m_colorType.getValue() == ALL) m_colorTypeEraser = INKNPAINT; m_normalEraser = new RasterStrokeGenerator( raster, ERASE, m_colorTypeEraser, 0, intPos, - m_currentStyle.getValue(), currentStyle, + m_currentStyle.getValue(), currentStyle, false, !(m_pencil.getValue() || m_colorType.getValue() == AREAS)); m_tileSaver->save(m_normalEraser->getLastRect()); m_normalEraser->generateLastPieceOfStroke( diff --git a/toonz/sources/tnztools/tooloptions.cpp b/toonz/sources/tnztools/tooloptions.cpp index 374bffd5..84150edc 100644 --- a/toonz/sources/tnztools/tooloptions.cpp +++ b/toonz/sources/tnztools/tooloptions.cpp @@ -1494,9 +1494,13 @@ PaintbrushToolOptionsBox::PaintbrushToolOptionsBox(QWidget *parent, TTool *tool, m_colorMode = dynamic_cast(m_controls.value("Mode:")); m_selectiveMode = dynamic_cast(m_controls.value("Selective")); + m_lockAlphaMode = + dynamic_cast(m_controls.value("Lock Alpha")); - if (m_colorMode->getProperty()->getValue() == L"Lines") + if (m_colorMode->getProperty()->getValue() == L"Lines") { m_selectiveMode->setVisible(false); + m_lockAlphaMode->setVisible(false); + } bool ret = connect(m_colorMode, SIGNAL(currentIndexChanged(int)), this, SLOT(onColorModeChanged(int))); @@ -1517,6 +1521,7 @@ void PaintbrushToolOptionsBox::onColorModeChanged(int index) { const TEnumProperty::Range &range = m_colorMode->getProperty()->getRange(); bool enabled = range[index] != L"Lines"; m_selectiveMode->setVisible(enabled); + m_lockAlphaMode->setVisible(enabled); } //============================================================================= diff --git a/toonz/sources/tnztools/toonzrasterbrushtool.cpp b/toonz/sources/tnztools/toonzrasterbrushtool.cpp index 73c084db..d2a98420 100644 --- a/toonz/sources/tnztools/toonzrasterbrushtool.cpp +++ b/toonz/sources/tnztools/toonzrasterbrushtool.cpp @@ -458,7 +458,7 @@ public: TToonzImageP image = getImage(); TRasterCM32P ras = image->getRaster(); RasterStrokeGenerator m_rasterTrack(ras, BRUSH, NONE, m_styleId, - m_points[0], m_selective, 0, + m_points[0], m_selective, 0, false, !m_isPencil, m_isPaletteOrder); if (m_isPaletteOrder) { QSet aboveStyleIds; @@ -1388,7 +1388,7 @@ void ToonzRasterBrushTool::leftButtonDown(const TPointD &pos, thickness); m_rasterTrack = new RasterStrokeGenerator( ras, BRUSH, NONE, m_styleId, thickPoint, drawOrder != OverAll, 0, - !m_pencil.getValue(), drawOrder == PaletteOrder); + false, !m_pencil.getValue(), drawOrder == PaletteOrder); if (drawOrder == PaletteOrder) m_rasterTrack->setAboveStyleIds(aboveStyleIds); diff --git a/toonz/sources/toonzlib/rasterstrokegenerator.cpp b/toonz/sources/toonzlib/rasterstrokegenerator.cpp index 50c84db9..f7760054 100644 --- a/toonz/sources/toonzlib/rasterstrokegenerator.cpp +++ b/toonz/sources/toonzlib/rasterstrokegenerator.cpp @@ -9,7 +9,7 @@ RasterStrokeGenerator::RasterStrokeGenerator(const TRasterCM32P &raster, Tasks task, ColorType colorType, int styleId, const TThickPoint &p, bool selective, int selectedStyle, - bool keepAntialias, + bool lockAlpha, bool keepAntialias, bool isPaletteOrder) : m_raster(raster) , m_boxOfRaster(TRect(raster->getSize())) @@ -21,7 +21,8 @@ RasterStrokeGenerator::RasterStrokeGenerator(const TRasterCM32P &raster, , m_selectedStyle(selectedStyle) , m_keepAntiAlias(keepAntialias) , m_doAnArc(false) - , m_isPaletteOrder(isPaletteOrder) { + , m_isPaletteOrder(isPaletteOrder) + , m_modifierLockAlpha(lockAlpha) { TThickPoint pp = p; m_points.push_back(pp); if (task == ERASE) m_styleId = m_eraseStyle; @@ -253,8 +254,10 @@ void RasterStrokeGenerator::placeOver(const TRasterCM32P &out, } } else if (m_task == PAINTBRUSH) { if (!inPix->isPureInk()) continue; - bool changePaint = - !m_selective || (m_selective && outPix->getPaint() == 0); + int paintIdx = outPix->getPaint(); + bool changePaint = (!m_selective && !m_modifierLockAlpha) || + (m_selective && paintIdx == 0) || + (m_modifierLockAlpha && paintIdx != 0); if (m_colorType == INK) *outPix = TPixelCM32(inPix->getInk(), outPix->getPaint(), outPix->getTone());