diff --git a/toonz/sources/include/tools/modifiers/modifiersmooth.h b/toonz/sources/include/tools/modifiers/modifiersmooth.h new file mode 100644 index 0000000..6968d38 --- /dev/null +++ b/toonz/sources/include/tools/modifiers/modifiersmooth.h @@ -0,0 +1,54 @@ +#pragma once + +#ifndef MODIFIERSMOOTH_INCLUDED +#define MODIFIERSMOOTH_INCLUDED + +// TnzTools includes +#include + + +#undef DVAPI +#undef DVVAR +#ifdef TNZTOOLS_EXPORTS +#define DVAPI DV_EXPORT_API +#define DVVAR DV_EXPORT_VAR +#else +#define DVAPI DV_IMPORT_API +#define DVVAR DV_IMPORT_VAR +#endif + + +//=================================================================== + +//***************************************************************************************** +// TModifierSmooth definition +//***************************************************************************************** + +class DVAPI TModifierSmooth: public TInputModifier { +public: + class DVAPI Modifier: public TTrackModifier { + public: + const int radius; + TTrack *smoothedTrack; + + Modifier(TTrackHandler &handler, int radius); + TTrackPoint calcPoint(double originalIndex) override; + }; + +private: + int m_radius; + +public: + TModifierSmooth(int radius = 10); + + void setRadius(int radius); + int getRadius() const { return m_radius; } + + void modifyTrack( + const TTrack &track, + TTrackList &outTracks ) override; +}; + + +#endif + diff --git a/toonz/sources/tnztools/CMakeLists.txt b/toonz/sources/tnztools/CMakeLists.txt index 101eb4e..2675853 100644 --- a/toonz/sources/tnztools/CMakeLists.txt +++ b/toonz/sources/tnztools/CMakeLists.txt @@ -54,7 +54,7 @@ set(HEADERS ../include/tools/modifiers/modifiertangents.h ../include/tools/modifiers/modifiertest.h ../include/tools/modifiers/modifiersegmentation.h - ../include/tools/modifiers/modifierassistants.h + ../include/tools/modifiers/modifiersmooth.h ../include/tools/assistants/guidelineline.h ../include/tools/assistants/guidelineellipse.h ) @@ -130,6 +130,7 @@ set(SOURCES modifiers/modifiertangents.cpp modifiers/modifiertest.cpp modifiers/modifiersegmentation.cpp + modifiers/modifiersmooth.cpp assistants/guidelineline.cpp assistants/guidelineellipse.cpp assistants/assistantvanishingpoint.cpp diff --git a/toonz/sources/tnztools/modifiers/modifiersmooth.cpp b/toonz/sources/tnztools/modifiers/modifiersmooth.cpp new file mode 100644 index 0000000..261a801 --- /dev/null +++ b/toonz/sources/tnztools/modifiers/modifiersmooth.cpp @@ -0,0 +1,115 @@ + + +#include +#include + + +//***************************************************************************************** +// TModifierSmooth::Modifier implementation +//***************************************************************************************** + + +TModifierSmooth::Modifier::Modifier(TTrackHandler &handler, int radius): + TTrackModifier(handler), + radius(std::max(radius, 0)), + smoothedTrack() +{ } + + +TTrackPoint +TModifierSmooth::Modifier::calcPoint(double originalIndex) { + return smoothedTrack + ? smoothedTrack->interpolateLinear(originalIndex) + : TTrackModifier::calcPoint(originalIndex); +} + + +//***************************************************************************************** +// TModifierSmooth implementation +//***************************************************************************************** + + +TModifierSmooth::TModifierSmooth(int radius): m_radius() + { setRadius(radius); } + + +void +TModifierSmooth::setRadius(int radius) + { m_radius = std::max(0, radius); } + + +void +TModifierSmooth::modifyTrack( + const TTrack &track, + TTrackList &outTracks ) +{ + if (!m_radius) { + TInputModifier::modifyTrack(track, outTracks); + return; + } + + if (!track.handler) { + track.handler = new TTrackHandler(track); + Modifier *modifier = new Modifier(*track.handler, m_radius); + modifier->smoothedTrack = new TTrack(modifier); + track.handler->tracks.push_back(modifier->smoothedTrack); + } + + if (track.handler->tracks.empty()) + return; + + TTrack &subTrack = *track.handler->tracks.front(); + outTracks.push_back(track.handler->tracks.front()); + + if (!track.changed()) + return; + + Modifier *modifier = dynamic_cast(subTrack.modifier.getPointer()); + if (!modifier) + return; + int radius = modifier->radius; + + // remove points + int start = std::max(0, track.size() - track.pointsAdded - radius); + subTrack.truncate(start); + + // add points + double k = 1.0/(2*radius + 1); + TTrackTangent accum; + for(int i = start - 2*radius; i < track.size(); ++i) { + const TTrackPoint &p1 = track[i + radius]; + accum.position += p1.position; + accum.pressure += p1.pressure; + accum.tilt += p1.tilt; + if (i < start) + continue; + + const TTrackPoint &p = track[i]; + subTrack.push_back( + TTrackPoint( + accum.position*k, + accum.pressure*k, + accum.tilt*k, + i, + p.time, + 0, + p.final ), + false ); + + const TTrackPoint &p0 = track[i - radius]; + accum.position -= p0.position; + accum.pressure -= p0.pressure; + accum.tilt -= p0.tilt; + } + + // fix points + if (track.fixedFinished()) { + subTrack.fix_all(); + } else + if (track.fixedSize() > radius) { + subTrack.fix_to(track.fixedSize() - radius); + } + + track.resetChanges(); +} + diff --git a/toonz/sources/tnztools/toonzrasterbrushtool.cpp b/toonz/sources/tnztools/toonzrasterbrushtool.cpp index ad71c14..218aea2 100644 --- a/toonz/sources/tnztools/toonzrasterbrushtool.cpp +++ b/toonz/sources/tnztools/toonzrasterbrushtool.cpp @@ -911,13 +911,16 @@ ToonzRasterBrushTool::ToonzRasterBrushTool(std::string name, int targetType) m_modifierLockAlpha.setId("LockAlpha"); m_inputmanager.setHandler(this); + m_modifierLine = new TModifierLine(); + m_modifierTangents = new TModifierTangents(); + m_modifierAssistants = new TModifierAssistants(); + m_modifierSegmentation = new TModifierSegmentation(); + m_modifierSmoothSegmentation = new TModifierSegmentation(); + for(int i = 0; i < 3; ++i) + m_modifierSmooth[i] = new TModifierSmooth(); #ifndef NDEBUG m_modifierTest = new TModifierTest(5, 40); #endif - m_modifierLine = new TModifierLine(); - m_modifierTangents = new TModifierTangents(); - m_modifierAssistants = new TModifierAssistants(); - m_modifierSegmentation = new TModifierSegmentation(); m_inputmanager.addModifier( TInputModifierP(m_modifierAssistants.getPointer())); @@ -1170,14 +1173,22 @@ bool ToonzRasterBrushTool::askWrite(const TRect &rect) { //-------------------------------------------------------------------------------------------------- bool ToonzRasterBrushTool::preLeftButtonDown() { + int smoothRadius = (int)round(m_smooth.getValue()); m_modifierAssistants->drawOnly = true; - m_inputmanager.drawPreview = false; //! m_modifierAssistants->drawOnly; + m_inputmanager.drawPreview = true;//bwtodo: false; //! m_modifierAssistants->drawOnly; m_inputmanager.clearModifiers(); m_inputmanager.addModifier(TInputModifierP(m_modifierTangents.getPointer())); + if (smoothRadius > 0) { + m_inputmanager.addModifier(TInputModifierP(m_modifierSmoothSegmentation.getPointer())); + for(int i = 0; i < 3; ++i) { + m_modifierSmooth[i]->setRadius(smoothRadius); + m_inputmanager.addModifier(TInputModifierP(m_modifierSmooth[i].getPointer())); + } + } m_inputmanager.addModifier(TInputModifierP(m_modifierAssistants.getPointer())); #ifndef NDEBUG - m_inputmanager.addModifier(TInputModifierP(m_modifierTest.getPointer())); + //m_inputmanager.addModifier(TInputModifierP(m_modifierTest.getPointer())); #endif m_inputmanager.addModifier(TInputModifierP(m_modifierSegmentation.getPointer())); diff --git a/toonz/sources/tnztools/toonzrasterbrushtool.h b/toonz/sources/tnztools/toonzrasterbrushtool.h index b2e3cda..47cfa07 100644 --- a/toonz/sources/tnztools/toonzrasterbrushtool.h +++ b/toonz/sources/tnztools/toonzrasterbrushtool.h @@ -19,6 +19,7 @@ #include #include #include +#include #ifndef NDEBUG #include #endif @@ -200,13 +201,15 @@ private: protected: TInputManager m_inputmanager; -#ifndef NDEBUG - TSmartPointerT m_modifierTest; -#endif TSmartPointerT m_modifierLine; TSmartPointerT m_modifierTangents; TSmartPointerT m_modifierAssistants; TSmartPointerT m_modifierSegmentation; + TSmartPointerT m_modifierSmoothSegmentation; + TSmartPointerT m_modifierSmooth[3]; +#ifndef NDEBUG + TSmartPointerT m_modifierTest; +#endif class MyPaintStroke: public TTrackToolHandler { public: