mypaint brush for toonz raster levels (#2257)

This commit is contained in:
shun-iwasawa 2018-09-12 10:37:07 +09:00 committed by masafumi-inoue
parent 0c0cf189c0
commit 98926de9b6
10 changed files with 2820 additions and 1367 deletions

View file

@ -43,63 +43,59 @@ public:
TMyPaintBrushStyle(const TMyPaintBrushStyle &other); TMyPaintBrushStyle(const TMyPaintBrushStyle &other);
~TMyPaintBrushStyle(); ~TMyPaintBrushStyle();
TColorStyle *clone() const override TColorStyle *clone() const override { return new TMyPaintBrushStyle(*this); }
{ return new TMyPaintBrushStyle(*this); }
TColorStyle &copy(const TColorStyle &other) override; TColorStyle &copy(const TColorStyle &other) override;
static std::string getBrushType(); static std::string getBrushType();
static TFilePathSet getBrushesDirs(); static TFilePathSet getBrushesDirs();
const TFilePath& getPath() const const TFilePath &getPath() const { return m_path; }
{ return m_path; } const mypaint::Brush &getBrush() const { return m_brushModified; }
const mypaint::Brush& getBrush() const const TRasterP &getPreview() const { return m_preview; }
{ return m_brushModified; }
const TRasterP& getPreview() const
{ return m_preview; }
TStrokeProp* makeStrokeProp(const TStroke * /* stroke */) override TStrokeProp *makeStrokeProp(const TStroke * /* stroke */) override {
{ return 0; } return 0;
TRegionProp* makeRegionProp(const TRegion * /* region */) override }
{ return 0; } TRegionProp *makeRegionProp(const TRegion * /* region */) override {
bool isRegionStyle() const override return 0;
{ return false; } }
bool isStrokeStyle() const override bool isRegionStyle() const override { return false; }
{ return false; } bool isStrokeStyle() const override { return true; }
bool hasMainColor() const override bool hasMainColor() const override { return true; }
{ return true; } TPixel32 getMainColor() const override { return m_color; }
TPixel32 getMainColor() const override void setMainColor(const TPixel32 &color) override { m_color = color; }
{ return m_color; }
void setMainColor(const TPixel32 &color) override
{ m_color = color; }
int getTagId() const override int getTagId() const override { return 4001; }
{ return 4001; }
QString getDescription() const override; QString getDescription() const override;
void setBaseValue(MyPaintBrushSetting id, bool enable, float value); void setBaseValue(MyPaintBrushSetting id, bool enable, float value);
void resetBaseValues(); void resetBaseValues();
void setBaseValue(MyPaintBrushSetting id, float value) void setBaseValue(MyPaintBrushSetting id, float value) {
{ setBaseValue(id, true, value); } setBaseValue(id, true, value);
}
void setBaseValueEnabled(MyPaintBrushSetting id, bool enable) void setBaseValueEnabled(MyPaintBrushSetting id, bool enable) {
{ setBaseValue(id, enable, getBaseValue(id)); } setBaseValue(id, enable, getBaseValue(id));
}
const std::map<MyPaintBrushSetting, float> getBaseValues() const const std::map<MyPaintBrushSetting, float> getBaseValues() const {
{ return m_baseValues; } return m_baseValues;
}
float getBaseValue(MyPaintBrushSetting id) const { float getBaseValue(MyPaintBrushSetting id) const {
std::map<MyPaintBrushSetting, float>::const_iterator i = m_baseValues.find(id); std::map<MyPaintBrushSetting, float>::const_iterator i =
return i == m_baseValues.end() m_baseValues.find(id);
? m_brushOriginal.getBaseValue(id) return i == m_baseValues.end() ? m_brushOriginal.getBaseValue(id)
: i->second; : i->second;
} }
bool getBaseValueEnabled(MyPaintBrushSetting id) const { bool getBaseValueEnabled(MyPaintBrushSetting id) const {
std::map<MyPaintBrushSetting, float>::const_iterator i = m_baseValues.find(id); std::map<MyPaintBrushSetting, float>::const_iterator i =
m_baseValues.find(id);
return i != m_baseValues.end(); return i != m_baseValues.end();
} }

View file

@ -14,12 +14,12 @@ set(MOC_HEADERS
rulertool.h rulertool.h
stylepickertool.h stylepickertool.h
viewtools.h viewtools.h
toonzrasterbrushtool.h
) )
set(HEADERS ${MOC_HEADERS} set(HEADERS ${MOC_HEADERS}
autofill.h autofill.h
bluredbrush.h bluredbrush.h
brushtool.h
../include/tools/cursormanager.h ../include/tools/cursormanager.h
../include/tools/cursors.h ../include/tools/cursors.h
../include/tools/levelselection.h ../include/tools/levelselection.h
@ -37,6 +37,7 @@ set(HEADERS ${MOC_HEADERS}
../include/tools/RGBpicker.h ../include/tools/RGBpicker.h
mypainttoonzbrush.h mypainttoonzbrush.h
shifttracetool.h shifttracetool.h
toonzvectorbrushtool.h
) )
set(SOURCES set(SOURCES
@ -49,7 +50,6 @@ set(SOURCES
toolutils.cpp toolutils.cpp
bendertool.cpp bendertool.cpp
bluredbrush.cpp bluredbrush.cpp
brushtool.cpp
controlpointeditortool.cpp controlpointeditortool.cpp
cuttertool.cpp cuttertool.cpp
edittool.cpp edittool.cpp
@ -98,6 +98,8 @@ set(SOURCES
rulertool.cpp rulertool.cpp
mypainttoonzbrush.cpp mypainttoonzbrush.cpp
shifttracetool.cpp shifttracetool.cpp
toonzrasterbrushtool.cpp
toonzvectorbrushtool.cpp
) )
set(RESOURCES tnztools.qrc) set(RESOURCES tnztools.qrc)

View file

@ -5,7 +5,7 @@
#include <ctime> #include <ctime>
#include "brushtool.h" #include "toonzrasterbrushtool.h"
#include "mypainttoonzbrush.h" #include "mypainttoonzbrush.h"
#include "toonz/mypaintbrushstyle.h" #include "toonz/mypaintbrushstyle.h"
#include <QElapsedTimer> #include <QElapsedTimer>
@ -18,7 +18,9 @@ class TTileSetFullColor;
class TTileSaverFullColor; class TTileSaverFullColor;
class MyPaintToonzBrush; class MyPaintToonzBrush;
class FullColorBrushToolNotifier; class FullColorBrushToolNotifier;
namespace mypaint { class Brush; } namespace mypaint {
class Brush;
}
//============================================================== //==============================================================
@ -77,7 +79,7 @@ public:
void onCanvasSizeChanged(); void onCanvasSizeChanged();
void onColorStyleChanged(); void onColorStyleChanged();
TMyPaintBrushStyle* getBrushStyle(); TMyPaintBrushStyle *getBrushStyle();
protected: protected:
TPropertyGroup m_prop; TPropertyGroup m_prop;
@ -97,7 +99,7 @@ protected:
int m_minCursorThick, m_maxCursorThick; int m_minCursorThick, m_maxCursorThick;
TPointD m_mousePos, //!< Current mouse position, in world coordinates. TPointD m_mousePos, //!< Current mouse position, in world coordinates.
m_brushPos; //!< World position the brush will be painted at. m_brushPos; //!< World position the brush will be painted at.
TRasterP m_backUpRas; TRasterP m_backUpRas;
TRaster32P m_workRaster; TRaster32P m_workRaster;

View file

@ -8,6 +8,35 @@
#include <QColor> #include <QColor>
namespace {
void putOnRasterCM(const TRasterCM32P &out, const TRaster32P &in, int styleId) {
if (!out.getPointer() || !in.getPointer()) return;
assert(out->getSize() == in->getSize());
int x, y;
for (y = 0; y < out->getLy(); y++) {
for (x = 0; x < out->getLx(); x++) {
#ifdef _DEBUG
assert(x >= 0 && x < in->getLx());
assert(y >= 0 && y < in->getLy());
assert(x >= 0 && x < out->getLx());
assert(y >= 0 && y < out->getLy());
#endif
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());
int ink = !sameStyleId && outPix->getTone() < 255 - inPix->m
? outPix->getInk()
: styleId;
*outPix = TPixelCM32(ink, outPix->getPaint(), tone);
}
}
}
} // namespace
//======================================================= //=======================================================
// //
@ -15,19 +44,15 @@
// //
//======================================================= //=======================================================
class Raster32PMyPaintSurface::Internal: class Raster32PMyPaintSurface::Internal
public mypaint::helpers::SurfaceCustom<readPixel, writePixel, askRead, askWrite> : public mypaint::helpers::SurfaceCustom<readPixel, writePixel, askRead,
{ askWrite> {
public: public:
typedef SurfaceCustom Parent; typedef SurfaceCustom Parent;
Internal(Raster32PMyPaintSurface &owner): Internal(Raster32PMyPaintSurface &owner)
SurfaceCustom( owner.m_ras->pixels(), : SurfaceCustom(owner.m_ras->pixels(), owner.m_ras->getLx(),
owner.m_ras->getLx(), owner.m_ras->getLy(), owner.m_ras->getPixelSize(),
owner.m_ras->getLy(), owner.m_ras->getRowSize(), &owner) {}
owner.m_ras->getPixelSize(),
owner.m_ras->getRowSize(),
&owner )
{ }
}; };
//======================================================= //=======================================================
@ -36,39 +61,38 @@ public:
// //
//======================================================= //=======================================================
Raster32PMyPaintSurface::Raster32PMyPaintSurface(const TRaster32P &ras): Raster32PMyPaintSurface::Raster32PMyPaintSurface(const TRaster32P &ras)
m_ras(ras), : m_ras(ras), controller(), internal() {
controller(),
internal()
{
assert(ras); assert(ras);
internal = new Internal(*this); internal = new Internal(*this);
} }
Raster32PMyPaintSurface::Raster32PMyPaintSurface(const TRaster32P &ras, RasterController &controller): Raster32PMyPaintSurface::Raster32PMyPaintSurface(const TRaster32P &ras,
m_ras(ras), RasterController &controller)
controller(&controller), : m_ras(ras), controller(&controller), internal() {
internal()
{
assert(ras); assert(ras);
internal = new Internal(*this); internal = new Internal(*this);
} }
Raster32PMyPaintSurface::~Raster32PMyPaintSurface() Raster32PMyPaintSurface::~Raster32PMyPaintSurface() { delete internal; }
{ delete internal; }
bool Raster32PMyPaintSurface::getColor(float x, float y, float radius, bool Raster32PMyPaintSurface::getColor(float x, float y, float radius,
float &colorR, float &colorG, float &colorB, float &colorA) float &colorR, float &colorG,
{ return internal->getColor(x, y, radius, colorR, colorG, colorB, colorA); } float &colorB, float &colorA) {
return internal->getColor(x, y, radius, colorR, colorG, colorB, colorA);
}
bool Raster32PMyPaintSurface::drawDab(const mypaint::Dab &dab) bool Raster32PMyPaintSurface::drawDab(const mypaint::Dab &dab) {
{ return internal->drawDab(dab); } return internal->drawDab(dab);
}
bool Raster32PMyPaintSurface::getAntialiasing() const bool Raster32PMyPaintSurface::getAntialiasing() const {
{ return internal->antialiasing; } return internal->antialiasing;
}
void Raster32PMyPaintSurface::setAntialiasing(bool value) void Raster32PMyPaintSurface::setAntialiasing(bool value) {
{ internal->antialiasing = value; } internal->antialiasing = value;
}
//======================================================= //=======================================================
// //
@ -76,20 +100,22 @@ void Raster32PMyPaintSurface::setAntialiasing(bool value)
// //
//======================================================= //=======================================================
MyPaintToonzBrush::MyPaintToonzBrush(const TRaster32P &ras, RasterController &controller, const mypaint::Brush &brush): MyPaintToonzBrush::MyPaintToonzBrush(const TRaster32P &ras,
m_ras(ras), RasterController &controller,
m_mypaintSurface(m_ras, controller), const mypaint::Brush &brush)
brush(brush), : m_ras(ras)
reset(true) , m_mypaintSurface(m_ras, controller)
{ , brush(brush)
, reset(true) {
// read brush antialiasing settings // read brush antialiasing settings
float aa = this->brush.getBaseValue(MYPAINT_BRUSH_SETTING_ANTI_ALIASING); float aa = this->brush.getBaseValue(MYPAINT_BRUSH_SETTING_ANTI_ALIASING);
m_mypaintSurface.setAntialiasing(aa > 0.5f); m_mypaintSurface.setAntialiasing(aa > 0.5f);
// reset brush antialiasing to zero to avoid radius and hardness correction // reset brush antialiasing to zero to avoid radius and hardness correction
this->brush.setBaseValue(MYPAINT_BRUSH_SETTING_ANTI_ALIASING, 0.f); this->brush.setBaseValue(MYPAINT_BRUSH_SETTING_ANTI_ALIASING, 0.f);
for(int i = 0; i < MYPAINT_BRUSH_INPUTS_COUNT; ++i) for (int i = 0; i < MYPAINT_BRUSH_INPUTS_COUNT; ++i)
this->brush.setMappingN(MYPAINT_BRUSH_SETTING_ANTI_ALIASING, (MyPaintBrushInput)i, 0); this->brush.setMappingN(MYPAINT_BRUSH_SETTING_ANTI_ALIASING,
(MyPaintBrushInput)i, 0);
} }
void MyPaintToonzBrush::beginStroke() { void MyPaintToonzBrush::beginStroke() {
@ -105,13 +131,14 @@ void MyPaintToonzBrush::endStroke() {
} }
} }
void MyPaintToonzBrush::strokeTo(const TPointD &point, double pressure, double dtime) { void MyPaintToonzBrush::strokeTo(const TPointD &point, double pressure,
double dtime) {
Params next(point.x, point.y, pressure, 0.0); Params next(point.x, point.y, pressure, 0.0);
if (reset) { if (reset) {
current = next; current = next;
previous = current; previous = current;
reset = false; reset = false;
// we need to jump to initial point (heuristic) // we need to jump to initial point (heuristic)
brush.setState(MYPAINT_BRUSH_STATE_X, current.x); brush.setState(MYPAINT_BRUSH_STATE_X, current.x);
brush.setState(MYPAINT_BRUSH_STATE_Y, current.y); brush.setState(MYPAINT_BRUSH_STATE_Y, current.y);
@ -123,31 +150,33 @@ void MyPaintToonzBrush::strokeTo(const TPointD &point, double pressure, double d
} }
// accuracy // accuracy
const double threshold = 1.0; const double threshold = 1.0;
const double thresholdSqr = threshold*threshold; const double thresholdSqr = threshold * threshold;
const int maxLevel = 16; const int maxLevel = 16;
// set initial segment // set initial segment
Segment stack[maxLevel+1]; Segment stack[maxLevel + 1];
Params p0; Params p0;
Segment *segment = stack; Segment *segment = stack;
Segment *maxSegment = segment + maxLevel; Segment *maxSegment = segment + maxLevel;
p0.setMedian(previous, current); p0.setMedian(previous, current);
segment->p1 = current; segment->p1 = current;
segment->p2.setMedian(current, next); segment->p2.setMedian(current, next);
// process // process
while(true) { while (true) {
double dx = segment->p2.x - p0.x; double dx = segment->p2.x - p0.x;
double dy = segment->p2.y - p0.y; double dy = segment->p2.y - p0.y;
if (dx*dx + dy*dy > thresholdSqr && segment != maxSegment) { if (dx * dx + dy * dy > thresholdSqr && segment != maxSegment) {
Segment *sub = segment + 1; Segment *sub = segment + 1;
sub->p1.setMedian(p0, segment->p1); sub->p1.setMedian(p0, segment->p1);
segment->p1.setMedian(segment->p1, segment->p2); segment->p1.setMedian(segment->p1, segment->p2);
sub->p2.setMedian(sub->p1, segment->p1); sub->p2.setMedian(sub->p1, segment->p1);
segment = sub; segment = sub;
} else { } else {
brush.strokeTo(m_mypaintSurface, segment->p2.x, segment->p2.y, segment->p2.pressure, 0.f, 0.f, segment->p2.time - p0.time); brush.strokeTo(m_mypaintSurface, segment->p2.x, segment->p2.y,
segment->p2.pressure, 0.f, 0.f,
segment->p2.time - p0.time);
if (segment == stack) break; if (segment == stack) break;
p0 = segment->p2; p0 = segment->p2;
--segment; --segment;
@ -160,6 +189,21 @@ void MyPaintToonzBrush::strokeTo(const TPointD &point, double pressure, double d
// shift time // shift time
previous.time = 0.0; previous.time = 0.0;
current.time = dtime; current.time = dtime;
} }
//----------------------------------------------------------------------------------
void MyPaintToonzBrush::updateDrawing(const TRasterCM32P rasCM,
const TRasterCM32P rasBackupCM,
const TRect &bbox, int styleId) const {
if (!rasCM) return;
TRect rasRect = rasCM->getBounds();
TRect targetRect = bbox * rasRect;
if (targetRect.isEmpty()) return;
rasCM->copy(rasBackupCM->extract(targetRect), targetRect.getP00());
putOnRasterCM(rasCM->extract(targetRect), m_ras->extract(targetRect),
styleId);
}

View file

@ -10,10 +10,9 @@
#include <QPainter> #include <QPainter>
#include <QImage> #include <QImage>
class RasterController { class RasterController {
public: public:
virtual ~RasterController() { } virtual ~RasterController() {}
virtual bool askRead(const TRect &rect) { return true; } virtual bool askRead(const TRect &rect) { return true; }
virtual bool askWrite(const TRect &rect) { return true; } virtual bool askWrite(const TRect &rect) { return true; }
}; };
@ -24,7 +23,7 @@ public:
// //
//======================================================= //=======================================================
class Raster32PMyPaintSurface: public mypaint::Surface { class Raster32PMyPaintSurface : public mypaint::Surface {
private: private:
class Internal; class Internal;
@ -32,39 +31,50 @@ private:
RasterController *controller; RasterController *controller;
Internal *internal; Internal *internal;
inline static void readPixel(const void *pixelPtr, float &colorR, float &colorG, float &colorB, float &colorA) { inline static void readPixel(const void *pixelPtr, float &colorR,
const TPixel32 &pixel = *(const TPixel32*)pixelPtr; float &colorG, float &colorB, float &colorA) {
colorR = (float)pixel.r/(float)TPixel32::maxChannelValue; const TPixel32 &pixel = *(const TPixel32 *)pixelPtr;
colorG = (float)pixel.g/(float)TPixel32::maxChannelValue; colorR = (float)pixel.r / (float)TPixel32::maxChannelValue;
colorB = (float)pixel.b/(float)TPixel32::maxChannelValue; colorG = (float)pixel.g / (float)TPixel32::maxChannelValue;
colorA = (float)pixel.m/(float)TPixel32::maxChannelValue; colorB = (float)pixel.b / (float)TPixel32::maxChannelValue;
colorA = (float)pixel.m / (float)TPixel32::maxChannelValue;
} }
inline static void writePixel(void *pixelPtr, float colorR, float colorG, float colorB, float colorA) { inline static void writePixel(void *pixelPtr, float colorR, float colorG,
TPixel32 &pixel = *(TPixel32*)pixelPtr; float colorB, float colorA) {
TPixel32 &pixel = *(TPixel32 *)pixelPtr;
pixel.r = (TPixel32::Channel)roundf(colorR * TPixel32::maxChannelValue); pixel.r = (TPixel32::Channel)roundf(colorR * TPixel32::maxChannelValue);
pixel.g = (TPixel32::Channel)roundf(colorG * TPixel32::maxChannelValue); pixel.g = (TPixel32::Channel)roundf(colorG * TPixel32::maxChannelValue);
pixel.b = (TPixel32::Channel)roundf(colorB * TPixel32::maxChannelValue); pixel.b = (TPixel32::Channel)roundf(colorB * TPixel32::maxChannelValue);
pixel.m = (TPixel32::Channel)roundf(colorA * TPixel32::maxChannelValue); pixel.m = (TPixel32::Channel)roundf(colorA * TPixel32::maxChannelValue);
} }
inline static bool askRead(void *surfaceController, const void* /* surfacePointer */, int x0, int y0, int x1, int y1) { inline static bool askRead(void *surfaceController,
Raster32PMyPaintSurface &owner = *((Raster32PMyPaintSurface*)surfaceController); const void * /* surfacePointer */, int x0, int y0,
return !owner.controller || owner.controller->askRead(TRect(x0, y0, x1, y1)); int x1, int y1) {
Raster32PMyPaintSurface &owner =
*((Raster32PMyPaintSurface *)surfaceController);
return !owner.controller ||
owner.controller->askRead(TRect(x0, y0, x1, y1));
} }
inline static bool askWrite(void *surfaceController, const void* /* surfacePointer */, int x0, int y0, int x1, int y1) { inline static bool askWrite(void *surfaceController,
Raster32PMyPaintSurface &owner = *((Raster32PMyPaintSurface*)surfaceController); const void * /* surfacePointer */, int x0, int y0,
return !owner.controller || owner.controller->askWrite(TRect(x0, y0, x1, y1)); int x1, int y1) {
Raster32PMyPaintSurface &owner =
*((Raster32PMyPaintSurface *)surfaceController);
return !owner.controller ||
owner.controller->askWrite(TRect(x0, y0, x1, y1));
} }
public: public:
explicit Raster32PMyPaintSurface(const TRaster32P &ras); explicit Raster32PMyPaintSurface(const TRaster32P &ras);
explicit Raster32PMyPaintSurface(const TRaster32P &ras, RasterController &controller); explicit Raster32PMyPaintSurface(const TRaster32P &ras,
RasterController &controller);
~Raster32PMyPaintSurface(); ~Raster32PMyPaintSurface();
bool getColor(float x, float y, float radius, bool getColor(float x, float y, float radius, float &colorR, float &colorG,
float &colorR, float &colorG, float &colorB, float &colorA) override; float &colorB, float &colorA) override;
bool drawDab(const mypaint::Dab &dab) override; bool drawDab(const mypaint::Dab &dab) override;
@ -82,16 +92,21 @@ class MyPaintToonzBrush {
private: private:
struct Params { struct Params {
union { union {
struct { double x, y, pressure, time; }; struct {
struct { double values[4]; }; double x, y, pressure, time;
};
struct {
double values[4];
};
}; };
inline explicit Params(double x = 0.0, double y = 0.0, double pressure = 0.0, double time = 0.0): inline explicit Params(double x = 0.0, double y = 0.0,
x(x), y(y), pressure(pressure), time(time) { } double pressure = 0.0, double time = 0.0)
: x(x), y(y), pressure(pressure), time(time) {}
inline void setMedian(Params &a, Params &b) { inline void setMedian(Params &a, Params &b) {
for(int i = 0; i < (int)sizeof(values)/sizeof(values[0]); ++i) for (int i = 0; i < (int)sizeof(values) / sizeof(values[0]); ++i)
values[i] = 0.5*(a.values[i] + b.values[i]); values[i] = 0.5 * (a.values[i] + b.values[i]);
} }
}; };
@ -107,10 +122,15 @@ private:
Params previous, current; Params previous, current;
public: public:
MyPaintToonzBrush(const TRaster32P &ras, RasterController &controller, const mypaint::Brush &brush); MyPaintToonzBrush(const TRaster32P &ras, RasterController &controller,
const mypaint::Brush &brush);
void beginStroke(); void beginStroke();
void endStroke(); void endStroke();
void strokeTo(const TPointD &p, double pressure, double dtime); void strokeTo(const TPointD &p, double pressure, double dtime);
// colormapped
void updateDrawing(const TRasterCM32P rasCM, const TRasterCM32P rasBackupCM,
const TRect &bbox, int styleId) const;
}; };
#endif // T_BLUREDBRUSH #endif // T_BLUREDBRUSH

View file

@ -10,8 +10,9 @@
#include "selectiontool.h" #include "selectiontool.h"
#include "vectorselectiontool.h" #include "vectorselectiontool.h"
#include "rasterselectiontool.h" #include "rasterselectiontool.h"
#include "brushtool.h" #include "toonzrasterbrushtool.h"
#include "fullcolorbrushtool.h" #include "fullcolorbrushtool.h"
#include "toonzvectorbrushtool.h"
#include "tooloptionscontrols.h" #include "tooloptionscontrols.h"
//#include "rgbpickertool.h" //#include "rgbpickertool.h"
@ -1867,9 +1868,18 @@ void BrushToolOptionsBox::filterControls() {
// show or hide widgets which modify imported brush (mypaint) // show or hide widgets which modify imported brush (mypaint)
bool showModifiers = false; bool showModifiers = false;
if (FullColorBrushTool *fullColorBrushTool = if (m_tool->getTargetType() & TTool::RasterImage) {
dynamic_cast<FullColorBrushTool *>(m_tool)) FullColorBrushTool *fullColorBrushTool =
dynamic_cast<FullColorBrushTool *>(m_tool);
showModifiers = fullColorBrushTool->getBrushStyle(); showModifiers = fullColorBrushTool->getBrushStyle();
} else if (m_tool->getTargetType() & TTool::ToonzImage) {
ToonzRasterBrushTool *toonzRasterBrushTool =
dynamic_cast<ToonzRasterBrushTool *>(m_tool);
showModifiers = toonzRasterBrushTool->isMyPaintStyleSelected();
} else { // (m_tool->getTargetType() & TTool::Vectors)
m_snapSensitivityCombo->setHidden(!m_snapCheckbox->isChecked());
return;
}
for (QMap<std::string, QLabel *>::iterator it = m_labels.begin(); for (QMap<std::string, QLabel *>::iterator it = m_labels.begin();
it != m_labels.end(); it++) { it != m_labels.end(); it++) {
@ -1887,9 +1897,6 @@ void BrushToolOptionsBox::filterControls() {
if (QWidget *widget = dynamic_cast<QWidget *>(it.value())) if (QWidget *widget = dynamic_cast<QWidget *>(it.value()))
widget->setVisible(visible); widget->setVisible(visible);
} }
if (m_tool->getTargetType() & TTool::Vectors) {
m_snapSensitivityCombo->setHidden(!m_snapCheckbox->isChecked());
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1931,9 +1938,12 @@ void BrushToolOptionsBox::onAddPreset() {
m_presetNamePopup->removeName(); m_presetNamePopup->removeName();
switch (m_tool->getTargetType() & TTool::CommonImages) { switch (m_tool->getTargetType() & TTool::CommonImages) {
case TTool::VectorImage: case TTool::VectorImage: {
static_cast<ToonzVectorBrushTool *>(m_tool)->addPreset(name);
break;
}
case TTool::ToonzImage: { case TTool::ToonzImage: {
static_cast<BrushTool *>(m_tool)->addPreset(name); static_cast<ToonzRasterBrushTool *>(m_tool)->addPreset(name);
break; break;
} }
@ -1950,9 +1960,12 @@ void BrushToolOptionsBox::onAddPreset() {
void BrushToolOptionsBox::onRemovePreset() { void BrushToolOptionsBox::onRemovePreset() {
switch (m_tool->getTargetType() & TTool::CommonImages) { switch (m_tool->getTargetType() & TTool::CommonImages) {
case TTool::VectorImage: case TTool::VectorImage: {
static_cast<ToonzVectorBrushTool *>(m_tool)->removePreset();
break;
}
case TTool::ToonzImage: { case TTool::ToonzImage: {
static_cast<BrushTool *>(m_tool)->removePreset(); static_cast<ToonzRasterBrushTool *>(m_tool)->removePreset();
break; break;
} }

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
#ifndef BRUSHTOOL_H #ifndef TOONZRASTERBRUSHTOOL_H
#define BRUSHTOOL_H #define TOONZRASTERBRUSHTOOL_H
#include "tgeometry.h" #include "tgeometry.h"
#include "tproperty.h" #include "tproperty.h"
@ -12,9 +12,11 @@
#include "tools/tool.h" #include "tools/tool.h"
#include "tools/cursors.h" #include "tools/cursors.h"
#include "mypainttoonzbrush.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QRadialGradient> #include <QRadialGradient>
#include <QElapsedTimer>
//-------------------------------------------------------------- //--------------------------------------------------------------
@ -24,11 +26,12 @@ class TTileSetCM32;
class TTileSaverCM32; class TTileSaverCM32;
class RasterStrokeGenerator; class RasterStrokeGenerator;
class BluredBrush; class BluredBrush;
class ToonzRasterBrushToolNotifier;
//-------------------------------------------------------------- //--------------------------------------------------------------
//************************************************************************ //************************************************************************
// Brush Data declaration // Toonz Raster Brush Data declaration
//************************************************************************ //************************************************************************
struct BrushData final : public TPersist { struct BrushData final : public TPersist {
@ -38,9 +41,9 @@ struct BrushData final : public TPersist {
// just the overall tool. // just the overall tool.
std::wstring m_name; std::wstring m_name;
double m_min, m_max, m_acc, m_smooth, m_hardness, m_opacityMin, m_opacityMax; double m_min, m_max, m_smooth, m_hardness, m_opacityMin, m_opacityMax;
bool m_pencil, m_breakAngles, m_pressure; bool m_pencil, m_pressure;
int m_cap, m_join, m_miter, m_drawOrder; int m_drawOrder;
double m_modifierSize, m_modifierOpacity; double m_modifierSize, m_modifierOpacity;
bool m_modifierEraser, m_modifierLockAlpha; bool m_modifierEraser, m_modifierLockAlpha;
@ -54,7 +57,7 @@ struct BrushData final : public TPersist {
}; };
//************************************************************************ //************************************************************************
// Brush Preset Manager declaration // Toonz Raster Brush Preset Manager declaration
//************************************************************************ //************************************************************************
class BrushPresetManager { class BrushPresetManager {
@ -108,14 +111,17 @@ private:
std::vector<TThickPoint> m_outputPoints; std::vector<TThickPoint> m_outputPoints;
}; };
//************************************************************************ //************************************************************************
// Brush Tool declaration // Toonz Raster Brush Tool declaration
//************************************************************************ //************************************************************************
class BrushTool final : public TTool { class ToonzRasterBrushTool final : public TTool, public RasterController {
Q_DECLARE_TR_FUNCTIONS(BrushTool) Q_DECLARE_TR_FUNCTIONS(ToonzRasterBrushTool)
void updateCurrentStyle();
double restartBrushTimer();
public: public:
BrushTool(std::string name, int targetType); ToonzRasterBrushTool(std::string name, int targetType);
ToolType getToolType() const override { return TTool::LevelWriteTool; } ToolType getToolType() const override { return TTool::LevelWriteTool; }
@ -131,7 +137,6 @@ public:
void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override; void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override;
void leftButtonUp(const TPointD &pos, const TMouseEvent &e) override; void leftButtonUp(const TPointD &pos, const TMouseEvent &e) override;
void mouseMove(const TPointD &pos, const TMouseEvent &e) override; void mouseMove(const TPointD &pos, const TMouseEvent &e) override;
bool keyDown(QKeyEvent *event) override;
void draw() override; void draw() override;
@ -142,7 +147,6 @@ public:
TPropertyGroup *getProperties(int targetType) override; TPropertyGroup *getProperties(int targetType) override;
bool onPropertyChanged(std::string propertyName) override; bool onPropertyChanged(std::string propertyName) override;
void resetFrameRange();
void onImageChanged() override; void onImageChanged() override;
void setWorkAndBackupImages(); void setWorkAndBackupImages();
void updateWorkAndBackupRasters(const TRect &rect); void updateWorkAndBackupRasters(const TRect &rect);
@ -157,56 +161,34 @@ public:
// Tools. // Tools.
bool isPencilModeActive() override; bool isPencilModeActive() override;
void addTrackPoint(const TThickPoint &point, double pixelSize2); void onColorStyleChanged();
void flushTrackPoint(); bool askRead(const TRect &rect) override;
bool doFrameRangeStrokes(TFrameId firstFrameId, TStroke *firstStroke, bool askWrite(const TRect &rect) override;
TFrameId lastFrameId, TStroke *lastStroke, bool isMyPaintStyleSelected() { return m_isMyPaintStyleSelected; }
bool drawFirstStroke = true);
void checkGuideSnapping(bool beforeMousePress, bool invertCheck);
void checkStrokeSnapping(bool beforeMousePress, bool invertCheck);
protected: protected:
TPropertyGroup m_prop[2]; TPropertyGroup m_prop[2];
TDoublePairProperty m_thickness;
TDoublePairProperty m_rasThickness; TDoublePairProperty m_rasThickness;
TDoubleProperty m_accuracy;
TDoubleProperty m_smooth; TDoubleProperty m_smooth;
TDoubleProperty m_hardness; TDoubleProperty m_hardness;
TEnumProperty m_preset; TEnumProperty m_preset;
TEnumProperty m_drawOrder; TEnumProperty m_drawOrder;
TBoolProperty m_breakAngles;
TBoolProperty m_pencil; TBoolProperty m_pencil;
TBoolProperty m_pressure; TBoolProperty m_pressure;
TBoolProperty m_snap; TDoubleProperty m_modifierSize;
TEnumProperty m_frameRange;
TEnumProperty m_snapSensitivity;
TEnumProperty m_capStyle;
TEnumProperty m_joinStyle;
TIntProperty m_miterJoinLimit;
StrokeGenerator m_track;
StrokeGenerator m_rangeTrack;
RasterStrokeGenerator *m_rasterTrack; RasterStrokeGenerator *m_rasterTrack;
TStroke *m_firstStroke;
TTileSetCM32 *m_tileSet; TTileSetCM32 *m_tileSet;
TTileSaverCM32 *m_tileSaver; TTileSaverCM32 *m_tileSaver;
TFrameId m_firstFrameId, m_veryFirstFrameId;
TPixel32 m_currentColor; TPixel32 m_currentColor;
int m_styleId; int m_styleId;
double m_minThick, m_maxThick; double m_minThick, m_maxThick;
// for snapping and framerange int m_targetType;
int m_strokeIndex1, m_strokeIndex2, m_col, m_firstFrame, m_veryFirstFrame,
m_veryFirstCol, m_targetType;
double m_w1, m_w2, m_pixelSize, m_currThickness, m_minDistance2;
bool m_foundFirstSnap = false, m_foundLastSnap = false, m_dragDraw = true,
m_altPressed = false, m_snapSelf = false;
TRectD m_modifiedRegion;
TPointD m_dpiScale, TPointD m_dpiScale,
m_mousePos, //!< Current mouse position, in world coordinates. m_mousePos, //!< Current mouse position, in world coordinates.
m_brushPos, //!< World position the brush will be painted at. m_brushPos; //!< World position the brush will be painted at.
m_firstSnapPoint, m_lastSnapPoint;
BluredBrush *m_bluredBrush; BluredBrush *m_bluredBrush;
QRadialGradient m_brushPad; QRadialGradient m_brushPad;
@ -215,7 +197,8 @@ protected:
TRaster32P m_workRas; TRaster32P m_workRas;
std::vector<TThickPoint> m_points; std::vector<TThickPoint> m_points;
TRect m_strokeRect, m_lastRect; TRect m_strokeRect, m_lastRect,
m_strokeSegmentRect; // used with mypaint brush
SmoothStroke m_smoothStroke; SmoothStroke m_smoothStroke;
@ -225,13 +208,19 @@ protected:
bool m_active, m_enabled, bool m_active, m_enabled,
m_isPrompting, //!< Whether the tool is prompting for spline m_isPrompting, //!< Whether the tool is prompting for spline
//! substitution. //! substitution.
m_firstTime, m_isPath, m_presetsLoaded, m_firstFrameRange; m_firstTime, m_presetsLoaded;
/*--- /*---
FrameIdをクリック時に保存しUndoの登録時 FrameIdをクリック時に保存しUndoの登録時
---*/ ---*/
TFrameId m_workingFrameId; TFrameId m_workingFrameId;
ToonzRasterBrushToolNotifier *m_notifier;
bool m_isMyPaintStyleSelected = false;
MyPaintToonzBrush *m_toonz_brush = 0;
QElapsedTimer m_brushTimer;
int m_minCursorThick, m_maxCursorThick;
protected: protected:
static void drawLine(const TPointD &point, const TPointD &centre, static void drawLine(const TPointD &point, const TPointD &centre,
bool horizontal, bool isDecimal); bool horizontal, bool isDecimal);
@ -239,4 +228,19 @@ protected:
bool isLyEven, bool isPencil); bool isLyEven, bool isPencil);
}; };
#endif // BRUSHTOOL_H //------------------------------------------------------------
class ToonzRasterBrushToolNotifier final : public QObject {
Q_OBJECT
ToonzRasterBrushTool *m_tool;
public:
ToonzRasterBrushToolNotifier(ToonzRasterBrushTool *tool);
protected slots:
// void onCanvasSizeChanged() { m_tool->onCanvasSizeChanged(); }
void onColorStyleChanged() { m_tool->onColorStyleChanged(); }
};
#endif // TOONZRASTERBRUSHTOOL_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,197 @@
#pragma once
#ifndef TOONZVECTORBRUSHTOOL_H
#define TOONZVECTORBRUSHTOOL_H
#include "tgeometry.h"
#include "tproperty.h"
#include "trasterimage.h"
#include "ttoonzimage.h"
#include "tstroke.h"
#include "toonz/strokegenerator.h"
#include "tools/tool.h"
#include "tools/cursors.h"
#include "toonzrasterbrushtool.h"
#include <QCoreApplication>
#include <QRadialGradient>
//--------------------------------------------------------------
// Forward declarations
class TTileSetCM32;
class TTileSaverCM32;
class RasterStrokeGenerator;
class BluredBrush;
//--------------------------------------------------------------
//************************************************************************
// Brush Data declaration
//************************************************************************
struct VectorBrushData final : public TPersist {
PERSIST_DECLARATION(VectorBrushData)
// frameRange, snapSensitivity and snap are not included
// Those options are not really a part of the brush settings,
// just the overall tool.
std::wstring m_name;
double m_min, m_max, m_acc, m_smooth;
bool m_breakAngles, m_pressure;
int m_cap, m_join, m_miter;
VectorBrushData();
VectorBrushData(const std::wstring &name);
bool operator<(const VectorBrushData &other) const {
return m_name < other.m_name;
}
void saveData(TOStream &os) override;
void loadData(TIStream &is) override;
};
//************************************************************************
// Brush Preset Manager declaration
//************************************************************************
class VectorBrushPresetManager {
TFilePath m_fp; //!< Presets file path
std::set<VectorBrushData> m_presets; //!< Current presets container
public:
VectorBrushPresetManager() {}
void load(const TFilePath &fp);
void save();
const TFilePath &path() { return m_fp; };
const std::set<VectorBrushData> &presets() const { return m_presets; }
void addPreset(const VectorBrushData &data);
void removePreset(const std::wstring &name);
};
//************************************************************************
// Brush Tool declaration
//************************************************************************
class ToonzVectorBrushTool final : public TTool {
Q_DECLARE_TR_FUNCTIONS(BrushTool)
public:
ToonzVectorBrushTool(std::string name, int targetType);
ToolType getToolType() const override { return TTool::LevelWriteTool; }
ToolOptionsBox *createOptionsBox() override;
void updateTranslation() override;
void onActivate() override;
void onDeactivate() override;
bool preLeftButtonDown() override;
void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override;
void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override;
void leftButtonUp(const TPointD &pos, const TMouseEvent &e) override;
void mouseMove(const TPointD &pos, const TMouseEvent &e) override;
bool keyDown(QKeyEvent *event) override;
void draw() override;
void onEnter() override;
void onLeave() override;
int getCursorId() const override { return ToolCursor::PenCursor; }
TPropertyGroup *getProperties(int targetType) override;
bool onPropertyChanged(std::string propertyName) override;
void resetFrameRange();
void initPresets();
void loadPreset();
void addPreset(QString name);
void removePreset();
// return true if the pencil mode is active in the Brush / PaintBrush / Eraser
// Tools.
bool isPencilModeActive() override;
void addTrackPoint(const TThickPoint &point, double pixelSize2);
void flushTrackPoint();
bool doFrameRangeStrokes(TFrameId firstFrameId, TStroke *firstStroke,
TFrameId lastFrameId, TStroke *lastStroke,
bool drawFirstStroke = true);
void checkGuideSnapping(bool beforeMousePress, bool invertCheck);
void checkStrokeSnapping(bool beforeMousePress, bool invertCheck);
protected:
TPropertyGroup m_prop[2];
TDoublePairProperty m_thickness;
TDoubleProperty m_accuracy;
TDoubleProperty m_smooth;
TEnumProperty m_preset;
TBoolProperty m_breakAngles;
TBoolProperty m_pressure;
TBoolProperty m_snap;
TEnumProperty m_frameRange;
TEnumProperty m_snapSensitivity;
TEnumProperty m_capStyle;
TEnumProperty m_joinStyle;
TIntProperty m_miterJoinLimit;
StrokeGenerator m_track;
StrokeGenerator m_rangeTrack;
RasterStrokeGenerator *m_rasterTrack;
TStroke *m_firstStroke;
TTileSetCM32 *m_tileSet;
TTileSaverCM32 *m_tileSaver;
TFrameId m_firstFrameId, m_veryFirstFrameId;
TPixel32 m_currentColor;
int m_styleId;
double m_minThick, m_maxThick;
// for snapping and framerange
int m_strokeIndex1, m_strokeIndex2, m_col, m_firstFrame, m_veryFirstFrame,
m_veryFirstCol, m_targetType;
double m_w1, m_w2, m_pixelSize, m_currThickness, m_minDistance2;
bool m_foundFirstSnap = false, m_foundLastSnap = false, m_dragDraw = true,
m_altPressed = false, m_snapSelf = false;
TRectD m_modifiedRegion;
TPointD m_dpiScale,
m_mousePos, //!< Current mouse position, in world coordinates.
m_brushPos, //!< World position the brush will be painted at.
m_firstSnapPoint, m_lastSnapPoint;
BluredBrush *m_bluredBrush;
QRadialGradient m_brushPad;
TRasterCM32P m_backupRas;
TRaster32P m_workRas;
std::vector<TThickPoint> m_points;
TRect m_strokeRect, m_lastRect;
SmoothStroke m_smoothStroke;
VectorBrushPresetManager
m_presetsManager; //!< Manager for presets of this tool instance
bool m_active, m_enabled,
m_isPrompting, //!< Whether the tool is prompting for spline
//! substitution.
m_firstTime, m_isPath, m_presetsLoaded, m_firstFrameRange;
/*---
FrameIdをクリック時に保存しUndoの登録時
---*/
TFrameId m_workingFrameId;
};
#endif // TOONZVECTORBRUSHTOOL_H