From 00337d080edb94cab7852df1062fff107b7626de Mon Sep 17 00:00:00 2001
From: Ivan Mahonin <bh@icystar.com>
Date: May 01 2023 07:52:44 +0000
Subject: #assistants: fix interpolation


---

diff --git a/toonz/sources/include/tools/track.h b/toonz/sources/include/tools/track.h
index 0ff907a..eff0c65 100644
--- a/toonz/sources/include/tools/track.h
+++ b/toonz/sources/include/tools/track.h
@@ -229,6 +229,13 @@ public:
   inline const TTrackPointList& points() const
     { return m_points; }
 
+  inline void resetRemoved() const
+    { pointsRemoved = 0; }
+  inline void resetAdded() const
+    { pointsAdded = 0; }
+  inline void resetChanges() const
+    { resetRemoved(); resetAdded(); }
+
   void push_back(const TTrackPoint &point);
   void pop_back(int count = 1);
 
diff --git a/toonz/sources/tnztools/fullcolorbrushtool.cpp b/toonz/sources/tnztools/fullcolorbrushtool.cpp
index 848a205..823b0cf 100644
--- a/toonz/sources/tnztools/fullcolorbrushtool.cpp
+++ b/toonz/sources/tnztools/fullcolorbrushtool.cpp
@@ -619,6 +619,11 @@ void FullColorBrushTool::inputMouseMove(
 
 //-------------------------------------------------------------------------------------------------------------
 
+void FullColorBrushTool::inputInvalidateRect(const TRectD &bounds)
+  { invalidate(bounds); }
+
+//-------------------------------------------------------------------------------------------------------------
+
 void FullColorBrushTool::draw() {
   if (TRasterImageP ri = TRasterImageP(getImage(false))) {
     // Draw line segment on straight line mode
diff --git a/toonz/sources/tnztools/fullcolorbrushtool.h b/toonz/sources/tnztools/fullcolorbrushtool.h
index 6f2b38a..b3d6b63 100644
--- a/toonz/sources/tnztools/fullcolorbrushtool.h
+++ b/toonz/sources/tnztools/fullcolorbrushtool.h
@@ -66,6 +66,7 @@ public:
   void inputLeftButtonDrag(const TTrackPoint &point, const TTrack &track) override;
   void inputLeftButtonUp(const TTrackPoint &point, const TTrack &track) override;
   void inputMouseMove(const TPointD &position, const TInputState &state) override;
+  void inputInvalidateRect(const TRectD &bounds) override;
 
   void draw() override;
 
diff --git a/toonz/sources/tnztools/inputmanager.cpp b/toonz/sources/tnztools/inputmanager.cpp
index 1d9af83..76ef14a 100644
--- a/toonz/sources/tnztools/inputmanager.cpp
+++ b/toonz/sources/tnztools/inputmanager.cpp
@@ -45,26 +45,14 @@ TInputModifier::modifyTrack(
   if (!track.changed())
     return;
 
-  int start = track.size() - track.pointsAdded;
-  if (start < 0) start = 0;
-
+  int start = std::max(0, track.size() - track.pointsAdded);
   for(TTrackList::const_iterator ti = track.handler->tracks.begin(); ti != track.handler->tracks.end(); ++ti) {
     TTrack &subTrack = **ti;
-
-    // remove points
-    if (start < track.size()) {
-      subTrack.pointsRemoved += subTrack.size() - start;
-      subTrack.truncate(start);
-    }
-
-    // add points
+    subTrack.truncate(start);
     for(int i = start; i < track.size(); ++i)
       subTrack.push_back( subTrack.modifier->calcPoint(i) );
-    subTrack.pointsAdded += subTrack.size() - start;
   }
-
-  track.pointsRemoved = 0;
-  track.pointsAdded = 0;
+  track.resetChanges();
 }
 
 
@@ -225,15 +213,15 @@ TInputManager::paintRollbackTo(int saveIndex, TTrackList &subTracks) {
   for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) {
     TTrack &track = **i;
     if (TrackHandler *handler = dynamic_cast<TrackHandler*>(track.handler.getPointer())) {
-      handler->saves.erase(handler->saves.begin() + level, handler->saves.end());
+      handler->saves.resize(level);
       int cnt = handler->saves[saveIndex];
-      track.pointsRemoved = 0;
+      track.resetRemoved();
       track.pointsAdded = track.size() - cnt;
     }
   }
   for(int i = level; i < (int)m_savePoints.size(); ++i)
     m_savePoints[i].savePoint()->available = false;
-  m_savePoints.erase(m_savePoints.begin() + level, m_savePoints.end());
+  m_savePoints.resize(level);
 }
 
 
@@ -264,15 +252,15 @@ TInputManager::paintApply(int count, TTrackList &subTracks) {
     TTrack &track = **i;
     if (TrackHandler *handler = dynamic_cast<TrackHandler*>(track.handler.getPointer())) {
       if (resend) {
-        track.pointsRemoved = 0;
+        track.resetRemoved();
         track.pointsAdded = track.size() - handler->saves[m_savePointsSent];
       }
-      handler->saves.erase(handler->saves.begin() + level, handler->saves.end());
+      handler->saves.resize(level);
     }
   }
   for(int i = level; i < (int)m_savePoints.size(); ++i)
     m_savePoints[i].savePoint()->available = false;
-  m_savePoints.erase(m_savePoints.begin() + level, m_savePoints.end());
+  m_savePoints.resize(level);
 }
 
 
@@ -321,11 +309,8 @@ TInputManager::paintTracks() {
     // send to handler
     if (m_savePointsSent == (int)m_savePoints.size() && !subTracks.empty() && m_handler)
       m_handler->inputPaintTracks(subTracks);
-    for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i) {
-      TTrack &track = **i;
-      track.pointsRemoved = 0;
-      track.pointsAdded = 0;
-    }
+    for(TTrackList::const_iterator i = subTracks.begin(); i != subTracks.end(); ++i)
+      (*i)->resetChanges();
 
     // is paint finished?
     newSavePoint.unlock();
@@ -437,7 +422,6 @@ TInputManager::addTrackPoint(
     time,
     0.0, // length will calculated inside of TTrack::push_back
     final ));
-  ++track->pointsAdded;
 }
 
 
diff --git a/toonz/sources/tnztools/modifiersegmentation.cpp b/toonz/sources/tnztools/modifiersegmentation.cpp
index 6069bb9..dc00b39 100644
--- a/toonz/sources/tnztools/modifiersegmentation.cpp
+++ b/toonz/sources/tnztools/modifiersegmentation.cpp
@@ -58,17 +58,8 @@ TModifierSegmentation::modifyTrack(
   // remove points
   int start = track.size() - track.pointsAdded;
   if (start < 0) start = 0;
-  int subStart = subTrack.floorIndex(subTrack.indexByOriginalIndex(start));
-  if (subStart < 0) subStart = 0;
-  if (subStart < subTrack.size() && subTrack[subStart].originalIndex + TTrack::epsilon < start)
-    ++subStart;
-
-  while(subStart > 0 && subTrack[subStart-1].originalIndex + TTrack::epsilon >= start)
-    --subStart;
-  if (subStart < subTrack.size()) {
-    subTrack.pointsRemoved += subTrack.size() - subStart;
-    subTrack.truncate(subStart);
-  }
+  int subStart = subTrack.ceilIndex(subTrack.indexByOriginalIndex(start-1)) + 1;
+  subTrack.truncate(subStart);
 
   // add points
   TTrackPoint p0 = subTrack.modifier->calcPoint(start - 1);
@@ -77,8 +68,6 @@ TModifierSegmentation::modifyTrack(
     addSegments(subTrack, p0, p1);
     p0 = p1;
   }
-  subTrack.pointsAdded += subTrack.size() - subStart;
 
-  track.pointsRemoved = 0;
-  track.pointsAdded = 0;
+  track.resetChanges();
 }
diff --git a/toonz/sources/tnztools/modifiertangents.cpp b/toonz/sources/tnztools/modifiertangents.cpp
index 485728b..1dab9cc 100644
--- a/toonz/sources/tnztools/modifiertangents.cpp
+++ b/toonz/sources/tnztools/modifiertangents.cpp
@@ -62,7 +62,6 @@ TModifierTangents::modifyTrack(
     // add temporary point
     modifier->tangents.push_back(TTrackTangent());
     subTrack.push_back(track.back());
-    ++subTrack.pointsAdded;
   } else {
     // apply permanent changes
 
@@ -70,14 +69,12 @@ TModifierTangents::modifyTrack(
     int start = track.size() - track.pointsAdded;
     if (start < 0) start = 0;
     if (start > 1) --start;
-    if (start < subTrack.size()) {
-      subTrack.pointsRemoved += subTrack.size() - start;
-      subTrack.truncate(start);
-    }
-    if (start < (int)modifier->tangents.size())
-      modifier->tangents.erase(
-        modifier->tangents.begin() + start,
-        modifier->tangents.end() );
+    subTrack.truncate(start);
+    TTrackTangent lastTangent =
+        start < (int)modifier->tangents.size() ? modifier->tangents[start]
+      : modifier->tangents.empty() ? TTrackTangent()
+      : modifier->tangents.back();
+    modifier->tangents.resize(start, lastTangent);
 
     // add first point
     int index = start;
@@ -103,9 +100,7 @@ TModifierTangents::modifyTrack(
       ++index;
     }
 
-    track.pointsRemoved = 0;
-    track.pointsAdded = 0;
-    subTrack.pointsAdded += index - start;
+    track.resetChanges();
 
     // release previous key point
     modifier->savePoint.reset();
@@ -114,7 +109,6 @@ TModifierTangents::modifyTrack(
       // finish
       modifier->tangents.push_back(TTrackTangent());
       subTrack.push_back(track.back());
-      ++subTrack.pointsAdded;
     } else {
       // save key point
       modifier->savePoint = savePoint;
diff --git a/toonz/sources/tnztools/modifiertest.cpp b/toonz/sources/tnztools/modifiertest.cpp
index fd7a35f..75090d6 100644
--- a/toonz/sources/tnztools/modifiertest.cpp
+++ b/toonz/sources/tnztools/modifiertest.cpp
@@ -104,10 +104,10 @@ TModifierTest::modifyTrack(
   if (start < 0) start = 0;
 
   // remove angles
-  if (start < (int)handler->angles.size())
-    handler->angles.erase(
-      handler->angles.begin() + start,
-      handler->angles.end() );
+  double lastAngle = start < (int)handler->angles.size() ? handler->angles[start]
+                   : handler->angles.empty() ? 0.0
+                   : handler->angles.back();
+  handler->angles.resize(start, lastAngle);
 
   // add angles
   for(int i = start; i < track.size(); ++i) {
@@ -130,11 +130,7 @@ TModifierTest::modifyTrack(
     if (subStart < 0) subStart = 0;
     if (subStart < subTrack.size() && subTrack[subStart].originalIndex + TTrack::epsilon < start)
       ++subStart;
-
-    if (subStart < subTrack.size()) {
-      subTrack.pointsRemoved += subTrack.size() - subStart;
-      subTrack.truncate(subStart);
-    }
+    subTrack.truncate(subStart);
 
     // add points
     for(int i = start; i < track.size(); ++i) {
@@ -150,10 +146,8 @@ TModifierTest::modifyTrack(
       }
       subTrack.push_back( subTrack.modifier->calcPoint(i) );
     }
-    subTrack.pointsAdded += subTrack.size() - subStart;
   }
 
-  track.pointsRemoved = 0;
-  track.pointsAdded = 0;
+  track.resetChanges();
 }
 
diff --git a/toonz/sources/tnztools/track.cpp b/toonz/sources/tnztools/track.cpp
index ab30870..78d7d00 100644
--- a/toonz/sources/tnztools/track.cpp
+++ b/toonz/sources/tnztools/track.cpp
@@ -100,13 +100,16 @@ TTrack::push_back(const TTrackPoint &point) {
   // calculate length
   TPointD d = p.position - prev.position;
   p.length = prev.length + sqrt(d.x*d.x + d.y*d.y);
+
+  ++pointsAdded;
 }
 
 void
 TTrack::pop_back(int count) {
-  if (count > (int)size()) count = size();
+  if (count > size()) count = size();
   if (count <= 0) return;
-  m_points.erase(m_points.end() - count, m_points.end());
+  m_points.resize(size() - count);
+  pointsRemoved += count;
 }