diff --git a/toonz/sources/include/tools/cursors.h b/toonz/sources/include/tools/cursors.h
index b156997..a741def 100644
--- a/toonz/sources/include/tools/cursors.h
+++ b/toonz/sources/include/tools/cursors.h
@@ -99,6 +99,7 @@ enum {
Ex_Precise = 0x200000,
Ex_Prev = 0x400000,
Ex_Next = 0x800000,
+ Ex_FreePick = 0x1000000,
// This section is for cursors that have fixed text that needs to
// be handled separately when flipping for left-handed cursors.
diff --git a/toonz/sources/tnztools/Resources/ex_freepick.png b/toonz/sources/tnztools/Resources/ex_freepick.png
new file mode 100644
index 0000000..b47c3ca
Binary files /dev/null and b/toonz/sources/tnztools/Resources/ex_freepick.png differ
diff --git a/toonz/sources/tnztools/Resources/ex_freepick_left.png b/toonz/sources/tnztools/Resources/ex_freepick_left.png
new file mode 100644
index 0000000..3aabc35
Binary files /dev/null and b/toonz/sources/tnztools/Resources/ex_freepick_left.png differ
diff --git a/toonz/sources/tnztools/cursormanager.cpp b/toonz/sources/tnztools/cursormanager.cpp
index 24531fa..4d08188 100644
--- a/toonz/sources/tnztools/cursormanager.cpp
+++ b/toonz/sources/tnztools/cursormanager.cpp
@@ -119,6 +119,7 @@ const struct {
{ToolCursor::Ex_Precise, "ex_precise"},
{ToolCursor::Ex_Prev, "ex_prev"},
{ToolCursor::Ex_Next, "ex_next"},
+ {ToolCursor::Ex_FreePick, "ex_freepick"},
{0, 0}};
}; // namespace
diff --git a/toonz/sources/tnztools/filltool.cpp b/toonz/sources/tnztools/filltool.cpp
index ee942be..2b6d78f 100644
--- a/toonz/sources/tnztools/filltool.cpp
+++ b/toonz/sources/tnztools/filltool.cpp
@@ -58,6 +58,7 @@ using namespace ToolUtils;
#define RECTFILL L"Rectangular"
#define FREEHANDFILL L"Freehand"
#define POLYLINEFILL L"Polyline"
+#define FREEPICKFILL L"Freepick"
TEnv::IntVar MinFillDepth("InknpaintMinFillDepth", 0);
TEnv::IntVar MaxFillDepth("InknpaintMaxFillDepth", 10);
@@ -1229,7 +1230,8 @@ void AreaFillTool::draw() {
drawRect(m_firstRect, color, 0x3F33, true);
if (m_selecting || (m_frameRange && !m_firstFrameSelected))
drawRect(m_selectingRect, color, 0xFFFF, true);
- } else if ((m_type == FREEHAND || m_type == POLYLINE) && m_frameRange) {
+ } else if ((m_type == FREEHAND || m_type == POLYLINE || m_type == FREEPICK) &&
+ m_frameRange) {
tglColor(color);
if (m_firstStroke) drawStrokeCenterline(*m_firstStroke, 1);
}
@@ -1243,7 +1245,7 @@ void AreaFillTool::draw() {
tglVertex(m_mousePosition);
glEnd();
glPopMatrix();
- } else if (m_type == FREEHAND && !m_track.isEmpty()) {
+ } else if ((m_type == FREEHAND || m_type == FREEPICK) && !m_track.isEmpty()) {
tglColor(TPixel::Red);
glPushMatrix();
m_track.drawAllFragments();
@@ -1251,6 +1253,36 @@ void AreaFillTool::draw() {
}
}
+int AreaFillTool::pick(const TImageP &image, const TPointD &pos,
+ const int frame, int mode) {
+ TToonzImageP ti = image;
+ TVectorImageP vi = image;
+ if (!ti && !vi) return 0;
+
+ TTool::Viewer *viewer = m_parent->getViewer();
+
+ StylePicker picker(viewer->viewerWidget(), image);
+ double scale2 = 1.0;
+ if (vi) {
+ TAffine aff =
+ viewer->getViewMatrix() * m_parent->getCurrentColumnMatrix(frame);
+ scale2 = aff.det();
+ }
+ TPointD pickPos = pos;
+ // in case that the column is animated in scene-editing mode
+ if (frame > 0) {
+ TPointD dpiScale = viewer->getDpiScale();
+ pickPos.x *= dpiScale.x;
+ pickPos.y *= dpiScale.y;
+ TPointD worldPos = m_parent->getCurrentColumnMatrix() * pickPos;
+ pickPos = m_parent->getCurrentColumnMatrix(frame).inv() * worldPos;
+ pickPos.x /= dpiScale.x;
+ pickPos.y /= dpiScale.y;
+ }
+ // thin stroke can be picked with 10 pixel range
+ return picker.pickStyleId(pickPos, 10.0, scale2, mode);
+}
+
void AreaFillTool::resetMulti() {
m_firstFrameSelected = false;
m_firstRect.empty();
@@ -1265,7 +1297,7 @@ void AreaFillTool::resetMulti() {
}
}
-void AreaFillTool::leftButtonDown(const TPointD &pos, const TMouseEvent &,
+void AreaFillTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e,
TImage *img) {
TVectorImageP vi = TImageP(img);
TToonzImageP ti = TToonzImageP(img);
@@ -1275,13 +1307,23 @@ void AreaFillTool::leftButtonDown(const TPointD &pos, const TMouseEvent &,
return;
}
+ if (m_type == FREEPICK) {
+ TTool::Application *app = TTool::getApplication();
+ if (!app) return;
+
+ int fllmode = e.isCtrlPressed() ? 2 : 0; // Line+Area : Area
+ int styleId = pick(img, pos, -1, fllmode);
+ if (!m_isLeftButtonPressed) m_bckStyleId = app->getCurrentLevelStyleIndex();
+ app->setCurrentLevelStyleIndex(styleId);
+ }
+
m_selecting = true;
if (m_type == RECT) {
m_selectingRect.x0 = pos.x;
m_selectingRect.y0 = pos.y;
m_selectingRect.x1 = pos.x + 1;
m_selectingRect.y1 = pos.y + 1;
- } else if (m_type == FREEHAND || m_type == POLYLINE) {
+ } else if (m_type == FREEHAND || m_type == POLYLINE || m_type == FREEPICK) {
int col = TTool::getApplication()->getCurrentColumn()->getColumnIndex();
m_isPath = TTool::getApplication()
->getCurrentObject()
@@ -1389,7 +1431,7 @@ void AreaFillTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
m_selectingRect.x1 = pos.x;
m_selectingRect.y1 = pos.y;
m_parent->invalidate();
- } else if (m_type == FREEHAND) {
+ } else if (m_type == FREEHAND || m_type == FREEPICK) {
if (!m_enabled || !m_active) return;
double pixelSize2 = m_parent->getPixelSize() * m_parent->getPixelSize();
@@ -1463,7 +1505,7 @@ void AreaFillTool::leftButtonUp(const TPointD &pos, const TMouseEvent &e) {
TTool *t = app->getCurrentTool()->getTool();
if (t) t->notifyImageChanged();
}
- } else if (m_type == FREEHAND) {
+ } else if (m_type == FREEHAND || m_type == FREEPICK) {
#if defined(MACOSX)
// m_parent->m_viewer->enableRedraw(true);
#endif
@@ -1527,6 +1569,8 @@ void AreaFillTool::leftButtonUp(const TPointD &pos, const TMouseEvent &e) {
m_parent->invalidate();
}
}
+
+ if (m_type == FREEPICK) app->setCurrentLevelStyleIndex(m_bckStyleId);
}
void AreaFillTool::onImageChanged() {
@@ -1544,7 +1588,7 @@ void AreaFillTool::onImageChanged() {
// stato iniziale
else { // cambio stato.
m_firstFrameSelected = true;
- if (m_type != FREEHAND && m_type != POLYLINE) {
+ if (m_type != FREEHAND && m_type != POLYLINE && m_type != FREEPICK) {
assert(!m_selectingRect.isEmpty());
m_firstRect = m_selectingRect;
}
@@ -1740,6 +1784,7 @@ FillTool::FillTool(int targetType)
m_fillType.addValue(RECTFILL);
m_fillType.addValue(FREEHANDFILL);
m_fillType.addValue(POLYLINEFILL);
+ m_fillType.addValue(FREEPICKFILL);
m_prop.bind(m_colorType);
m_colorType.addValue(LINES);
@@ -1784,6 +1829,8 @@ int FillTool::getCursorId() const {
ret = ret | ToolCursor::Ex_PolyLine;
else if (m_fillType.getValue() == RECTFILL)
ret = ret | ToolCursor::Ex_Rectangle;
+ if (m_fillType.getValue() == FREEPICKFILL)
+ ret = ret | ToolCursor::Ex_FreePick;
if (ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg)
ret = ret | ToolCursor::Ex_Negate;
@@ -1800,6 +1847,7 @@ void FillTool::updateTranslation() {
m_fillType.setItemUIName(RECTFILL, tr("Rectangular"));
m_fillType.setItemUIName(FREEHANDFILL, tr("Freehand"));
m_fillType.setItemUIName(POLYLINEFILL, tr("Polyline"));
+ m_fillType.setItemUIName(FREEPICKFILL, tr("Pick+Freehand"));
m_selective.setQStringName(tr("Selective"));
@@ -2090,6 +2138,8 @@ bool FillTool::onPropertyChanged(std::string propertyName) {
type = AreaFillTool::FREEHAND;
else if (m_fillType.getValue() == POLYLINEFILL)
type = AreaFillTool::POLYLINE;
+ else if (m_fillType.getValue() == FREEPICKFILL)
+ type = AreaFillTool::FREEPICK;
else
assert(false);
@@ -2294,6 +2344,8 @@ void FillTool::onActivate() {
type = AreaFillTool::FREEHAND;
else if (m_fillType.getValue() == POLYLINEFILL)
type = AreaFillTool::POLYLINE;
+ else if (m_fillType.getValue() == FREEPICKFILL)
+ type = AreaFillTool::FREEPICK;
else
assert(false);
diff --git a/toonz/sources/tnztools/filltool.h b/toonz/sources/tnztools/filltool.h
index 32342b7..80bdd67 100644
--- a/toonz/sources/tnztools/filltool.h
+++ b/toonz/sources/tnztools/filltool.h
@@ -24,7 +24,7 @@ class NormalLineFillTool;
namespace {
class AreaFillTool {
public:
- enum Type { RECT, FREEHAND, POLYLINE };
+ enum Type { RECT, FREEHAND, POLYLINE, FREEPICK };
private:
bool m_frameRange;
@@ -54,9 +54,12 @@ private:
bool m_isLeftButtonPressed;
bool m_autopaintLines;
+ int m_bckStyleId;
+
public:
AreaFillTool(TTool *Parent);
void draw();
+ int pick(const TImageP &image, const TPointD &pos, const int frame, int mode);
void resetMulti();
void leftButtonDown(const TPointD &pos, const TMouseEvent &, TImage *img);
void leftButtonDoubleClick(const TPointD &pos, const TMouseEvent &e);
diff --git a/toonz/sources/tnztools/tnztools.qrc b/toonz/sources/tnztools/tnztools.qrc
index 7370ccc..e333b83 100644
--- a/toonz/sources/tnztools/tnztools.qrc
+++ b/toonz/sources/tnztools/tnztools.qrc
@@ -1,5 +1,5 @@
-
+
Resources/brush.png
Resources/bender.png
Resources/cutter.png
@@ -33,59 +33,61 @@
Resources/selection_add.png
Resources/selection_convert.png
Resources/selection_distort.png
- Resources/move_ew.png
- Resources/move_ns.png
- Resources/disable.png
- Resources/move_z.png
- Resources/picker_style_line.png
- Resources/picker_style_area.png
- Resources/picker_style.png
- Resources/scale_global.png
- Resources/scale_hv.png
- Resources/normaleraser.png
- Resources/recteraser.png
- Resources/picker_style_organize.png
- Resources/picker_rgb.png
- Resources/picker_rgb_white.png
- Resources/pointing_hand.png
- Resources/karasu.png
- Resources/ruler_modify.png
- Resources/ruler_new.png
- Resources/ex_freehand.png
- Resources/ex_freehand_left.png
- Resources/ex_polyline.png
- Resources/ex_polyline_left.png
- Resources/ex_rectangle.png
- Resources/ex_rectangle_left.png
- Resources/ex_line.png
- Resources/ex_line_left.png
- Resources/ex_area.png
- Resources/ex_area_left.png
- Resources/ex_fill_no_autopaint.png
- Resources/ex_fill_no_autopaint_left.png
- Resources/edit_FX_notext.png
- Resources/move_z_notext.png
- Resources/scale_hv_notext.png
- Resources/ex_FX.png
- Resources/ex_FX_left.png
- Resources/ex_hv.png
- Resources/ex_hv_left.png
- Resources/ex_rgb.png
- Resources/ex_rgb_left.png
- Resources/ex_style_area.png
- Resources/ex_style_area_left.png
- Resources/ex_style_line.png
- Resources/ex_style_line_left.png
- Resources/ex_z.png
- Resources/ex_z_left.png
- Resources/ex_precise.png
- Resources/ex_precise_left.png
- Resources/brush_large.png
- Resources/brush_crosshair.png
- Resources/tracker.png
- Resources/ex_prev.png
- Resources/ex_prev_left.png
- Resources/ex_next.png
- Resources/ex_next_left.png
-
+ Resources/move_ew.png
+ Resources/move_ns.png
+ Resources/disable.png
+ Resources/move_z.png
+ Resources/picker_style_line.png
+ Resources/picker_style_area.png
+ Resources/picker_style.png
+ Resources/scale_global.png
+ Resources/scale_hv.png
+ Resources/normaleraser.png
+ Resources/recteraser.png
+ Resources/picker_style_organize.png
+ Resources/picker_rgb.png
+ Resources/picker_rgb_white.png
+ Resources/pointing_hand.png
+ Resources/karasu.png
+ Resources/ruler_modify.png
+ Resources/ruler_new.png
+ Resources/ex_freehand.png
+ Resources/ex_freehand_left.png
+ Resources/ex_freepick.png
+ Resources/ex_freepick_left.png
+ Resources/ex_polyline.png
+ Resources/ex_polyline_left.png
+ Resources/ex_rectangle.png
+ Resources/ex_rectangle_left.png
+ Resources/ex_line.png
+ Resources/ex_line_left.png
+ Resources/ex_area.png
+ Resources/ex_area_left.png
+ Resources/ex_fill_no_autopaint.png
+ Resources/ex_fill_no_autopaint_left.png
+ Resources/edit_FX_notext.png
+ Resources/move_z_notext.png
+ Resources/scale_hv_notext.png
+ Resources/ex_FX.png
+ Resources/ex_FX_left.png
+ Resources/ex_hv.png
+ Resources/ex_hv_left.png
+ Resources/ex_rgb.png
+ Resources/ex_rgb_left.png
+ Resources/ex_style_area.png
+ Resources/ex_style_area_left.png
+ Resources/ex_style_line.png
+ Resources/ex_style_line_left.png
+ Resources/ex_z.png
+ Resources/ex_z_left.png
+ Resources/ex_precise.png
+ Resources/ex_precise_left.png
+ Resources/brush_large.png
+ Resources/brush_crosshair.png
+ Resources/tracker.png
+ Resources/ex_prev.png
+ Resources/ex_prev_left.png
+ Resources/ex_next.png
+ Resources/ex_next_left.png
+
\ No newline at end of file
diff --git a/toonz/sources/toonz/icons/dark/actions/20/type_pickerlasso.svg b/toonz/sources/toonz/icons/dark/actions/20/type_pickerlasso.svg
new file mode 100644
index 0000000..412ea70
--- /dev/null
+++ b/toonz/sources/toonz/icons/dark/actions/20/type_pickerlasso.svg
@@ -0,0 +1,21 @@
+
+
diff --git a/toonz/sources/toonz/mainwindow.cpp b/toonz/sources/toonz/mainwindow.cpp
index ba2bda2..6f96bfb 100644
--- a/toonz/sources/toonz/mainwindow.cpp
+++ b/toonz/sources/toonz/mainwindow.cpp
@@ -2446,6 +2446,8 @@ void MainWindow::defineActions() {
ToolCommandType, "fill_freehand");
createAction(MI_FillPolyline, QT_TR_NOOP("Fill Tool - Polyline"), "",
ToolCommandType, "fill_polyline");
+ createAction(MI_FillFreepick, QT_TR_NOOP("Fill Tool - Pick+Freehand"), "",
+ ToolCommandType, "fill_freepick");
createAction(MI_FillNextMode, QT_TR_NOOP("Fill Tool - Next Mode"), "",
ToolCommandType);
createAction(MI_FillAreas, QT_TR_NOOP("Fill Tool - Areas"), "",
@@ -2672,6 +2674,11 @@ void MainWindow::defineActions() {
menuAct = createToolOptionsAction("A_ToolOption_Type:Polyline",
QT_TR_NOOP("Type - Polyline"), "");
menuAct->setIcon(createQIcon("type_polyline"));
+
+ menuAct = createToolOptionsAction("A_ToolOption_Type:Freepick",
+ QT_TR_NOOP("Type - Pick+Freehand"), "");
+ menuAct->setIcon(createQIcon("type_pickerlasso"));
+
menuAct = createToolOptionsAction("A_ToolOption_Type:Segment",
QT_TR_NOOP("Type - Segment"), "");
menuAct->setIcon(createQIcon("type_erase_segment"));
diff --git a/toonz/sources/toonz/menubarcommandids.h b/toonz/sources/toonz/menubarcommandids.h
index 6197228..583d87c 100644
--- a/toonz/sources/toonz/menubarcommandids.h
+++ b/toonz/sources/toonz/menubarcommandids.h
@@ -362,6 +362,7 @@
#define MI_FillRectangular "MI_FillRectangular"
#define MI_FillFreehand "MI_FillFreehand"
#define MI_FillPolyline "MI_FillPolyline"
+#define MI_FillFreepick "MI_FillFreepick"
#define MI_FillNextMode "MI_FillNextMode"
#define MI_FillAreas "MI_FillAreas"
#define MI_FillLines "MI_FillLines"
diff --git a/toonz/sources/toonz/tooloptionsshortcutinvoker.cpp b/toonz/sources/toonz/tooloptionsshortcutinvoker.cpp
index f181fe9..e3fd0b9 100644
--- a/toonz/sources/toonz/tooloptionsshortcutinvoker.cpp
+++ b/toonz/sources/toonz/tooloptionsshortcutinvoker.cpp
@@ -492,6 +492,8 @@ void ToolOptionsShortcutInvoker::initialize() {
&ToolOptionsShortcutInvoker::toggleFillFreehand);
setCommandHandler(MI_FillPolyline, this,
&ToolOptionsShortcutInvoker::toggleFillPolyline);
+ setCommandHandler(MI_FillFreepick, this,
+ &ToolOptionsShortcutInvoker::toggleFillFreepick);
setCommandHandler(MI_FillNextMode, this,
&ToolOptionsShortcutInvoker::toggleFillNextMode);
setCommandHandler(MI_FillAreas, this,
@@ -850,6 +852,14 @@ void ToolOptionsShortcutInvoker::toggleFillPolyline() {
->trigger();
}
+void ToolOptionsShortcutInvoker::toggleFillFreepick() {
+ CommandManager::instance()->getAction(T_Fill)->trigger();
+ CommandManager::instance()->getAction("A_ToolOption_Type:Normal")->trigger();
+ CommandManager::instance()
+ ->getAction("A_ToolOption_Type:Freepick")
+ ->trigger();
+}
+
void ToolOptionsShortcutInvoker::toggleFillNextMode() {
if (TApp::instance()->getCurrentTool()->getTool()->getName() == T_Fill)
CommandManager::instance()->getAction("A_ToolOption_Mode")->trigger();
diff --git a/toonz/sources/toonz/tooloptionsshortcutinvoker.h b/toonz/sources/toonz/tooloptionsshortcutinvoker.h
index f372e1d..2c83a02 100644
--- a/toonz/sources/toonz/tooloptionsshortcutinvoker.h
+++ b/toonz/sources/toonz/tooloptionsshortcutinvoker.h
@@ -196,6 +196,7 @@ protected slots:
void toggleFillRectangular();
void toggleFillFreehand();
void toggleFillPolyline();
+ void toggleFillFreepick();
void toggleFillNextMode();
void toggleFillAreas();
void toggleFillLines();
diff --git a/toonz/sources/toonz/toonz.qrc b/toonz/sources/toonz/toonz.qrc
index 57e7d66..33a0ff6 100644
--- a/toonz/sources/toonz/toonz.qrc
+++ b/toonz/sources/toonz/toonz.qrc
@@ -417,6 +417,7 @@
icons/dark/actions/20/selection_freehand.svg
icons/dark/actions/20/type_lasso.svg
+ icons/dark/actions/20/type_pickerlasso.svg
icons/dark/actions/20/type_rectangular.svg
icons/dark/actions/20/type_polyline.svg
icons/dark/actions/20/type_normal.svg
diff --git a/toonz/sources/toonzlib/fillutil.cpp b/toonz/sources/toonzlib/fillutil.cpp
index 523098f..f4e66ce 100644
--- a/toonz/sources/toonzlib/fillutil.cpp
+++ b/toonz/sources/toonzlib/fillutil.cpp
@@ -149,7 +149,7 @@ void fillautoInks(TRasterCM32P &rin, TRect &rect, const TRasterCM32P &rbefore,
int paint = pix->getPaint();
int tone = pix->getTone();
int ink = pix->getInk();
- if (paint != pixb->getPaint() && tone > 0 && tone < 255 && ink != paint &&
+ if (paint != pixb->getPaint() && ink != paint &&
plt->getStyle(ink)->getFlags() != 0)
inkFill(rin, TPoint(j, i) + rect.getP00(), paint, 0, NULL, &rect);
}