New option for Toonz Raster Brush Tool : Draw Order - Palette Order (#1849)
* style order option for toonz raster brush * change text to "draw order"
This commit is contained in:
parent
133733bb6c
commit
975eb1fa6f
7 changed files with 150 additions and 58 deletions
|
@ -4,6 +4,7 @@
|
|||
#include "ttilesaver.h"
|
||||
#include "tstopwatch.h"
|
||||
#include <fstream>
|
||||
#include <QSet>
|
||||
#undef DVAPI
|
||||
#undef DVVAR
|
||||
#ifdef TOONZLIB_EXPORTS
|
||||
|
@ -34,6 +35,9 @@ class DVAPI RasterStrokeGenerator {
|
|||
int m_selectedStyle;
|
||||
bool m_keepAntiAlias;
|
||||
bool m_doAnArc;
|
||||
bool m_isPaletteOrder; // Used in the Draw Order option of Brush Tool,
|
||||
// use style order to define line stacking order
|
||||
QSet<int> m_aboveStyleIds;
|
||||
|
||||
// Ricalcola i punti in un nuovo sistema di riferimento
|
||||
void translatePoints(std::vector<TThickPoint> &points,
|
||||
|
@ -46,13 +50,17 @@ class DVAPI RasterStrokeGenerator {
|
|||
public:
|
||||
RasterStrokeGenerator(const TRasterCM32P &raster, Tasks task,
|
||||
ColorType colorType, int styleId, const TThickPoint &p,
|
||||
bool selective, int selectedStyle, bool keepAntialias);
|
||||
bool selective, int selectedStyle, 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 isPaletteOrder() { return m_isPaletteOrder; }
|
||||
void setAboveStyleIds(QSet<int> &ids) { m_aboveStyleIds = ids; }
|
||||
|
||||
// Inserisce un punto in "m_points"
|
||||
bool add(const TThickPoint &p);
|
||||
|
||||
|
|
|
@ -25,13 +25,13 @@ QImage rasterToQImage(const TRasterP &ras, bool premultiplied = false) {
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// drawOrderMode : 0=OverAll, 1=UnderAll, 2=PaletteOrder
|
||||
void putOnRasterCM(const TRasterCM32P &out, const TRaster32P &in, int styleId,
|
||||
bool selective) {
|
||||
int drawOrderMode, const QSet<int> &aboveStyleIds) {
|
||||
if (!out.getPointer() || !in.getPointer()) return;
|
||||
assert(out->getSize() == in->getSize());
|
||||
int x, y;
|
||||
if (!selective) {
|
||||
if (drawOrderMode == 0) { // OverAll
|
||||
for (y = 0; y < out->getLy(); y++) {
|
||||
for (x = 0; x < out->getLx(); x++) {
|
||||
#ifdef _DEBUG
|
||||
|
@ -44,16 +44,17 @@ void putOnRasterCM(const TRasterCM32P &out, const TRaster32P &in, int styleId,
|
|||
if (inPix->m == 0) continue;
|
||||
TPixelCM32 *outPix = &out->pixels(y)[x];
|
||||
bool sameStyleId = styleId == outPix->getInk();
|
||||
// line with the same style : multiply tones
|
||||
// line with different style : pick darker tone
|
||||
int tone = sameStyleId ? outPix->getTone() * (255 - inPix->m) / 255
|
||||
: outPix->getTone();
|
||||
: std::min(255 - inPix->m, outPix->getTone());
|
||||
int ink = !sameStyleId && outPix->getTone() < 255 - inPix->m
|
||||
? outPix->getInk()
|
||||
: styleId;
|
||||
*outPix =
|
||||
TPixelCM32(ink, outPix->getPaint(), std::min(255 - inPix->m, tone));
|
||||
*outPix = TPixelCM32(ink, outPix->getPaint(), tone);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (drawOrderMode == 1) { // UnderAll
|
||||
for (y = 0; y < out->getLy(); y++) {
|
||||
for (x = 0; x < out->getLx(); x++) {
|
||||
#ifdef _DEBUG
|
||||
|
@ -66,14 +67,32 @@ void putOnRasterCM(const TRasterCM32P &out, const TRaster32P &in, int styleId,
|
|||
if (inPix->m == 0) continue;
|
||||
TPixelCM32 *outPix = &out->pixels(y)[x];
|
||||
bool sameStyleId = styleId == outPix->getInk();
|
||||
// line with the same style : multiply tones
|
||||
// line with different style : pick darker tone
|
||||
int tone = sameStyleId ? outPix->getTone() * (255 - inPix->m) / 255
|
||||
: outPix->getTone();
|
||||
int ink = outPix->getTone() < 255 && !sameStyleId &&
|
||||
outPix->getTone() <= 255 - inPix->m
|
||||
: std::min(255 - inPix->m, outPix->getTone());
|
||||
int ink = !sameStyleId && outPix->getTone() <= 255 - inPix->m
|
||||
? outPix->getInk()
|
||||
: styleId;
|
||||
*outPix =
|
||||
TPixelCM32(ink, outPix->getPaint(), std::min(255 - inPix->m, tone));
|
||||
*outPix = TPixelCM32(ink, outPix->getPaint(), tone);
|
||||
}
|
||||
}
|
||||
} else { // PaletteOrder
|
||||
for (y = 0; y < out->getLy(); y++) {
|
||||
for (x = 0; x < out->getLx(); x++) {
|
||||
TPixel32 *inPix = &in->pixels(y)[x];
|
||||
if (inPix->m == 0) continue;
|
||||
TPixelCM32 *outPix = &out->pixels(y)[x];
|
||||
bool sameStyleId = styleId == outPix->getInk();
|
||||
// line with the same style : multiply tones
|
||||
// line with different style : pick darker tone
|
||||
int tone = sameStyleId ? outPix->getTone() * (255 - inPix->m) / 255
|
||||
: std::min(255 - inPix->m, outPix->getTone());
|
||||
bool chooseOutPixInk = outPix->getTone() < 255 - inPix->m ||
|
||||
(outPix->getTone() == 255 - inPix->m &&
|
||||
aboveStyleIds.contains(outPix->getInk()));
|
||||
int ink = !sameStyleId && chooseOutPixInk ? outPix->getInk() : styleId;
|
||||
*outPix = TPixelCM32(ink, outPix->getPaint(), tone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -346,7 +365,7 @@ void BluredBrush::eraseDrawing(const TRasterP ras, const TRasterP rasBackup,
|
|||
void BluredBrush::updateDrawing(const TRasterCM32P rasCM,
|
||||
const TRasterCM32P rasBackupCM,
|
||||
const TRect &bbox, int styleId,
|
||||
bool selective) const {
|
||||
int drawOrderMode) const {
|
||||
if (!rasCM) return;
|
||||
|
||||
TRect rasRect = rasCM->getBounds();
|
||||
|
@ -355,7 +374,7 @@ void BluredBrush::updateDrawing(const TRasterCM32P rasCM,
|
|||
|
||||
rasCM->copy(rasBackupCM->extract(targetRect), targetRect.getP00());
|
||||
putOnRasterCM(rasCM->extract(targetRect), m_ras->extract(targetRect), styleId,
|
||||
selective);
|
||||
drawOrderMode, m_aboveStyleIds);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "tcurves.h"
|
||||
#include <QPainter>
|
||||
#include <QImage>
|
||||
#include <QSet>
|
||||
|
||||
//=======================================================
|
||||
//
|
||||
|
@ -24,6 +25,8 @@ class BluredBrush {
|
|||
double m_oldOpacity;
|
||||
bool m_enableDinamicOpacity;
|
||||
|
||||
QSet<int> m_aboveStyleIds;
|
||||
|
||||
double getNextPadPosition(const TThickQuadratic &q, double t) const;
|
||||
|
||||
public:
|
||||
|
@ -37,11 +40,13 @@ public:
|
|||
TRect getBoundFromPoints(const std::vector<TThickPoint> &points) const;
|
||||
// colormapped
|
||||
void updateDrawing(const TRasterCM32P rasCM, const TRasterCM32P rasBackupCM,
|
||||
const TRect &bbox, int styleId, bool selective) const;
|
||||
const TRect &bbox, int styleId, int drawOrderMode) const;
|
||||
void eraseDrawing(const TRasterCM32P rasCM, const TRasterCM32P rasBackupCM,
|
||||
const TRect &bbox, bool selective, int selectedStyleId,
|
||||
const std::wstring &mode) const;
|
||||
|
||||
void setAboveStyleIds(QSet<int> &ids) { m_aboveStyleIds = ids; }
|
||||
|
||||
// fullcolor
|
||||
void updateDrawing(const TRasterP ras, const TRasterP rasBackup,
|
||||
const TPixel32 &color, const TRect &bbox,
|
||||
|
|
|
@ -54,7 +54,7 @@ TEnv::DoubleVar RasterBrushMinSize("InknpaintRasterBrushMinSize", 1);
|
|||
TEnv::DoubleVar RasterBrushMaxSize("InknpaintRasterBrushMaxSize", 5);
|
||||
TEnv::DoubleVar BrushAccuracy("InknpaintBrushAccuracy", 20);
|
||||
TEnv::DoubleVar BrushSmooth("InknpaintBrushSmooth", 0);
|
||||
TEnv::IntVar BrushSelective("InknpaintBrushSelective", 0);
|
||||
TEnv::IntVar BrushDrawOrder("InknpaintBrushDrawOrder", 0);
|
||||
TEnv::IntVar BrushBreakSharpAngles("InknpaintBrushBreakSharpAngles", 0);
|
||||
TEnv::IntVar RasterBrushPencilMode("InknpaintRasterBrushPencilMode", 0);
|
||||
TEnv::IntVar BrushPressureSensitivity("InknpaintBrushPressureSensitivity", 1);
|
||||
|
@ -436,31 +436,56 @@ void addStrokeToImage(TTool::Application *application, const TVectorImageP &vi,
|
|||
// getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
|
||||
enum DrawOrder { OverAll = 0, UnderAll, PaletteOrder };
|
||||
|
||||
void getAboveStyleIdSet(int styleId, TPaletteP palette,
|
||||
QSet<int> &aboveStyles) {
|
||||
if (!palette) return;
|
||||
for (int p = 0; p < palette->getPageCount(); p++) {
|
||||
TPalette::Page *page = palette->getPage(p);
|
||||
for (int s = 0; s < page->getStyleCount(); s++) {
|
||||
int tmpId = page->getStyleId(s);
|
||||
if (tmpId == styleId) return;
|
||||
if (tmpId != 0) aboveStyles.insert(tmpId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================================================
|
||||
|
||||
class RasterBrushUndo final : public TRasterUndo {
|
||||
std::vector<TThickPoint> m_points;
|
||||
int m_styleId;
|
||||
bool m_selective;
|
||||
bool m_isPaletteOrder;
|
||||
bool m_isPencil;
|
||||
|
||||
public:
|
||||
RasterBrushUndo(TTileSetCM32 *tileSet, const std::vector<TThickPoint> &points,
|
||||
int styleId, bool selective, TXshSimpleLevel *level,
|
||||
const TFrameId &frameId, bool isPencil, bool isFrameCreated,
|
||||
bool isLevelCreated)
|
||||
bool isLevelCreated, bool isPaletteOrder)
|
||||
: TRasterUndo(tileSet, level, frameId, isFrameCreated, isLevelCreated, 0)
|
||||
, m_points(points)
|
||||
, m_styleId(styleId)
|
||||
, m_selective(selective)
|
||||
, m_isPencil(isPencil) {}
|
||||
, m_isPencil(isPencil)
|
||||
, m_isPaletteOrder(isPaletteOrder) {}
|
||||
|
||||
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, !m_isPencil);
|
||||
RasterStrokeGenerator m_rasterTrack(ras, BRUSH, NONE, m_styleId,
|
||||
m_points[0], m_selective, 0,
|
||||
!m_isPencil, m_isPaletteOrder);
|
||||
if (m_isPaletteOrder) {
|
||||
QSet<int> aboveStyleIds;
|
||||
getAboveStyleIdSet(m_styleId, image->getPalette(), aboveStyleIds);
|
||||
m_rasterTrack.setAboveStyleIds(aboveStyleIds);
|
||||
}
|
||||
m_rasterTrack.setPointsSequence(m_points);
|
||||
m_rasterTrack.generateStroke(m_isPencil);
|
||||
image->setSavebox(image->getSavebox() +
|
||||
|
@ -482,20 +507,20 @@ public:
|
|||
class RasterBluredBrushUndo final : public TRasterUndo {
|
||||
std::vector<TThickPoint> m_points;
|
||||
int m_styleId;
|
||||
bool m_selective;
|
||||
DrawOrder m_drawOrder;
|
||||
int m_maxThick;
|
||||
double m_hardness;
|
||||
|
||||
public:
|
||||
RasterBluredBrushUndo(TTileSetCM32 *tileSet,
|
||||
const std::vector<TThickPoint> &points, int styleId,
|
||||
bool selective, TXshSimpleLevel *level,
|
||||
DrawOrder drawOrder, TXshSimpleLevel *level,
|
||||
const TFrameId &frameId, int maxThick, double hardness,
|
||||
bool isFrameCreated, bool isLevelCreated)
|
||||
: TRasterUndo(tileSet, level, frameId, isFrameCreated, isLevelCreated, 0)
|
||||
, m_points(points)
|
||||
, m_styleId(styleId)
|
||||
, m_selective(selective)
|
||||
, m_drawOrder(drawOrder)
|
||||
, m_maxThick(maxThick)
|
||||
, m_hardness(hardness) {}
|
||||
|
||||
|
@ -510,11 +535,17 @@ public:
|
|||
workRaster->clear();
|
||||
BluredBrush brush(workRaster, m_maxThick, brushPad, false);
|
||||
|
||||
if (m_drawOrder == PaletteOrder) {
|
||||
QSet<int> aboveStyleIds;
|
||||
getAboveStyleIdSet(m_styleId, image->getPalette(), aboveStyleIds);
|
||||
brush.setAboveStyleIds(aboveStyleIds);
|
||||
}
|
||||
|
||||
std::vector<TThickPoint> points;
|
||||
points.push_back(m_points[0]);
|
||||
TRect bbox = brush.getBoundFromPoints(points);
|
||||
brush.addPoint(m_points[0], 1);
|
||||
brush.updateDrawing(ras, ras, bbox, m_styleId, m_selective);
|
||||
brush.updateDrawing(ras, ras, bbox, m_styleId, (int)m_drawOrder);
|
||||
if (m_points.size() > 1) {
|
||||
points.clear();
|
||||
points.push_back(m_points[0]);
|
||||
|
@ -522,7 +553,7 @@ public:
|
|||
bbox = brush.getBoundFromPoints(points);
|
||||
brush.addArc(m_points[0], (m_points[1] + m_points[0]) * 0.5, m_points[1],
|
||||
1, 1);
|
||||
brush.updateDrawing(ras, backupRas, bbox, m_styleId, m_selective);
|
||||
brush.updateDrawing(ras, backupRas, bbox, m_styleId, (int)m_drawOrder);
|
||||
int i;
|
||||
for (i = 1; i + 2 < (int)m_points.size(); i = i + 2) {
|
||||
points.clear();
|
||||
|
@ -531,7 +562,7 @@ public:
|
|||
points.push_back(m_points[i + 2]);
|
||||
bbox = brush.getBoundFromPoints(points);
|
||||
brush.addArc(m_points[i], m_points[i + 1], m_points[i + 2], 1, 1);
|
||||
brush.updateDrawing(ras, backupRas, bbox, m_styleId, m_selective);
|
||||
brush.updateDrawing(ras, backupRas, bbox, m_styleId, (int)m_drawOrder);
|
||||
}
|
||||
}
|
||||
ToolUtils::updateSaveBox();
|
||||
|
@ -768,7 +799,7 @@ BrushTool::BrushTool(std::string name, int targetType)
|
|||
, m_smooth("Smooth:", 0, 50, 0)
|
||||
, m_hardness("Hardness:", 0, 100, 100)
|
||||
, m_preset("Preset:")
|
||||
, m_selective("Selective", false)
|
||||
, m_drawOrder("Draw Order:")
|
||||
, m_breakAngles("Break", true)
|
||||
, m_pencil("Pencil", false)
|
||||
, m_pressure("Pressure", true)
|
||||
|
@ -804,10 +835,14 @@ BrushTool::BrushTool(std::string name, int targetType)
|
|||
m_prop[0].bind(m_rasThickness);
|
||||
m_prop[0].bind(m_hardness);
|
||||
m_prop[0].bind(m_smooth);
|
||||
m_prop[0].bind(m_selective);
|
||||
m_prop[0].bind(m_drawOrder);
|
||||
m_prop[0].bind(m_pencil);
|
||||
m_pencil.setId("PencilMode");
|
||||
m_selective.setId("Selective");
|
||||
|
||||
m_drawOrder.addValue(tr("Over All").toStdWString());
|
||||
m_drawOrder.addValue(tr("Under All").toStdWString());
|
||||
m_drawOrder.addValue(tr("Palette Order").toStdWString());
|
||||
m_drawOrder.setId("DrawOrder");
|
||||
}
|
||||
|
||||
m_prop[0].bind(m_pressure);
|
||||
|
@ -1013,7 +1048,7 @@ void BrushTool::updateTranslation() {
|
|||
m_hardness.setQStringName(tr("Hardness:"));
|
||||
m_accuracy.setQStringName(tr("Accuracy:"));
|
||||
m_smooth.setQStringName(tr("Smooth:"));
|
||||
m_selective.setQStringName(tr("Selective"));
|
||||
m_drawOrder.setQStringName(tr("Draw Order:"));
|
||||
// m_filled.setQStringName(tr("Filled"));
|
||||
m_preset.setQStringName(tr("Preset:"));
|
||||
m_breakAngles.setQStringName(tr("Break"));
|
||||
|
@ -1064,7 +1099,7 @@ void BrushTool::onActivate() {
|
|||
m_capStyle.setIndex(VectorCapStyle);
|
||||
m_joinStyle.setIndex(VectorJoinStyle);
|
||||
m_miterJoinLimit.setValue(VectorMiterValue);
|
||||
m_selective.setValue(BrushSelective ? 1 : 0);
|
||||
if (m_targetType & TTool::ToonzImage) m_drawOrder.setIndex(BrushDrawOrder);
|
||||
m_breakAngles.setValue(BrushBreakSharpAngles ? 1 : 0);
|
||||
m_pencil.setValue(RasterBrushPencilMode ? 1 : 0);
|
||||
m_pressure.setValue(BrushPressureSensitivity ? 1 : 0);
|
||||
|
@ -1188,6 +1223,15 @@ void BrushTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
|
|||
|
||||
TPointD halfThick(maxThick * 0.5, maxThick * 0.5);
|
||||
TRectD invalidateRect(pos - halfThick, pos + halfThick);
|
||||
|
||||
// if the drawOrder mode = "Palette Order",
|
||||
// get styleId list which is above the current style in the palette
|
||||
DrawOrder drawOrder = (DrawOrder)m_drawOrder.getIndex();
|
||||
QSet<int> aboveStyleIds;
|
||||
if (drawOrder == PaletteOrder) {
|
||||
getAboveStyleIdSet(m_styleId, ri->getPalette(), aboveStyleIds);
|
||||
}
|
||||
|
||||
if (m_hardness.getValue() == 100 || m_pencil.getValue()) {
|
||||
/*-- Pencilモードでなく、Hardness=100 の場合のブラシサイズを1段階下げる
|
||||
* --*/
|
||||
|
@ -1195,8 +1239,12 @@ void BrushTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
|
|||
|
||||
TThickPoint thickPoint(pos + convert(ras->getCenter()), thickness);
|
||||
m_rasterTrack = new RasterStrokeGenerator(
|
||||
ras, BRUSH, NONE, m_styleId, thickPoint, m_selective.getValue(), 0,
|
||||
!m_pencil.getValue());
|
||||
ras, BRUSH, NONE, m_styleId, thickPoint, drawOrder != OverAll, 0,
|
||||
!m_pencil.getValue(), drawOrder == PaletteOrder);
|
||||
|
||||
if (drawOrder == PaletteOrder)
|
||||
m_rasterTrack->setAboveStyleIds(aboveStyleIds);
|
||||
|
||||
m_tileSaver->save(m_rasterTrack->getLastRect());
|
||||
m_rasterTrack->generateLastPieceOfStroke(m_pencil.getValue());
|
||||
|
||||
|
@ -1211,12 +1259,15 @@ void BrushTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
|
|||
m_points.push_back(point);
|
||||
m_bluredBrush = new BluredBrush(m_workRas, maxThick, m_brushPad, false);
|
||||
|
||||
if (drawOrder == PaletteOrder)
|
||||
m_bluredBrush->setAboveStyleIds(aboveStyleIds);
|
||||
|
||||
m_strokeRect = m_bluredBrush->getBoundFromPoints(m_points);
|
||||
updateWorkAndBackupRasters(m_strokeRect);
|
||||
m_tileSaver->save(m_strokeRect);
|
||||
m_bluredBrush->addPoint(point, 1);
|
||||
m_bluredBrush->updateDrawing(ri->getRaster(), m_backupRas, m_strokeRect,
|
||||
m_styleId, m_selective.getValue());
|
||||
m_styleId, drawOrder);
|
||||
m_lastRect = m_strokeRect;
|
||||
|
||||
m_smoothStroke.beginStroke(m_smooth.getValue());
|
||||
|
@ -1356,7 +1407,7 @@ void BrushTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
|
|||
}
|
||||
|
||||
m_bluredBrush->updateDrawing(ti->getRaster(), m_backupRas, bbox,
|
||||
m_styleId, m_selective.getValue());
|
||||
m_styleId, m_drawOrder.getIndex());
|
||||
m_strokeRect += bbox;
|
||||
}
|
||||
}
|
||||
|
@ -1773,7 +1824,7 @@ void BrushTool::finishRasterBrush(const TPointD &pos, double pressureVal) {
|
|||
m_tileSet, m_rasterTrack->getPointsSequence(),
|
||||
m_rasterTrack->getStyleId(), m_rasterTrack->isSelective(),
|
||||
simLevel.getPointer(), frameId, m_pencil.getValue(), m_isFrameCreated,
|
||||
m_isLevelCreated));
|
||||
m_isLevelCreated, m_rasterTrack->isPaletteOrder()));
|
||||
}
|
||||
delete m_rasterTrack;
|
||||
m_rasterTrack = 0;
|
||||
|
@ -1834,7 +1885,7 @@ void BrushTool::finishRasterBrush(const TPointD &pos, double pressureVal) {
|
|||
}
|
||||
|
||||
m_bluredBrush->updateDrawing(ti->getRaster(), m_backupRas, bbox,
|
||||
m_styleId, m_selective.getValue());
|
||||
m_styleId, m_drawOrder.getIndex());
|
||||
m_strokeRect += bbox;
|
||||
}
|
||||
if (pts.size() > 0) {
|
||||
|
@ -1850,7 +1901,7 @@ void BrushTool::finishRasterBrush(const TPointD &pos, double pressureVal) {
|
|||
m_tileSaver->save(bbox);
|
||||
m_bluredBrush->addArc(points[0], points[1], points[2], 1, 1);
|
||||
m_bluredBrush->updateDrawing(ti->getRaster(), m_backupRas, bbox,
|
||||
m_styleId, m_selective.getValue());
|
||||
m_styleId, m_drawOrder.getIndex());
|
||||
|
||||
if (!rectUpdated) {
|
||||
invalidateRect =
|
||||
|
@ -1870,7 +1921,7 @@ void BrushTool::finishRasterBrush(const TPointD &pos, double pressureVal) {
|
|||
|
||||
if (m_tileSet->getTileCount() > 0) {
|
||||
TUndoManager::manager()->add(new RasterBluredBrushUndo(
|
||||
m_tileSet, m_points, m_styleId, m_selective.getValue(),
|
||||
m_tileSet, m_points, m_styleId, (DrawOrder)m_drawOrder.getIndex(),
|
||||
simLevel.getPointer(), frameId, m_rasThickness.getValue().second,
|
||||
m_hardness.getValue() * 0.01, m_isFrameCreated, m_isLevelCreated));
|
||||
}
|
||||
|
@ -2288,8 +2339,8 @@ bool BrushTool::onPropertyChanged(std::string propertyName) {
|
|||
} else if (propertyName == m_preset.getName()) {
|
||||
loadPreset();
|
||||
notifyTool = true;
|
||||
} else if (propertyName == m_selective.getName()) {
|
||||
BrushSelective = m_selective.getValue();
|
||||
} else if (propertyName == m_drawOrder.getName()) {
|
||||
BrushDrawOrder = m_drawOrder.getIndex();
|
||||
} else if (propertyName == m_breakAngles.getName()) {
|
||||
BrushBreakSharpAngles = m_breakAngles.getValue();
|
||||
} else if (propertyName == m_pencil.getName()) {
|
||||
|
@ -2402,7 +2453,7 @@ void BrushTool::loadPreset() {
|
|||
ToolUtils::getBrushPad(preset.m_max, preset.m_hardness * 0.01);
|
||||
m_smooth.setValue(preset.m_smooth, true);
|
||||
m_hardness.setValue(preset.m_hardness, true);
|
||||
m_selective.setValue(preset.m_selective);
|
||||
m_drawOrder.setIndex(preset.m_drawOrder);
|
||||
m_pencil.setValue(preset.m_pencil);
|
||||
m_pressure.setValue(preset.m_pressure);
|
||||
}
|
||||
|
@ -2427,7 +2478,7 @@ void BrushTool::addPreset(QString name) {
|
|||
preset.m_acc = m_accuracy.getValue();
|
||||
preset.m_smooth = m_smooth.getValue();
|
||||
preset.m_hardness = m_hardness.getValue();
|
||||
preset.m_selective = m_selective.getValue();
|
||||
preset.m_drawOrder = m_drawOrder.getIndex();
|
||||
preset.m_pencil = m_pencil.getValue();
|
||||
preset.m_breakAngles = m_breakAngles.getValue();
|
||||
preset.m_pressure = m_pressure.getValue();
|
||||
|
@ -2485,7 +2536,7 @@ BrushData::BrushData()
|
|||
, m_hardness(0.0)
|
||||
, m_opacityMin(0.0)
|
||||
, m_opacityMax(0.0)
|
||||
, m_selective(false)
|
||||
, m_drawOrder(0)
|
||||
, m_pencil(false)
|
||||
, m_breakAngles(false)
|
||||
, m_pressure(false)
|
||||
|
@ -2508,7 +2559,7 @@ BrushData::BrushData(const std::wstring &name)
|
|||
, m_hardness(0.0)
|
||||
, m_opacityMin(0.0)
|
||||
, m_opacityMax(0.0)
|
||||
, m_selective(false)
|
||||
, m_drawOrder(0)
|
||||
, m_pencil(false)
|
||||
, m_breakAngles(false)
|
||||
, m_pressure(false)
|
||||
|
@ -2541,8 +2592,8 @@ void BrushData::saveData(TOStream &os) {
|
|||
os.openChild("Opacity");
|
||||
os << m_opacityMin << m_opacityMax;
|
||||
os.closeChild();
|
||||
os.openChild("Selective");
|
||||
os << (int)m_selective;
|
||||
os.openChild("Draw_Order");
|
||||
os << m_drawOrder;
|
||||
os.closeChild();
|
||||
os.openChild("Pencil");
|
||||
os << (int)m_pencil;
|
||||
|
@ -2595,8 +2646,10 @@ void BrushData::loadData(TIStream &is) {
|
|||
is >> m_hardness, is.matchEndTag();
|
||||
else if (tagName == "Opacity")
|
||||
is >> m_opacityMin >> m_opacityMax, is.matchEndTag();
|
||||
else if (tagName == "Selective")
|
||||
is >> val, m_selective = val, is.matchEndTag();
|
||||
else if (tagName == "Selective" ||
|
||||
tagName == "Draw_Order") // "Selective" is left to keep backward
|
||||
// compatibility
|
||||
is >> m_drawOrder, is.matchEndTag();
|
||||
else if (tagName == "Pencil")
|
||||
is >> val, m_pencil = val, is.matchEndTag();
|
||||
else if (tagName == "Break_Sharp_Angles")
|
||||
|
|
|
@ -39,8 +39,8 @@ struct BrushData final : public TPersist {
|
|||
|
||||
std::wstring m_name;
|
||||
double m_min, m_max, m_acc, m_smooth, m_hardness, m_opacityMin, m_opacityMax;
|
||||
bool m_selective, m_pencil, m_breakAngles, m_pressure;
|
||||
int m_cap, m_join, m_miter;
|
||||
bool m_pencil, m_breakAngles, m_pressure;
|
||||
int m_cap, m_join, m_miter, m_drawOrder;
|
||||
double m_modifierSize, m_modifierOpacity;
|
||||
bool m_modifierEraser, m_modifierLockAlpha;
|
||||
|
||||
|
@ -174,7 +174,7 @@ protected:
|
|||
TDoubleProperty m_smooth;
|
||||
TDoubleProperty m_hardness;
|
||||
TEnumProperty m_preset;
|
||||
TBoolProperty m_selective;
|
||||
TEnumProperty m_drawOrder;
|
||||
TBoolProperty m_breakAngles;
|
||||
TBoolProperty m_pencil;
|
||||
TBoolProperty m_pressure;
|
||||
|
|
|
@ -1625,7 +1625,8 @@ void MainWindow::defineActions() {
|
|||
QAction *newToonzRasterLevelAction = createMenuFileAction(
|
||||
MI_NewToonzRasterLevel, tr("&New Toonz Raster Level"), "");
|
||||
newToonzRasterLevelAction->setIconText(tr("New Toonz Raster Level"));
|
||||
newToonzRasterLevelAction->setIcon(QIcon(":Resources/new_toonz_raster_level.svg"));
|
||||
newToonzRasterLevelAction->setIcon(
|
||||
QIcon(":Resources/new_toonz_raster_level.svg"));
|
||||
QAction *newRasterLevelAction =
|
||||
createMenuFileAction(MI_NewRasterLevel, tr("&New Raster Level"), "");
|
||||
newRasterLevelAction->setIconText(tr("New Raster Level"));
|
||||
|
@ -2213,6 +2214,8 @@ void MainWindow::defineActions() {
|
|||
tr("Pressure Sensitivity"), "Shift+P");
|
||||
createToolOptionsAction("A_ToolOption_SegmentInk", tr("Segment Ink"), "F8");
|
||||
createToolOptionsAction("A_ToolOption_Selective", tr("Selective"), "F7");
|
||||
createToolOptionsAction("A_ToolOption_DrawOrder",
|
||||
tr("Brush Tool - Draw Order"), "");
|
||||
createToolOptionsAction("A_ToolOption_Smooth", tr("Smooth"), "");
|
||||
createToolOptionsAction("A_ToolOption_Snap", tr("Snap"), "");
|
||||
createToolOptionsAction("A_ToolOption_AutoSelectDrawing",
|
||||
|
|
|
@ -9,7 +9,8 @@ RasterStrokeGenerator::RasterStrokeGenerator(const TRasterCM32P &raster,
|
|||
Tasks task, ColorType colorType,
|
||||
int styleId, const TThickPoint &p,
|
||||
bool selective, int selectedStyle,
|
||||
bool keepAntialias)
|
||||
bool keepAntialias,
|
||||
bool isPaletteOrder)
|
||||
: m_raster(raster)
|
||||
, m_boxOfRaster(TRect(raster->getSize()))
|
||||
, m_styleId(styleId)
|
||||
|
@ -19,7 +20,8 @@ RasterStrokeGenerator::RasterStrokeGenerator(const TRasterCM32P &raster,
|
|||
, m_eraseStyle(4095)
|
||||
, m_selectedStyle(selectedStyle)
|
||||
, m_keepAntiAlias(keepAntialias)
|
||||
, m_doAnArc(false) {
|
||||
, m_doAnArc(false)
|
||||
, m_isPaletteOrder(isPaletteOrder) {
|
||||
TThickPoint pp = p;
|
||||
m_points.push_back(pp);
|
||||
if (task == ERASE) m_styleId = m_eraseStyle;
|
||||
|
@ -192,8 +194,10 @@ void RasterStrokeGenerator::placeOver(const TRasterCM32P &out,
|
|||
continue;
|
||||
}
|
||||
if (outPix->isPureInk() && m_selective) {
|
||||
*outPix = TPixelCM32(outPix->getInk(), outPix->getPaint(), outTone);
|
||||
continue;
|
||||
if (!m_isPaletteOrder || m_aboveStyleIds.contains(outPix->getInk())) {
|
||||
*outPix = TPixelCM32(outPix->getInk(), outPix->getPaint(), outTone);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (inTone <= outTone) {
|
||||
*outPix = TPixelCM32(inPix->getInk(), outPix->getPaint(), inTone);
|
||||
|
|
Loading…
Reference in a new issue