From 8ace370677f01462577cf4d026bc21178200b0cf Mon Sep 17 00:00:00 2001
From: joanvallve <jvallve@iri.upc.edu>
Date: Wed, 26 Feb 2025 11:27:14 +0100
Subject: [PATCH] new TrackMatrix method cleanSnapshots

---
 include/core/processor/track_matrix.h |  5 +++
 src/processor/track_matrix.cpp        | 21 +++++++++++++
 test/gtest_track_matrix.cpp           | 45 +++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)

diff --git a/include/core/processor/track_matrix.h b/include/core/processor/track_matrix.h
index 6a325f79b..d15917120 100644
--- a/include/core/processor/track_matrix.h
+++ b/include/core/processor/track_matrix.h
@@ -121,6 +121,8 @@ class TrackMatrix
     FeatureBasePtr      feature(const SizeStd& _track_id, CaptureBasePtr _cap);
     CaptureBaseConstPtr firstCapture(const SizeStd& _track_id) const;
     CaptureBasePtr      firstCapture(const SizeStd& _track_id);
+    CaptureBaseConstPtr lastCapture(const SizeStd& _track_id) const;
+    CaptureBasePtr      lastCapture(const SizeStd& _track_id);
 
     list<SizeStd> trackIds(CaptureBaseConstPtr _capture = nullptr) const;
 
@@ -128,6 +130,9 @@ class TrackMatrix
     TrackConst trackAtKeyframes(const SizeStd& _track_id) const;
     Track      trackAtKeyframes(const SizeStd& _track_id);
 
+    // Remove snapshots of captures that are being removed from the problem (e.g. when a keyframe is removed)
+    void cleanSnapshots();
+
   private:
     static SizeStd track_id_count_;
 
diff --git a/src/processor/track_matrix.cpp b/src/processor/track_matrix.cpp
index f4dacef75..52ac6c063 100644
--- a/src/processor/track_matrix.cpp
+++ b/src/processor/track_matrix.cpp
@@ -150,6 +150,17 @@ void TrackMatrix::remove(FeatureBasePtr _ftr)
     }
 }
 
+void TrackMatrix::cleanSnapshots()
+{
+    // In two steps to avoid erasing while iterating
+    CaptureBasePtrList removing_captures;
+    for (auto snapshot_pair : snapshots_)
+        if (snapshot_pair.first->isRemoving())
+            removing_captures.push_back(snapshot_pair.first);
+
+    for (auto cap : removing_captures) remove(cap);
+}
+
 SizeStd TrackMatrix::numTracks() const
 {
     return tracks_.size();
@@ -306,6 +317,16 @@ CaptureBasePtr TrackMatrix::firstCapture(const SizeStd& _track_id)
     return firstFeature(_track_id)->getCapture();
 }
 
+CaptureBaseConstPtr TrackMatrix::lastCapture(const SizeStd& _track_id) const
+{
+    return lastFeature(_track_id)->getCapture();
+}
+
+CaptureBasePtr TrackMatrix::lastCapture(const SizeStd& _track_id)
+{
+    return lastFeature(_track_id)->getCapture();
+}
+
 TrackConst TrackMatrix::trackAtKeyframes(const SizeStd& _track_id) const
 {
     // We assemble a track_kf on the fly by checking each capture's frame.
diff --git a/test/gtest_track_matrix.cpp b/test/gtest_track_matrix.cpp
index 5f93a4f92..ba583d196 100644
--- a/test/gtest_track_matrix.cpp
+++ b/test/gtest_track_matrix.cpp
@@ -334,6 +334,51 @@ TEST_F(TrackMatrixTest, remove_snapshot)
     ASSERT_EQ(track_matrix.numTracks(), (unsigned int)0);
 }
 
+TEST_F(TrackMatrixTest, clean_snapshots)
+{
+    f0->link(C0);
+    f1->link(C1);
+    f2->link(C2);
+    f3->link(C1);
+    f4->link(C3);
+    f5->link(C4);
+
+    track_matrix.newTrack(f0);
+    track_matrix.add(f0->trackId(), f1);
+    track_matrix.add(f0->trackId(), f2);
+    track_matrix.add(f0->trackId(), f4);
+    track_matrix.add(f0->trackId(), f5);
+    track_matrix.newTrack(f3);
+    /* KC0   C1   C2   C3  KC4 snapshots
+     *
+     *  f0---f1---f2---f4---f5 trk 0
+     *       |
+     *       f3                trk 1
+     */
+
+     // remove F1 --> remove C1
+    F1->remove();
+
+    track_matrix.cleanSnapshots();
+
+    // Resulting track matrix should be:
+    /* KC0   C2   C3  KC4 snapshots
+     *
+     *  f0---f2---f4---f5 trk 0
+     *  
+     */
+    ASSERT_EQ(track_matrix.numTracks(), 1);
+    ASSERT_EQ(track_matrix.trackSize(f0->trackId()), 4);
+    ASSERT_EQ(track_matrix.firstFeature(f0->trackId()), f0);
+    ASSERT_EQ(track_matrix.lastFeature(f0->trackId()), f5);
+    ASSERT_EQ(track_matrix.firstCapture(f0->trackId()), C0);
+    ASSERT_EQ(track_matrix.lastCapture(f0->trackId()), C4);
+    ASSERT_EQ(track_matrix.feature(f0->trackId(), C0), f0);
+    ASSERT_EQ(track_matrix.feature(f0->trackId(), C2), f2);
+    ASSERT_EQ(track_matrix.feature(f0->trackId(), C3), f4);
+    ASSERT_EQ(track_matrix.feature(f0->trackId(), C4), f5);
+}
+
 TEST_F(TrackMatrixTest, track)
 {
     f0->link(C0);
-- 
GitLab