diff --git a/toonz/sources/tnztools/toonzrasterbrushtool.cpp b/toonz/sources/tnztools/toonzrasterbrushtool.cpp index 80060b4..b985c74 100644 --- a/toonz/sources/tnztools/toonzrasterbrushtool.cpp +++ b/toonz/sources/tnztools/toonzrasterbrushtool.cpp @@ -56,6 +56,7 @@ TEnv::IntVar BrushPressureSensitivity("InknpaintBrushPressureSensitivity", 1); TEnv::DoubleVar RasterBrushHardness("RasterBrushHardness", 100); TEnv::DoubleVar RasterBrushModifierSize("RasterBrushModifierSize", 0); TEnv::StringVar RasterBrushPreset("RasterBrushPreset", ""); +TEnv::IntVar BrushLockAlpha("InknpaintBrushLockAlpha", 0); //------------------------------------------------------------------- #define CUSTOM_WSTR L"" @@ -436,26 +437,28 @@ class RasterBrushUndo final : public TRasterUndo { bool m_selective; bool m_isPaletteOrder; bool m_isPencil; + bool m_modifierLockAlpha; public: RasterBrushUndo(TTileSetCM32 *tileSet, const std::vector &points, int styleId, bool selective, TXshSimpleLevel *level, const TFrameId &frameId, bool isPencil, bool isFrameCreated, - bool isLevelCreated, bool isPaletteOrder) + bool isLevelCreated, bool isPaletteOrder, bool lockAlpha) : TRasterUndo(tileSet, level, frameId, isFrameCreated, isLevelCreated, 0) , m_points(points) , m_styleId(styleId) , m_selective(selective) , m_isPencil(isPencil) - , m_isPaletteOrder(isPaletteOrder) {} + , m_isPaletteOrder(isPaletteOrder) + , m_modifierLockAlpha(lockAlpha) {} void redo() const override { insertLevelAndFrameIfNeeded(); TToonzImageP image = getImage(); TRasterCM32P ras = image->getRaster(); - RasterStrokeGenerator m_rasterTrack(ras, BRUSH, NONE, m_styleId, - m_points[0], m_selective, 0, false, - !m_isPencil, m_isPaletteOrder); + RasterStrokeGenerator m_rasterTrack( + ras, BRUSH, NONE, m_styleId, m_points[0], m_selective, 0, + m_modifierLockAlpha, !m_isPencil, m_isPaletteOrder); if (m_isPaletteOrder) { QSet aboveStyleIds; getAboveStyleIdSet(m_styleId, image->getPalette(), aboveStyleIds); @@ -864,7 +867,8 @@ ToonzRasterBrushTool::ToonzRasterBrushTool(std::string name, int targetType) , m_presetsLoaded(false) , m_targetType(targetType) , m_workingFrameId(TFrameId()) - , m_notifier(0) { + , m_notifier(0) + , m_modifierLockAlpha("Lock Alpha", false) { bind(targetType); m_rasThickness.setNonLinearSlider(); @@ -874,6 +878,7 @@ ToonzRasterBrushTool::ToonzRasterBrushTool(std::string name, int targetType) m_prop[0].bind(m_smooth); m_prop[0].bind(m_drawOrder); m_prop[0].bind(m_modifierSize); + m_prop[0].bind(m_modifierLockAlpha); m_prop[0].bind(m_pencil); m_pencil.setId("PencilMode"); @@ -888,6 +893,7 @@ ToonzRasterBrushTool::ToonzRasterBrushTool(std::string name, int targetType) m_preset.setId("BrushPreset"); m_preset.addValue(CUSTOM_WSTR); m_pressure.setId("PressureSensitivity"); + m_modifierLockAlpha.setId("LockAlpha"); } //------------------------------------------------------------------------------------------------------- @@ -1081,6 +1087,7 @@ void ToonzRasterBrushTool::updateTranslation() { m_preset.setItemUIName(CUSTOM_WSTR, tr("")); m_pencil.setQStringName(tr("Pencil")); m_pressure.setQStringName(tr("Pressure")); + m_modifierLockAlpha.setQStringName(tr("Lock Alpha")); } //--------------------------------------------------------------------------------------------------- @@ -1341,7 +1348,8 @@ void ToonzRasterBrushTool::leftButtonDown(const TPointD &pos, thickness); m_rasterTrack = new RasterStrokeGenerator( ras, BRUSH, NONE, m_styleId, thickPoint, drawOrder != OverAll, 0, - false, !m_pencil.getValue(), drawOrder == PaletteOrder); + m_modifierLockAlpha.getValue(), !m_pencil.getValue(), + drawOrder == PaletteOrder); if (drawOrder == PaletteOrder) m_rasterTrack->setAboveStyleIds(aboveStyleIds); @@ -1651,7 +1659,8 @@ void ToonzRasterBrushTool::finishRasterBrush(const TPointD &pos, m_tileSet, m_rasterTrack->getPointsSequence(), m_rasterTrack->getStyleId(), m_rasterTrack->isSelective(), simLevel.getPointer(), frameId, m_pencil.getValue(), m_isFrameCreated, - m_isLevelCreated, m_rasterTrack->isPaletteOrder())); + m_isLevelCreated, m_rasterTrack->isPaletteOrder(), + m_rasterTrack->isAlphaLocked())); } delete m_rasterTrack; m_rasterTrack = 0; @@ -1992,6 +2001,7 @@ bool ToonzRasterBrushTool::onPropertyChanged(std::string propertyName) { BrushPressureSensitivity = m_pressure.getValue(); RasterBrushHardness = m_hardness.getValue(); RasterBrushModifierSize = m_modifierSize.getValue(); + BrushLockAlpha = m_modifierLockAlpha.getValue(); // Recalculate/reset based on changed settings if (propertyName == m_rasThickness.getName()) { @@ -2062,6 +2072,7 @@ void ToonzRasterBrushTool::loadPreset() { m_pencil.setValue(preset.m_pencil); m_pressure.setValue(preset.m_pressure); m_modifierSize.setValue(preset.m_modifierSize); + m_modifierLockAlpha.setValue(preset.m_modifierLockAlpha); // Recalculate based on updated presets m_minThick = m_rasThickness.getValue().first; @@ -2083,12 +2094,13 @@ void ToonzRasterBrushTool::addPreset(QString name) { preset.m_min = m_rasThickness.getValue().first; preset.m_max = m_rasThickness.getValue().second; - preset.m_smooth = m_smooth.getValue(); - preset.m_hardness = m_hardness.getValue(); - preset.m_drawOrder = m_drawOrder.getIndex(); - preset.m_pencil = m_pencil.getValue(); - preset.m_pressure = m_pressure.getValue(); - preset.m_modifierSize = m_modifierSize.getValue(); + preset.m_smooth = m_smooth.getValue(); + preset.m_hardness = m_hardness.getValue(); + preset.m_drawOrder = m_drawOrder.getIndex(); + preset.m_pencil = m_pencil.getValue(); + preset.m_pressure = m_pressure.getValue(); + preset.m_modifierSize = m_modifierSize.getValue(); + preset.m_modifierLockAlpha = m_modifierLockAlpha.getValue(); // Pass the preset to the manager m_presetsManager.addPreset(preset); @@ -2126,6 +2138,7 @@ void ToonzRasterBrushTool::loadLastBrush() { m_pressure.setValue(BrushPressureSensitivity ? 1 : 0); m_smooth.setValue(BrushSmooth); m_modifierSize.setValue(RasterBrushModifierSize); + m_modifierLockAlpha.setValue(BrushLockAlpha ? 1 : 0); // Recalculate based on prior values m_minThick = m_rasThickness.getValue().first; diff --git a/toonz/sources/tnztools/toonzrasterbrushtool.h b/toonz/sources/tnztools/toonzrasterbrushtool.h index 2dfab81..eeaf0b2 100644 --- a/toonz/sources/tnztools/toonzrasterbrushtool.h +++ b/toonz/sources/tnztools/toonzrasterbrushtool.h @@ -182,6 +182,7 @@ protected: TBoolProperty m_pencil; TBoolProperty m_pressure; TDoubleProperty m_modifierSize; + TBoolProperty m_modifierLockAlpha; RasterStrokeGenerator *m_rasterTrack; TTileSetCM32 *m_tileSet; diff --git a/toonz/sources/toonzlib/rasterstrokegenerator.cpp b/toonz/sources/toonzlib/rasterstrokegenerator.cpp index ff62bc4..393d5df 100644 --- a/toonz/sources/toonzlib/rasterstrokegenerator.cpp +++ b/toonz/sources/toonzlib/rasterstrokegenerator.cpp @@ -189,10 +189,15 @@ void RasterStrokeGenerator::placeOver(const TRasterCM32P &out, if (m_task == BRUSH) { int inTone = inPix->getTone(); int outTone = outPix->getTone(); - if (inPix->isPureInk() && !m_selective) { + if (inPix->isPureInk() && !m_selective && !m_modifierLockAlpha) { *outPix = TPixelCM32(inPix->getInk(), outPix->getPaint(), inTone); continue; } + if (m_modifierLockAlpha && !outPix->isPureInk() && + outPix->getPaint() == 0 && outPix->getTone() == 255) { + *outPix = TPixelCM32(outPix->getInk(), outPix->getPaint(), outTone); + continue; + } if (outPix->isPureInk() && m_selective) { if (!m_isPaletteOrder || m_aboveStyleIds.contains(outPix->getInk())) { *outPix = TPixelCM32(outPix->getInk(), outPix->getPaint(), outTone);