Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 28636dc

Browse files
committed
fix brush smoothing
1 parent ef852c9 commit 28636dc

File tree

2 files changed

+48
-21
lines changed

2 files changed

+48
-21
lines changed

toonz/sources/tnztools/toonzrasterbrushtool.cpp

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,8 @@ static void CatmullRomInterpolate(const TThickPoint &P0, const TThickPoint &P1,
655655

656656
//--------------------------------------------------------------------------------------------------
657657

658-
static void Smooth(std::vector<TThickPoint> &points, int radius) {
658+
static void Smooth(std::vector<TThickPoint> &points, const int radius,
659+
const int readIndex, const int level) {
659660
int n = (int)points.size();
660661
if (radius < 1 || n < 3) {
661662
return;
@@ -665,7 +666,10 @@ static void Smooth(std::vector<TThickPoint> &points, int radius) {
665666

666667
float d = 1.0f / (radius * 2 + 1);
667668

668-
for (int i = 1; i < n - 1; ++i) {
669+
int endSamples = 10;
670+
int startId = std::max(readIndex - endSamples * 3 - radius * level, 1);
671+
672+
for (int i = startId; i < n - 1; ++i) {
669673
int lower = i - radius;
670674
int upper = i + radius;
671675

@@ -692,21 +696,23 @@ static void Smooth(std::vector<TThickPoint> &points, int radius) {
692696
result.push_back(total);
693697
}
694698

695-
for (int i = 1; i < n - 1; ++i) {
696-
points[i].x = result[i - 1].x;
697-
points[i].y = result[i - 1].y;
698-
points[i].thick = result[i - 1].thick;
699+
auto result_itr = result.begin();
700+
for (int i = startId; i < n - 1; ++i, ++result_itr) {
701+
points[i].x = (*result_itr).x;
702+
points[i].y = (*result_itr).y;
703+
points[i].thick = (*result_itr).thick;
699704
}
700705

701706
if (points.size() >= 3) {
702707
std::vector<TThickPoint> pts;
703-
CatmullRomInterpolate(points[0], points[0], points[1], points[2], 10, pts);
708+
CatmullRomInterpolate(points[0], points[0], points[1], points[2],
709+
endSamples, pts);
704710
std::vector<TThickPoint>::iterator it = points.begin() + 1;
705711
points.insert(it, pts.begin(), pts.end());
706712

707713
pts.clear();
708714
CatmullRomInterpolate(points[n - 3], points[n - 2], points[n - 1],
709-
points[n - 1], 10, pts);
715+
points[n - 1], endSamples, pts);
710716
it = points.begin();
711717
it += n - 1;
712718
points.insert(it, pts.begin(), pts.end());
@@ -721,6 +727,8 @@ void SmoothStroke::beginStroke(int smooth) {
721727
m_readIndex = -1;
722728
m_rawPoints.clear();
723729
m_outputPoints.clear();
730+
m_resampledIndex = 0;
731+
m_resampledPoints.clear();
724732
}
725733

726734
//--------------------------------------------------------------------------------------------------
@@ -749,6 +757,8 @@ void SmoothStroke::clearPoints() {
749757
m_readIndex = -1;
750758
m_outputPoints.clear();
751759
m_rawPoints.clear();
760+
m_resampledIndex = 0;
761+
m_resampledPoints.clear();
752762
}
753763

754764
//--------------------------------------------------------------------------------------------------
@@ -781,26 +791,40 @@ void SmoothStroke::generatePoints() {
781791
return;
782792
}
783793

784-
std::vector<TThickPoint> smoothedPoints;
794+
std::vector<TThickPoint> smoothedPoints = m_resampledPoints;
785795
// Add more stroke samples before applying the smoothing
786796
// This is because the raw inputs points are too few to support smooth result,
787797
// especially on stroke ends
788-
smoothedPoints.push_back(m_rawPoints.front());
789-
for (int i = 1; i < n; ++i) {
790-
const TThickPoint &p1 = m_rawPoints[i - 1];
791-
const TThickPoint &p2 = m_rawPoints[i];
792-
const TThickPoint &p0 = i - 2 >= 0 ? m_rawPoints[i - 2] : p1;
793-
const TThickPoint &p3 = i + 1 < n ? m_rawPoints[i + 1] : p2;
794-
795-
int samples = 8;
796-
CatmullRomInterpolate(p0, p1, p2, p3, samples, smoothedPoints);
797-
smoothedPoints.push_back(p2);
798+
799+
int resampleStartId = m_resampledIndex;
800+
for (int i = resampleStartId; i < n - 1; ++i) {
801+
const TThickPoint &p1 = m_rawPoints[i];
802+
const TThickPoint &p2 = m_rawPoints[i + 1];
803+
const TThickPoint &p0 = i - 1 >= 0 ? m_rawPoints[i - 1] : p1;
804+
const TThickPoint &p3 = i + 2 < n ? m_rawPoints[i + 2] : p2;
805+
806+
std::vector<TThickPoint> tmpResampled;
807+
tmpResampled.push_back(p1);
808+
// define subsample amount according to distance between points
809+
int samples = std::min((int)tdistance(p1, p2), 8);
810+
if (samples >= 1)
811+
CatmullRomInterpolate(p0, p1, p2, p3, samples, tmpResampled);
812+
813+
if (i + 2 < n) {
814+
m_resampledIndex = i + 1;
815+
std::copy(tmpResampled.begin(), tmpResampled.end(),
816+
std::back_inserter(m_resampledPoints));
817+
}
818+
std::copy(tmpResampled.begin(), tmpResampled.end(),
819+
std::back_inserter(smoothedPoints));
798820
}
821+
smoothedPoints.push_back(m_rawPoints.back());
799822
// Apply the 1D box filter
800823
// Multiple passes result in better quality and fix the stroke ends break
801824
// issue
802-
for (int i = 0; i < 3; ++i) {
803-
Smooth(smoothedPoints, m_smooth);
825+
// level is passed to define range where the points are smoothed
826+
for (int level = 2; level >= 0; --level) {
827+
Smooth(smoothedPoints, m_smooth, m_readIndex, level);
804828
}
805829
// Compare the new smoothed stroke with old one
806830
// Enable the output for unchanged parts

toonz/sources/tnztools/toonzrasterbrushtool.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ class SmoothStroke {
109109
int m_readIndex;
110110
std::vector<TThickPoint> m_rawPoints;
111111
std::vector<TThickPoint> m_outputPoints;
112+
113+
int m_resampledIndex;
114+
std::vector<TThickPoint> m_resampledPoints;
112115
};
113116
//************************************************************************
114117
// Toonz Raster Brush Tool declaration

0 commit comments

Comments
 (0)