diff --git a/src/libslic3r/TriangleSelector.cpp b/src/libslic3r/TriangleSelector.cpp
index c9f253d88..ad823c55d 100644
--- a/src/libslic3r/TriangleSelector.cpp
+++ b/src/libslic3r/TriangleSelector.cpp
@@ -228,7 +228,7 @@ void TriangleSelector::seed_fill_select_triangles(const Vec3f &hit, int facet_st
     }
 }
 
-void TriangleSelector::precompute_all_level_neighbors_recursive(const int facet_idx, const Vec3i &neighbors, const Vec3i &neighbors_propagated, std::vector<Vec3i> &neighbors_out) const
+void TriangleSelector::precompute_all_neighbors_recursive(const int facet_idx, const Vec3i &neighbors, const Vec3i &neighbors_propagated, std::vector<Vec3i> &neighbors_out, std::vector<Vec3i> &neighbors_propagated_out) const
 {
     assert(facet_idx < int(m_triangles.size()));
 
@@ -236,7 +236,8 @@ void TriangleSelector::precompute_all_level_neighbors_recursive(const int facet_
     if (!tr->valid())
         return;
 
-    neighbors_out[facet_idx] = neighbors_propagated;
+    neighbors_out[facet_idx]            = neighbors;
+    neighbors_propagated_out[facet_idx] = neighbors_propagated;
     if (tr->is_split()) {
         assert(this->verify_triangle_neighbors(*tr, neighbors));
 
@@ -247,67 +248,51 @@ void TriangleSelector::precompute_all_level_neighbors_recursive(const int facet_
                 assert(tr->children[i] < int(m_triangles.size()));
                 // Recursion, deep first search over the children of this triangle.
                 // All children of this triangle were created by splitting a single source triangle of the original mesh.
-                this->precompute_all_level_neighbors_recursive(tr->children[i], this->child_neighbors(*tr, neighbors, i), this->child_neighbors_propagated(*tr, neighbors_propagated, i), neighbors_out);
+                this->precompute_all_neighbors_recursive(tr->children[i], this->child_neighbors(*tr, neighbors, i),
+                                                         this->child_neighbors_propagated(*tr, neighbors_propagated, i), neighbors_out,
+                                                         neighbors_propagated_out);
             }
         }
     }
 }
 
-std::vector<Vec3i> TriangleSelector::precompute_all_level_neighbors() const
+std::pair<std::vector<Vec3i>, std::vector<Vec3i>> TriangleSelector::precompute_all_neighbors() const
 {
     std::vector<Vec3i> neighbors(m_triangles.size(), Vec3i(-1, -1, -1));
+    std::vector<Vec3i> neighbors_propagated(m_triangles.size(), Vec3i(-1, -1, -1));
     for (int facet_idx = 0; facet_idx < this->m_orig_size_indices; ++facet_idx) {
-        neighbors[facet_idx] = root_neighbors(*m_mesh, facet_idx);
+        neighbors[facet_idx]            = root_neighbors(*m_mesh, facet_idx);
+        neighbors_propagated[facet_idx] = neighbors[facet_idx];
         assert(this->verify_triangle_neighbors(m_triangles[facet_idx], neighbors[facet_idx]));
         if (m_triangles[facet_idx].is_split())
-            this->precompute_all_level_neighbors_recursive(facet_idx, neighbors[facet_idx], neighbors[facet_idx], neighbors);
+            this->precompute_all_neighbors_recursive(facet_idx, neighbors[facet_idx], neighbors_propagated[facet_idx], neighbors, neighbors_propagated);
     }
-    return neighbors;
+    return std::make_pair(std::move(neighbors), std::move(neighbors_propagated));
 }
 
-bool TriangleSelector::are_triangles_touching(const int first_facet_idx, const int second_facet_idx) const
+// It appends all triangles that are touching the edge (vertexi, vertexj) of the triangle.
+// It doesn't append the triangles that are touching the triangle only by part of the edge that means the triangles are from lower depth.
+void TriangleSelector::append_touching_subtriangles(int itriangle, int vertexi, int vertexj, std::vector<int> &touching_subtriangles_out) const
 {
-    std::array<Linef3, 3> sides_facet = {Linef3(m_vertices[m_triangles[first_facet_idx].verts_idxs[0]].v.cast<double>(), m_vertices[m_triangles[first_facet_idx].verts_idxs[1]].v.cast<double>()),
-                                         Linef3(m_vertices[m_triangles[first_facet_idx].verts_idxs[1]].v.cast<double>(), m_vertices[m_triangles[first_facet_idx].verts_idxs[2]].v.cast<double>()),
-                                         Linef3(m_vertices[m_triangles[first_facet_idx].verts_idxs[2]].v.cast<double>(), m_vertices[m_triangles[first_facet_idx].verts_idxs[0]].v.cast<double>())};
+    if (itriangle == -1)
+        return;
 
-    const Vec3d           p0          = m_vertices[m_triangles[second_facet_idx].verts_idxs[0]].v.cast<double>();
-    const Vec3d           p1          = m_vertices[m_triangles[second_facet_idx].verts_idxs[1]].v.cast<double>();
-    const Vec3d           p2          = m_vertices[m_triangles[second_facet_idx].verts_idxs[2]].v.cast<double>();
+    auto process_subtriangle = [this, &itriangle, &vertexi, &vertexj, &touching_subtriangles_out](const int subtriangle_idx) -> void {
+        assert(subtriangle_idx == -1);
+        if (!m_triangles[subtriangle_idx].is_split())
+            touching_subtriangles_out.emplace_back(subtriangle_idx);
+        else if (int midpoint = this->triangle_midpoint(itriangle, vertexi, vertexj); midpoint != -1)
+            append_touching_subtriangles(subtriangle_idx, vertexi, midpoint, touching_subtriangles_out);
+        else
+            append_touching_subtriangles(subtriangle_idx, vertexi, vertexj, touching_subtriangles_out);
+    };
 
-    for (size_t idx = 0; idx < 3; ++idx)
-        if (line_alg::distance_to_squared(sides_facet[idx], p0) <= EPSILON && (line_alg::distance_to_squared(sides_facet[idx], p1) <= EPSILON || line_alg::distance_to_squared(sides_facet[idx], p2) <= EPSILON))
-            return true;
-        else if (line_alg::distance_to_squared(sides_facet[idx], p1) <= EPSILON && line_alg::distance_to_squared(sides_facet[idx], p2) <= EPSILON)
-            return true;
+    std::pair<int, int> touching = this->triangle_subtriangles(itriangle, vertexi, vertexj);
+    if (touching.first != -1)
+        process_subtriangle(touching.first);
 
-    return false;
-}
-
-std::vector<int> TriangleSelector::neighboring_triangles(const int first_facet_idx, const int second_facet_idx, EnforcerBlockerType second_facet_state) const
-{
-    assert(first_facet_idx < int(m_triangles.size()));
-
-    const Triangle *tr = &m_triangles[first_facet_idx];
-    if (!tr->valid())
-        return {};
-
-    if (!tr->is_split() && tr->get_state() == second_facet_state && (are_triangles_touching(second_facet_idx, first_facet_idx) || are_triangles_touching(first_facet_idx, second_facet_idx)))
-        return {first_facet_idx};
-
-    std::vector<int> neighbor_facets_out;
-    int              num_of_children = tr->number_of_split_sides() + 1;
-    if (num_of_children != 1) {
-        for (int i = 0; i < num_of_children; ++i) {
-            assert(i < int(tr->children.size()));
-            assert(tr->children[i] < int(m_triangles.size()));
-
-            if (std::vector<int> neighbor_facets = neighboring_triangles(tr->children[i], second_facet_idx, second_facet_state); !neighbor_facets.empty())
-                Slic3r::append(neighbor_facets_out, std::move(neighbor_facets));
-        }
-    }
-
-    return neighbor_facets_out;
+    if (touching.second != -1)
+        process_subtriangle(touching.second);
 }
 
 void TriangleSelector::bucket_fill_select_triangles(const Vec3f& hit, int facet_start, bool propagate)
@@ -326,7 +311,23 @@ void TriangleSelector::bucket_fill_select_triangles(const Vec3f& hit, int facet_
         return;
     }
 
-    std::vector<Vec3i> all_level_neighbors = this->precompute_all_level_neighbors();
+    auto get_all_touching_triangles = [this](int facet_idx, const Vec3i &neighbors, const Vec3i &neighbors_propagated) -> std::vector<int> {
+        assert(facet_idx != -1 && facet_idx < m_triangles.size());
+        assert(this->verify_triangle_neighbors(m_triangles[facet_idx], neighbors));
+        std::vector<int> touching_triangles;
+        Vec3i            vertices = {m_triangles[facet_idx].verts_idxs[0], m_triangles[facet_idx].verts_idxs[1], m_triangles[facet_idx].verts_idxs[2]};
+        append_touching_subtriangles(neighbors(0), vertices(1), vertices(0), touching_triangles);
+        append_touching_subtriangles(neighbors(1), vertices(2), vertices(1), touching_triangles);
+        append_touching_subtriangles(neighbors(2), vertices(0), vertices(2), touching_triangles);
+
+        for (int neighbor_idx : neighbors_propagated)
+            if (neighbor_idx != -1 && !m_triangles[neighbor_idx].is_split())
+                touching_triangles.emplace_back(neighbor_idx);
+
+        return touching_triangles;
+    };
+
+    auto [neighbors, neighbors_propagated] = this->precompute_all_neighbors();
     std::vector<bool>  visited(m_triangles.size(), false);
     std::queue<int>    facet_queue;
 
@@ -338,17 +339,14 @@ void TriangleSelector::bucket_fill_select_triangles(const Vec3f& hit, int facet_
 
         if (!visited[current_facet]) {
             m_triangles[current_facet].select_by_seed_fill();
-            for (int neighbor_idx : all_level_neighbors[current_facet]) {
-                if (neighbor_idx < 0 || visited[neighbor_idx])
+
+            std::vector<int> touching_triangles = get_all_touching_triangles(current_facet, neighbors[current_facet], neighbors_propagated[current_facet]);
+            for(const int tr_idx : touching_triangles) {
+                if (tr_idx < 0 || visited[tr_idx] || m_triangles[tr_idx].get_state() != start_facet_state)
                     continue;
 
-                if (!m_triangles[neighbor_idx].is_split()) {
-                    if (m_triangles[neighbor_idx].get_state() == start_facet_state)
-                        facet_queue.push(neighbor_idx);
-                } else {
-                    for (int neighbor_facet_idx : neighboring_triangles(neighbor_idx, current_facet, start_facet_state))
-                        facet_queue.push(neighbor_facet_idx);
-                }
+                assert(!m_triangles[tr_idx].is_split());
+                facet_queue.push(tr_idx);
             }
         }
 
@@ -437,6 +435,40 @@ int TriangleSelector::neighbor_child(int itriangle, int vertexi, int vertexj, Pa
     return itriangle == -1 ? -1 : this->neighbor_child(m_triangles[itriangle], vertexi, vertexj, partition);
 }
 
+std::pair<int, int> TriangleSelector::triangle_subtriangles(int itriangle, int vertexi, int vertexj) const
+{
+    return itriangle == -1 ? std::make_pair(-1, -1) : this->triangle_subtriangles(m_triangles[itriangle], vertexi, vertexj);
+}
+
+std::pair<int, int> TriangleSelector::triangle_subtriangles(const Triangle &tr, int vertexi, int vertexj)
+{
+    if (tr.number_of_split_sides() == 0)
+        // If this triangle is not split, then there is no subtriangles touching the edge.
+        return std::make_pair(-1, -1);
+
+    // Find the triangle edge.
+    int edge = tr.verts_idxs[0] == vertexi ? 0 : tr.verts_idxs[1] == vertexi ? 1 : 2;
+    assert(tr.verts_idxs[edge] == vertexi);
+    assert(tr.verts_idxs[next_idx_modulo(edge, 3)] == vertexj);
+
+    if (tr.number_of_split_sides() == 1) {
+        return edge == next_idx_modulo(tr.special_side(), 3) ? std::make_pair(tr.children[0], tr.children[1]) :
+                                                                     std::make_pair(tr.children[edge == tr.special_side() ? 0 : 1], -1);
+    } else if (tr.number_of_split_sides() == 2) {
+        return edge == next_idx_modulo(tr.special_side(), 3) ? std::make_pair(tr.children[2], -1) :
+               edge == tr.special_side()                           ? std::make_pair(tr.children[0], tr.children[1]) :
+                                                                     std::make_pair(tr.children[2], tr.children[0]);
+    } else {
+        assert(tr.number_of_split_sides() == 3);
+        assert(tr.special_side() == 0);
+        return edge == 0 ? std::make_pair(tr.children[0], tr.children[1]) :
+               edge == 1 ? std::make_pair(tr.children[1], tr.children[2]) :
+                           std::make_pair(tr.children[2], tr.children[0]);
+    }
+
+    return std::make_pair(-1, -1);
+}
+
 // Return existing midpoint of CCW oriented side (vertexi, vertexj).
 // If itriangle == -1 or if the side sharing (vertexi, vertexj) is not split, return -1.
 int TriangleSelector::triangle_midpoint(const Triangle &tr, int vertexi, int vertexj) const
@@ -524,12 +556,8 @@ Vec3i TriangleSelector::child_neighbors(const Triangle &tr, const Vec3i &neighbo
 
     assert(child_idx >= 0 && child_idx <= tr.number_of_split_sides());
     int   i = tr.special_side();
-    int   j = i + 1;
-    if (j >= 3)
-        j = 0;
-    int   k = j + 1;
-    if (k >= 3)
-        k = 0;
+    int   j = next_idx_modulo(i, 3);
+    int   k = next_idx_modulo(j, 3);
 
     Vec3i out;
     switch (tr.number_of_split_sides()) {
@@ -612,23 +640,28 @@ Vec3i TriangleSelector::child_neighbors(const Triangle &tr, const Vec3i &neighbo
 Vec3i TriangleSelector::child_neighbors_propagated(const Triangle &tr, const Vec3i &neighbors, int child_idx) const
 {
     int i = tr.special_side();
-    int j = i + 1;
-    if (j >= 3) j = 0;
-    int k = j + 1;
-    if (k >= 3) k = 0;
+    int j = next_idx_modulo(i, 3);
+    int k = next_idx_modulo(j, 3);
 
     Vec3i out;
+    auto  replace_if_not_exists = [&out](int index_to_replace, int neighbor) {
+        if (out(index_to_replace) == -1)
+            out(index_to_replace) = neighbor;
+    };
+
     switch (tr.number_of_split_sides()) {
     case 1:
         switch (child_idx) {
         case 0:
             out(0) = neighbors(i);
-            out(1) = neighbors(j);
+            out(1) = this->neighbor_child(neighbors(j), tr.verts_idxs[k], tr.verts_idxs[j], Partition::Second);
+            replace_if_not_exists(1, neighbors(j));
             out(2) = tr.children[1];
             break;
         default:
             assert(child_idx == 1);
-            out(0) = neighbors(j);
+            out(0) = this->neighbor_child(neighbors(j), tr.verts_idxs[k], tr.verts_idxs[j], Partition::First);
+            replace_if_not_exists(0, neighbors(j));
             out(1) = neighbors(k);
             out(2) = tr.children[0];
             break;
@@ -638,20 +671,24 @@ Vec3i TriangleSelector::child_neighbors_propagated(const Triangle &tr, const Vec
     case 2:
         switch (child_idx) {
         case 0:
-            out(0) = neighbors(i);
+            out(0) = this->neighbor_child(neighbors(i), tr.verts_idxs[j], tr.verts_idxs[i], Partition::Second);
+            replace_if_not_exists(0, neighbors(i));
             out(1) = tr.children[1];
-            out(2) = neighbors(k);
+            out(2) = this->neighbor_child(neighbors(k), tr.verts_idxs[i], tr.verts_idxs[k], Partition::First);
+            replace_if_not_exists(2, neighbors(k));
             break;
         case 1:
             assert(child_idx == 1);
-            out(0) = neighbors(i);
+            out(0) = this->neighbor_child(neighbors(i), tr.verts_idxs[j], tr.verts_idxs[i], Partition::First);
+            replace_if_not_exists(0, neighbors(i));
             out(1) = tr.children[2];
             out(2) = tr.children[0];
             break;
         default:
             assert(child_idx == 2);
             out(0) = neighbors(j);
-            out(1) = neighbors(k);
+            out(1) = this->neighbor_child(neighbors(k), tr.verts_idxs[i], tr.verts_idxs[k], Partition::Second);
+            replace_if_not_exists(1, neighbors(k));
             out(2) = tr.children[1];
             break;
         }
@@ -661,18 +698,24 @@ Vec3i TriangleSelector::child_neighbors_propagated(const Triangle &tr, const Vec
         assert(tr.special_side() == 0);
         switch (child_idx) {
         case 0:
-            out(0) = neighbors(0);
+            out(0) = this->neighbor_child(neighbors(0), tr.verts_idxs[1], tr.verts_idxs[0], Partition::Second);
+            replace_if_not_exists(0, neighbors(0));
             out(1) = tr.children[3];
-            out(2) = neighbors(2);
+            out(2) = this->neighbor_child(neighbors(2), tr.verts_idxs[0], tr.verts_idxs[2], Partition::First);
+            replace_if_not_exists(2, neighbors(2));
             break;
         case 1:
-            out(0) = neighbors(0);
-            out(1) = neighbors(1);
+            out(0) = this->neighbor_child(neighbors(0), tr.verts_idxs[1], tr.verts_idxs[0], Partition::First);
+            replace_if_not_exists(0, neighbors(0));
+            out(1) = this->neighbor_child(neighbors(1), tr.verts_idxs[2], tr.verts_idxs[1], Partition::Second);
+            replace_if_not_exists(1, neighbors(1));
             out(2) = tr.children[3];
             break;
         case 2:
-            out(0) = neighbors(1);
-            out(1) = neighbors(2);
+            out(0) = this->neighbor_child(neighbors(1), tr.verts_idxs[2], tr.verts_idxs[1], Partition::First);
+            replace_if_not_exists(0, neighbors(1));
+            out(1) = this->neighbor_child(neighbors(2), tr.verts_idxs[0], tr.verts_idxs[2], Partition::Second);
+            replace_if_not_exists(1, neighbors(2));
             out(2) = tr.children[3];
             break;
         default:
@@ -886,13 +929,13 @@ void TriangleSelector::undivide_triangle(int facet_idx)
     Triangle& tr = m_triangles[facet_idx];
 
     if (tr.is_split()) {
-        for (int i=0; i<=tr.number_of_split_sides(); ++i) {
+        for (int i = 0; i <= tr.number_of_split_sides(); ++i) {
             int       child    = tr.children[i];
             Triangle &child_tr = m_triangles[child];
             assert(child_tr.valid());
             undivide_triangle(child);
-            for (int i = 0; i < 3; ++ i) {
-                int     iv = child_tr.verts_idxs[i];
+            for (int j = 0; j < 3; ++j) {
+                int     iv = child_tr.verts_idxs[j];
                 Vertex &v  = m_vertices[iv];
                 assert(v.ref_cnt > 0);
                 if (-- v.ref_cnt == 0) {
@@ -1231,7 +1274,7 @@ void TriangleSelector::get_facets_strict_recursive(
         this->get_facets_split_by_tjoints({tr.verts_idxs[0], tr.verts_idxs[1], tr.verts_idxs[2]}, neighbors, out_triangles);
 }
 
-void TriangleSelector::get_facets_split_by_tjoints(const Vec3i vertices, const Vec3i neighbors, std::vector<stl_triangle_vertex_indices> &out_triangles) const
+void TriangleSelector::get_facets_split_by_tjoints(const Vec3i &vertices, const Vec3i &neighbors, std::vector<stl_triangle_vertex_indices> &out_triangles) const
 {
 // Export this triangle, but first collect the T-joint vertices along its edges.
     Vec3i midpoints(
diff --git a/src/libslic3r/TriangleSelector.hpp b/src/libslic3r/TriangleSelector.hpp
index b0fbabaed..eeb479dee 100644
--- a/src/libslic3r/TriangleSelector.hpp
+++ b/src/libslic3r/TriangleSelector.hpp
@@ -22,8 +22,8 @@ public:
         POINTER
     };
 
-    [[nodiscard]] std::vector<Vec3i> precompute_all_level_neighbors() const;
-    void precompute_all_level_neighbors_recursive(const int facet_idx, const Vec3i &neighbors, const Vec3i &neighbors_propagated, std::vector<Vec3i> &neighbors_out) const;
+    std::pair<std::vector<Vec3i>, std::vector<Vec3i>> precompute_all_neighbors() const;
+    void precompute_all_neighbors_recursive(int facet_idx, const Vec3i &neighbors, const Vec3i &neighbors_propagated, std::vector<Vec3i> &neighbors_out, std::vector<Vec3i> &neighbors_normal_out) const;
 
     // Set a limit to the edge length, below which the edge will not be split by select_patch().
     // Called by select_patch() internally. Made public for debugging purposes, see TriangleSelectorGUI::render_debug().
@@ -37,10 +37,6 @@ public:
     [[nodiscard]] int select_unsplit_triangle(const Vec3f &hit, int facet_idx) const;
     [[nodiscard]] int select_unsplit_triangle(const Vec3f &hit, int facet_idx, const Vec3i &neighbors) const;
 
-    [[nodiscard]] bool are_triangles_touching(int first_facet_idx, int second_facet_idx) const;
-
-    [[nodiscard]] std::vector<int> neighboring_triangles(int first_facet_idx, int second_facet_idx, EnforcerBlockerType second_facet_state) const;
-
     // Select all triangles fully inside the circle, subdivide where needed.
     void select_patch(const Vec3f        &hit,         // point where to start
                       int                 facet_start, // facet of the original mesh (unsplit) that the hit point belongs to
@@ -60,7 +56,7 @@ public:
                                     bool         propagate);        // if bucket fill is propagated to neighbor faces or if it fills the only facet of the modified mesh that the hit point belongs to.
 
     bool                 has_facets(EnforcerBlockerType state) const;
-    static bool          has_facets(const std::pair<std::vector<std::pair<int, int>>, std::vector<bool>> &data, const EnforcerBlockerType test_state);
+    static bool          has_facets(const std::pair<std::vector<std::pair<int, int>>, std::vector<bool>> &data, EnforcerBlockerType test_state);
     int                  num_facets(EnforcerBlockerType state) const;
     // Get facets at a given state. Don't triangulate T-joints.
     indexed_triangle_set get_facets(EnforcerBlockerType state) const;
@@ -128,11 +124,11 @@ protected:
         bool is_selected_by_seed_fill() const { assert(! is_split()); return m_selected_by_seed_fill; }
 
         // Is this triangle valid or marked to be removed?
-        bool valid() const throw() { return m_valid; }
+        bool valid() const noexcept { return m_valid; }
         // Get info on how it's split.
-        bool is_split() const throw() { return number_of_split_sides() != 0; }
-        int number_of_split_sides() const throw() { return number_of_splits; }
-        int special_side() const throw() { assert(is_split()); return special_side_idx; }
+        bool is_split() const noexcept { return number_of_split_sides() != 0; }
+        int number_of_split_sides() const noexcept { return number_of_splits; }
+        int special_side() const noexcept { assert(is_split()); return special_side_idx; }
 
     private:
         friend TriangleSelector;
@@ -205,7 +201,7 @@ private:
     void remove_useless_children(int facet_idx); // No hidden meaning. Triangles are meant.
     bool is_pointer_in_triangle(int facet_idx) const;
     bool is_edge_inside_cursor(int facet_idx) const;
-    int  push_triangle(int a, int b, int c, int source_triangle, const EnforcerBlockerType state = EnforcerBlockerType{0});
+    int  push_triangle(int a, int b, int c, int source_triangle, EnforcerBlockerType state = EnforcerBlockerType{0});
     void perform_split(int facet_idx, const Vec3i &neighbors, EnforcerBlockerType old_state);
     Vec3i child_neighbors(const Triangle &tr, const Vec3i &neighbors, int child_idx) const;
     Vec3i child_neighbors_propagated(const Triangle &tr, const Vec3i &neighbors, int child_idx) const;
@@ -221,6 +217,11 @@ private:
     int triangle_midpoint(int itriangle, int vertexi, int vertexj) const;
     int triangle_midpoint_or_allocate(int itriangle, int vertexi, int vertexj);
 
+    static std::pair<int, int> triangle_subtriangles(const Triangle &tr, int vertexi, int vertexj);
+    std::pair<int, int>        triangle_subtriangles(int itriangle, int vertexi, int vertexj) const;
+
+    void append_touching_subtriangles(int itriangle, int vertexi, int vertexj, std::vector<int> &touching_subtriangles_out) const;
+
 #ifndef NDEBUG
     bool verify_triangle_neighbors(const Triangle& tr, const Vec3i& neighbors) const;
     bool verify_triangle_midpoints(const Triangle& tr) const;
@@ -231,7 +232,7 @@ private:
         const Vec3i                                 &neighbors,
         EnforcerBlockerType                          state,
         std::vector<stl_triangle_vertex_indices>    &out_triangles) const;
-    void get_facets_split_by_tjoints(const Vec3i vertices, const Vec3i neighbors, std::vector<stl_triangle_vertex_indices> &out_triangles) const;
+    void get_facets_split_by_tjoints(const Vec3i &vertices, const Vec3i &neighbors, std::vector<stl_triangle_vertex_indices> &out_triangles) const;
 
     int m_free_triangles_head { -1 };
     int m_free_vertices_head { -1 };