From 9c1d0adc7775ec2352a0bf8b8d75ae9bc671e77c Mon Sep 17 00:00:00 2001
From: Philip Trettner <Philip.Trettner@rwth-aachen.de>
Date: Tue, 17 Jul 2018 15:51:18 +0200
Subject: [PATCH] working on optimization

---
 src/polymesh/algorithms/optimization.hh | 12 +++++
 src/polymesh/algorithms/topology.hh     | 37 +++++++++++++++
 src/polymesh/cursors.hh                 |  4 ++
 src/polymesh/detail/union_find.hh       | 60 +++++++++++++++++++++++++
 4 files changed, 113 insertions(+)
 create mode 100644 src/polymesh/algorithms/topology.hh
 create mode 100644 src/polymesh/detail/union_find.hh

diff --git a/src/polymesh/algorithms/optimization.hh b/src/polymesh/algorithms/optimization.hh
index 05edc01..4e10659 100644
--- a/src/polymesh/algorithms/optimization.hh
+++ b/src/polymesh/algorithms/optimization.hh
@@ -4,6 +4,7 @@
 
 #include "../detail/permutation.hh"
 #include "../detail/random.hh"
+#include "../detail/union_find.hh"
 
 namespace polymesh
 {
@@ -62,6 +63,17 @@ inline void optimize_for_rendering(Mesh& m)
 
 inline std::vector<int> cache_coherent_face_layout(Mesh const& m)
 {
+    // build binary tree
+    // - approx min cut
+    // - refine approx
+    // - split
+
+    std::vector<std::pair<int, int>> edges;
+    for (auto e : m.edges())
+        edges.emplace_back((int)e.faceA(), (int)e.faceB());
+
+    // TODO
+
     std::vector<int> id;
     for (auto i = 0u; i < m.faces().size(); ++i)
         id.push_back(i);
diff --git a/src/polymesh/algorithms/topology.hh b/src/polymesh/algorithms/topology.hh
new file mode 100644
index 0000000..88d434c
--- /dev/null
+++ b/src/polymesh/algorithms/topology.hh
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <vector>
+
+#include "../Mesh.hh"
+
+namespace polymesh {
+
+/// Given a face handle, returns the topologically farthest (but finite) face
+/// (i.e. the last face that would be visited in a BFS)
+face_handle farthest_face(face_handle f);
+
+/// ======== IMPLEMENTATION ========
+
+/*inline face_handle farthest_face(face_handle f)
+{
+    std::vector<face_index> q_curr;
+    std::vector<face_index> q_next;
+
+    q_curr.push_back(f.idx);
+
+    face_handle last_f = f;
+
+    while (!q_curr.empty())
+    {
+        for (auto f : q_curr)
+        {
+            // TODO
+        }
+
+        std::swap(q_curr, q_next);
+    }
+
+    return last_f;
+}*/
+
+}
diff --git a/src/polymesh/cursors.hh b/src/polymesh/cursors.hh
index 635d166..7f93c51 100644
--- a/src/polymesh/cursors.hh
+++ b/src/polymesh/cursors.hh
@@ -31,6 +31,8 @@ struct primitive_index
     bool operator==(handle_t const& rhs) const { return value == rhs.idx.value; }
     bool operator!=(handle_t const& rhs) const { return value != rhs.idx.value; }
 
+    explicit operator int() const { return value; }
+
     /// indexes this primitive by a functor
     /// also works for attributes
     /// - e.g. v[position] or f[area]
@@ -57,6 +59,8 @@ struct primitive_handle
     bool operator==(handle_t const& rhs) const { return mesh == rhs.mesh && idx == rhs.idx; }
     bool operator!=(handle_t const& rhs) const { return mesh != rhs.mesh || idx != rhs.idx; }
 
+    explicit operator int() const { return (int)idx; }
+
     /// indexes this primitive by a functor
     /// also works for attributes
     /// - e.g. v[position] or f[area]
diff --git a/src/polymesh/detail/union_find.hh b/src/polymesh/detail/union_find.hh
new file mode 100644
index 0000000..c294bc8
--- /dev/null
+++ b/src/polymesh/detail/union_find.hh
@@ -0,0 +1,60 @@
+#pragma once
+
+#include <vector>
+
+namespace polymesh
+{
+namespace detail
+{
+struct disjoint_set
+{
+public:
+    disjoint_set(int size) : entries(size)
+    {
+        for (auto i = 0; i < size; ++i)
+        {
+            auto& e = entries[i];
+            e.parent = i;
+            e.size = 1;
+        }
+    }
+
+    int find(int idx)
+    {
+        auto& e = entries[idx];
+        if (e.parent != idx)
+            e.parent = find(e.parent);
+        return e.parent;
+    }
+
+    bool do_union(int x, int y)
+    {
+        // union by size
+        auto x_root = find(x);
+        auto y_root = find(y);
+
+        if (x_root == y_root)
+            return false;
+
+        if (entries[x_root].size < entries[y_root].size)
+            std::swap(x_root, y_root);
+        // |X| > |Y|
+
+        entries[y_root].parent = x_root;
+        entries[x_root].size += entries[y_root].size;
+
+        return true;
+    }
+
+private:
+    struct entry
+    {
+        int parent;
+        int size;
+    };
+
+private:
+    std::vector<entry> entries;
+};
+}
+}
-- 
GitLab