diff --git a/toonz/sources/include/toonz/strokegenerator.h b/toonz/sources/include/toonz/strokegenerator.h index 5d8c1d3..84b69dd 100644 --- a/toonz/sources/include/toonz/strokegenerator.h +++ b/toonz/sources/include/toonz/strokegenerator.h @@ -83,6 +83,9 @@ In caso affermativo li cancella. //! Visualizza tutti i frammenti void drawAllFragments(); + // Only keep first and last points. Used for straight lines + void removeMiddlePoints(); + //! Restituisce il rettangolo che contiene la regione modificata TRectD getModifiedRegion() const; diff --git a/toonz/sources/tnztools/brushtool.cpp b/toonz/sources/tnztools/brushtool.cpp index 1cb08c7..54c1a72 100644 --- a/toonz/sources/tnztools/brushtool.cpp +++ b/toonz/sources/tnztools/brushtool.cpp @@ -27,6 +27,7 @@ #include "toonz/toonzimageutils.h" #include "toonz/palettecontroller.h" #include "toonz/stage2.h" +#include "toonz/preferences.h" // TnzCore includes #include "tstream.h" @@ -675,6 +676,15 @@ void SmoothStroke::endStroke() { //-------------------------------------------------------------------------------------------------- +void SmoothStroke::clearPoints() { + m_outputIndex = 0; + m_readIndex = -1; + m_outputPoints.clear(); + m_rawPoints.clear(); +} + +//-------------------------------------------------------------------------------------------------- + void SmoothStroke::getSmoothPoints(std::vector &smoothPoints) { int n = m_outputPoints.size(); for (int i = m_readIndex + 1; i <= m_outputIndex && i < n; ++i) { @@ -1285,7 +1295,15 @@ void BrushTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) { (m_pressure.getValue() || m_isPath) ? computeThickness(e.m_pressure, m_thickness, m_isPath) : m_thickness.getValue().second * 0.5; - addTrackPoint(TThickPoint(pos, thickness), getPixelSize() * getPixelSize()); + + if (e.isShiftPressed()) { + m_smoothStroke.clearPoints(); + m_track.add(TThickPoint(pos, thickness), getPixelSize() * getPixelSize()); + m_track.removeMiddlePoints(); + } else { + addTrackPoint(TThickPoint(pos, thickness), + getPixelSize() * getPixelSize()); + } invalidate(); } } @@ -1300,9 +1318,16 @@ void BrushTool::leftButtonUp(const TPointD &pos, const TMouseEvent &e) { if (m_isPath) { double error = 20.0 * getPixelSize(); - flushTrackPoint(); - TStroke *stroke = m_track.makeStroke(error); - int points = stroke->getControlPointCount(); + + TStroke *stroke; + if (e.isShiftPressed()) { + m_track.removeMiddlePoints(); + stroke = m_track.makeStroke(0); + } else { + flushTrackPoint(); + stroke = m_track.makeStroke(error); + } + int points = stroke->getControlPointCount(); if (TVectorImageP vi = getImage(true)) { struct Cleanup { @@ -1348,8 +1373,14 @@ void BrushTool::leftButtonUp(const TPointD &pos, const TMouseEvent &e) { double error = 30.0 / (1 + 0.5 * m_accuracy.getValue()); error *= getPixelSize(); - flushTrackPoint(); - TStroke *stroke = m_track.makeStroke(error); + TStroke *stroke; + if (e.isShiftPressed()) { + m_track.removeMiddlePoints(); + stroke = m_track.makeStroke(0); + } else { + flushTrackPoint(); + stroke = m_track.makeStroke(error); + } stroke->setStyle(m_styleId); { TStroke::OutlineOptions &options = stroke->outlineOptions(); @@ -1674,7 +1705,9 @@ void BrushTool::mouseMove(const TPointD &pos, const TMouseEvent &e) { void BrushTool::draw() { /*--ショートカットでのツール切り替え時に赤点が描かれるのを防止する--*/ - if (m_minThick == 0 && m_maxThick == 0) return; + if (m_minThick == 0 && m_maxThick == 0 && + !Preferences::instance()->getShow0ThickLines()) + return; TImageP img = getImage(false, 1); diff --git a/toonz/sources/tnztools/brushtool.h b/toonz/sources/tnztools/brushtool.h index 03765ed..23b18da 100644 --- a/toonz/sources/tnztools/brushtool.h +++ b/toonz/sources/tnztools/brushtool.h @@ -90,6 +90,8 @@ public: // Both addPoint() and endStroke() generate new smoothed points. // This method will removed generated points void getSmoothPoints(std::vector &smoothPoints); + // Remove all points - used for straight lines + void clearPoints(); private: void generatePoints(); diff --git a/toonz/sources/toonzlib/strokegenerator.cpp b/toonz/sources/toonzlib/strokegenerator.cpp index 1fde00f..1a9469a 100644 --- a/toonz/sources/toonzlib/strokegenerator.cpp +++ b/toonz/sources/toonzlib/strokegenerator.cpp @@ -5,6 +5,7 @@ //#include "tofflinegl.h" #include "tstroke.h" +#include "toonz/preferences.h" using namespace std; @@ -117,10 +118,46 @@ void StrokeGenerator::drawFragments(int first, int last) { TThickPoint c; TPointD v; + // If drawing a straight line, a stroke can have only two points + if (m_points.size() == 2) { + a = m_points[0]; + b = m_points[1]; + if (Preferences::instance()->getShow0ThickLines()) { + if (a.thick == 0) a.thick = 0.1; + if (b.thick == 0) b.thick = 0.1; + } + // m_p0 = m_p1 = b; + assert(tdistance(b, a) > h); + v = a.thick * normalize(rotate90(b - a)); + m_p0 = a + v; + m_p1 = a - v; + v = b.thick * normalize(rotate90(b - a)); + TPointD p0 = b + v; + TPointD p1 = b - v; + glBegin(GL_POLYGON); + tglVertex(m_p0); + tglVertex(m_p1); + tglVertex(p1); + tglVertex(p0); + glEnd(); + m_p0 = p0; + m_p1 = p1; + glBegin(GL_LINE_STRIP); + tglVertex(a); + tglVertex(b); + glEnd(); + return; + } + while (i < last) { a = m_points[i - 1]; b = m_points[i]; c = m_points[i + 1]; + if (Preferences::instance()->getShow0ThickLines()) { + if (a.thick == 0) a.thick = 0.1; + if (b.thick == 0) b.thick = 0.1; + if (c.thick == 0) c.thick = 0.1; + } if (a.thick >= h && b.thick >= h && tdistance2(b, a) >= h && tdistance2(a, c) >= h) { if (i - 1 == 0) { @@ -205,6 +242,15 @@ TRectD StrokeGenerator::getModifiedRegion() const { return m_modifiedRegion; } //------------------------------------------------------------------- +void StrokeGenerator::removeMiddlePoints() { + int size = m_points.size(); + if (size > 2) { + m_points.erase(m_points.begin() + 1, m_points.begin() + (size - 1)); + } +} + +//------------------------------------------------------------------- + TRectD StrokeGenerator::getLastModifiedRegion() { TRectD lastModifiedRegion = m_lastModifiedRegion; m_lastModifiedRegion.empty();