From b2c9e7ec251263b758c616f402858696ad2a6b81 Mon Sep 17 00:00:00 2001
From: Ivan Mahonin <bh@icystar.com>
Date: Aug 09 2023 05:10:40 +0000
Subject: #assistants: fix smooth


---

diff --git a/toonz/sources/include/tools/modifiers/modifiersegmentation.h b/toonz/sources/include/tools/modifiers/modifiersegmentation.h
index a979c8b..48d8872 100644
--- a/toonz/sources/include/tools/modifiers/modifiersegmentation.h
+++ b/toonz/sources/include/tools/modifiers/modifiersegmentation.h
@@ -27,14 +27,18 @@
 class DVAPI TModifierSegmentation: public TInputModifier {
 private:
   TPointD m_step;
+  int m_maxLevel;
   
-  void addSegments(TTrack &track, const TTrackPoint &p0, const TTrackPoint &p1, int level = 0);
+  void addSegments(TTrack &track, const TTrackPoint &p0, const TTrackPoint &p1, int maxLevel);
 
 public:
-  TModifierSegmentation(const TPointD &step = TPointD(1.0, 1.0));
+  TModifierSegmentation(const TPointD &step = TPointD(1.0, 1.0), int level = 10);
 
   void setStep(const TPointD &step);
-  const TPointD& getStep() const { return m_step; }
+  inline const TPointD& getStep() const { return m_step; }
+
+  void setMaxLevel(int maxLevel);
+  inline int getMaxLevel() const { return m_maxLevel; }
   
   void modifyTrack(
     const TTrack &track,
diff --git a/toonz/sources/tnztools/modifiers/modifiersegmentation.cpp b/toonz/sources/tnztools/modifiers/modifiersegmentation.cpp
index 1fdf154..1fbb4c0 100644
--- a/toonz/sources/tnztools/modifiers/modifiersegmentation.cpp
+++ b/toonz/sources/tnztools/modifiers/modifiersegmentation.cpp
@@ -9,8 +9,9 @@
 //*****************************************************************************************
 
 
-TModifierSegmentation::TModifierSegmentation(const TPointD &step)
-  { setStep(step); }
+TModifierSegmentation::TModifierSegmentation(const TPointD &step, int maxLevel):
+  m_maxLevel(0)
+  { setStep(step); setMaxLevel(maxLevel); }
 
 
 void
@@ -21,23 +22,29 @@ TModifierSegmentation::setStep(const TPointD &step) {
 
 
 void
+TModifierSegmentation::setMaxLevel(int maxLevel) {
+  m_maxLevel = std::max(0, maxLevel);
+}
+
+
+void
 TModifierSegmentation::addSegments(
   TTrack &track,
   const TTrackPoint &p0,
   const TTrackPoint &p1,
   int level)
 {
-  static const int maxRecursion = 10;
   TPointD d = p1.position - p0.position;
 
-  if (level >= maxRecursion || (fabs(d.x) <= m_step.x && fabs(d.y) <= m_step.y)) {
+  if (level <= 0 || (fabs(d.x) <= m_step.x && fabs(d.y) <= m_step.y)) {
     track.push_back(p1, false);
     return;
   }
 
+  --level;
   TTrackPoint p = track.modifier->calcPoint(0.5*(p0.originalIndex + p1.originalIndex));
-  addSegments(track, p0, p, level + 1);
-  addSegments(track, p, p1, level + 1);
+  addSegments(track, p0, p, level);
+  addSegments(track, p, p1, level);
 }
 
 
@@ -72,7 +79,7 @@ TModifierSegmentation::modifyTrack(
   TTrackPoint p0 = subTrack.modifier->calcPoint(start - 1);
   for(int i = start; i < track.size(); ++i) {
     TTrackPoint p1 = subTrack.modifier->calcPoint(i);
-    addSegments(subTrack, p0, p1);
+    addSegments(subTrack, p0, p1, m_maxLevel);
     p0 = p1;
   }
 
diff --git a/toonz/sources/tnztools/modifiers/modifiersmooth.cpp b/toonz/sources/tnztools/modifiers/modifiersmooth.cpp
index 261a801..449623f 100644
--- a/toonz/sources/tnztools/modifiers/modifiersmooth.cpp
+++ b/toonz/sources/tnztools/modifiers/modifiersmooth.cpp
@@ -70,33 +70,37 @@ TModifierSmooth::modifyTrack(
   int radius = modifier->radius;
 
   // remove points
-  int start = std::max(0, track.size() - track.pointsAdded - radius);
+  int start = std::max(0, track.size() - track.pointsAdded);
   subTrack.truncate(start);
 
   // add points
+  // extra points will be added at the beginning and at the end
+  int size = track.size() + 2*radius;
   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];
+  for(int i = start - 2*radius; i < size; ++i) {
+    
+    const TTrackPoint &p1 = track[i];
     accum.position += p1.position;
     accum.pressure += p1.pressure;
     accum.tilt     += p1.tilt;
     if (i < start)
       continue;
 
-    const TTrackPoint &p = track[i];
+    int oi = track.clampIndex(i - radius);
+    const TTrackPoint &p = track[oi];
     subTrack.push_back(
       TTrackPoint(
         accum.position*k,
         accum.pressure*k,
         accum.tilt*k,
-        i,
+        oi,
         p.time,
         0,
         p.final ),
       false );
     
-    const TTrackPoint &p0 = track[i - radius];
+    const TTrackPoint &p0 = track[i - 2*radius];
     accum.position -= p0.position;
     accum.pressure -= p0.pressure;
     accum.tilt     -= p0.tilt;
@@ -106,8 +110,8 @@ TModifierSmooth::modifyTrack(
   if (track.fixedFinished()) {
     subTrack.fix_all();
   } else
-  if (track.fixedSize() > radius) {
-    subTrack.fix_to(track.fixedSize() - radius);
+  if (track.fixedSize()) {
+    subTrack.fix_to(track.fixedSize());
   }
   
   track.resetChanges();
diff --git a/toonz/sources/tnztools/modifiers/modifiertangents.cpp b/toonz/sources/tnztools/modifiers/modifiertangents.cpp
index 7f6c533..c7f11e0 100644
--- a/toonz/sources/tnztools/modifiers/modifiertangents.cpp
+++ b/toonz/sources/tnztools/modifiers/modifiertangents.cpp
@@ -96,7 +96,8 @@ TModifierTangents::modifyTrack(
     return;
   
   // update subTrack
-  int start = track.size() - track.pointsAdded - 1;
+  int start = track.size() - track.pointsAdded;
+  if (start > 1) --start;
   if (start < 0) start = 0;
   subTrack.truncate(start);
   for(int i = start; i < track.size(); ++i)
@@ -112,7 +113,7 @@ TModifierTangents::modifyTrack(
     subTrack.fix_all();
   } else
   if (track.fixedSize()) {
-    subTrack.fix_to(std::max(track.fixedSize() - 1, 0));
+    subTrack.fix_to(std::max(track.fixedSize() - 1, 1));
   }
   
   track.resetChanges();
diff --git a/toonz/sources/tnztools/toonzrasterbrushtool.cpp b/toonz/sources/tnztools/toonzrasterbrushtool.cpp
index d21e100..488a77b 100644
--- a/toonz/sources/tnztools/toonzrasterbrushtool.cpp
+++ b/toonz/sources/tnztools/toonzrasterbrushtool.cpp
@@ -915,7 +915,7 @@ ToonzRasterBrushTool::ToonzRasterBrushTool(std::string name, int targetType)
   m_modifierTangents           = new TModifierTangents();
   m_modifierAssistants         = new TModifierAssistants();
   m_modifierSegmentation       = new TModifierSegmentation();
-  m_modifierSmoothSegmentation = new TModifierSegmentation();
+  m_modifierSmoothSegmentation = new TModifierSegmentation(TPointD(1, 1), 3);
   for(int i = 0; i < 3; ++i)
     m_modifierSmooth[i]        = new TModifierSmooth();
 #ifndef NDEBUG