Revision: 37562
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=37562
Author:   shuvro
Date:     2011-06-16 17:32:24 +0000 (Thu, 16 Jun 2011)
Log Message:
-----------
Basic implementation of the seam generation algorithm is done. The code is 
restructured to make it more efficient. Most of the restructure ideas are given 
by Elubie. Some crashes are handled, Non-manifold mesh support is added with 
the restructured code. Combinatorial centers are added to make the result more 
accurate.

Modified Paths:
--------------
    branches/soc-2011-avocado/blender/intern/autoseam/AutoseamUtility.cpp
    branches/soc-2011-avocado/blender/intern/autoseam/AutoseamUtility.h
    branches/soc-2011-avocado/blender/intern/autoseam/CMakeLists.txt
    branches/soc-2011-avocado/blender/intern/autoseam/autoseam_C_API.cpp
    branches/soc-2011-avocado/blender/intern/autoseam/autoseam_C_API.h
    
branches/soc-2011-avocado/blender/source/blender/editors/mesh/autoseam_tools.c

Added Paths:
-----------
    branches/soc-2011-avocado/blender/intern/autoseam/AutoseamAdjacency.cpp
    branches/soc-2011-avocado/blender/intern/autoseam/AutoseamAdjacency.h
    branches/soc-2011-avocado/blender/intern/autoseam/AutoseamEigenspace.cpp
    branches/soc-2011-avocado/blender/intern/autoseam/AutoseamEigenspace.h

Added: branches/soc-2011-avocado/blender/intern/autoseam/AutoseamAdjacency.cpp
===================================================================
--- branches/soc-2011-avocado/blender/intern/autoseam/AutoseamAdjacency.cpp     
                        (rev 0)
+++ branches/soc-2011-avocado/blender/intern/autoseam/AutoseamAdjacency.cpp     
2011-06-16 17:32:24 UTC (rev 37562)
@@ -0,0 +1,107 @@
+#include "AutoseamAdjacency.h"
+
+
+AutoseamAdjacency::AutoseamAdjacency(int dimension)
+{
+    m_adjacency = MatrixXd::Zero(dimension, dimension);
+}
+
+void AutoseamAdjacency::set(int row, int col, float value)
+{
+    m_adjacency(row, col) = value;
+    m_adjacency(col, row) = value;
+    //  m_adjacency(row, col) = 1.0f;
+    //  m_adjacency(col, row) = 1.0f;
+}
+
+
+int AutoseamAdjacency::get(int row, int col)
+{
+    return m_adjacency(row, col) > 0.9 ? 1 : 0;
+}
+
+AutoseamAdjacency::~AutoseamAdjacency()
+{
+    clear_eigenspaces();
+}
+
+void AutoseamAdjacency::clear_eigenspaces()
+{
+
+    for (std::vector<AutoseamEigenspace*>::iterator it = 
m_eigenspaces.begin(); it != m_eigenspaces.end(); ++it)
+    {
+        delete (*it);
+    }
+    m_eigenspaces.clear();
+}
+
+bool AutoseamAdjacency::generate_seam()
+{
+    MatrixXd& a = m_adjacency;
+       
+    clear_eigenspaces();
+
+    int n = a.rows();
+    for (int i=0; i<n;++i) {
+        a(i,i) = 0.0;
+        double rowsum = a.row(i).sum();
+        a(i,i) = -rowsum;
+    }
+
+    Eigen::SelfAdjointEigenSolver<MatrixXd> es(a);
+    Eigen::VectorXd evalues(es.eigenvalues());
+    int f = 0;
+    bool found = false;
+    int seam_length=0;
+    MatrixXd aplus;
+    MatrixXd aminus;
+    while ( (f < n) && (f<30) ) {
+        // Eigenvalues seem to be sorted largest to smallest, we need the 30 
smallest
+        // in the future only those will be calculated by the algorithm (if we 
use ARPACK)
+        AutoseamEigenspace* aes = new AutoseamEigenspace(evalues[n-f-1], 
es.eigenvectors().col(n-f-1));
+
+        // split Eigenspace into two subspaces F+ and F- where the ith entry 
in the eigenvector is positive/negative
+        aes->split();
+
+
+        aes->fill_adjacency(a, aplus, aminus);
+        // We filter out eigenspaces that give non-connected F+ and F- as in 
the paper
+        if (is_graph_connected(aplus) && is_graph_connected(aminus)) {
+            m_eigenspaces.push_back(aes);
+            found = true;
+        } else {
+            delete aes;
+        }
+        f++;
+    }
+    return found;
+}
+
+int AutoseamAdjacency::get_num_splits()
+{
+    return m_eigenspaces.size();
+}
+
+void AutoseamAdjacency::get_split(int n, int *fplus, unsigned int* nplus, int* 
fminus, unsigned int* nminus)
+{
+    if(m_eigenspaces.size())
+        m_eigenspaces[n]->get(fplus, nplus, fminus, nminus);
+    else
+        printf("No seam generation is possible");
+}
+
+// get the longest seam with connected subgraphs F+ and F-
+int AutoseamAdjacency::get_best_split()
+{
+    int max_length= 0;
+    int best= 0;
+    for (int i=0; i < m_eigenspaces.size(); ++i) {
+        AutoseamEigenspace* aes = m_eigenspaces[i];
+        int len = aes->get_seam_length(m_adjacency);
+        if (len>max_length) {
+            max_length = len;
+            best = i;
+        }
+    }
+    return best;
+}
\ No newline at end of file

Added: branches/soc-2011-avocado/blender/intern/autoseam/AutoseamAdjacency.h
===================================================================
--- branches/soc-2011-avocado/blender/intern/autoseam/AutoseamAdjacency.h       
                        (rev 0)
+++ branches/soc-2011-avocado/blender/intern/autoseam/AutoseamAdjacency.h       
2011-06-16 17:32:24 UTC (rev 37562)
@@ -0,0 +1,29 @@
+#ifndef AUTOSEAM_ADJACENCY_H
+#define AUTOSEAM_ADJACENCY_H
+
+#include "AutoseamUtility.h"
+#include "AutoseamEigenspace.h"
+#include <vector>
+
+class AutoseamAdjacency
+{
+    public:
+        AutoseamAdjacency(int dimension);
+        ~AutoseamAdjacency();
+
+        void set(int row, int col, float value);
+        int get(int row, int col);
+        const Eigen::MatrixXd& getMatrix() const { return m_adjacency; }
+        bool generate_seam();
+        void clear_eigenspaces();
+        int get_num_splits();
+        int get_best_split();
+        void get_split(int n, int *fplus, unsigned int* nplus, int* fminus, 
unsigned int* nminus);
+    
+    private:
+        Eigen::MatrixXd m_adjacency;
+        std::vector<AutoseamEigenspace*> m_eigenspaces;
+       
+};
+
+#endif

Added: branches/soc-2011-avocado/blender/intern/autoseam/AutoseamEigenspace.cpp
===================================================================
--- branches/soc-2011-avocado/blender/intern/autoseam/AutoseamEigenspace.cpp    
                        (rev 0)
+++ branches/soc-2011-avocado/blender/intern/autoseam/AutoseamEigenspace.cpp    
2011-06-16 17:32:24 UTC (rev 37562)
@@ -0,0 +1,78 @@
+#include "AutoseamEigenspace.h"
+
+
+AutoseamEigenspace::AutoseamEigenspace(double eigenval, const Eigen::VectorXd& 
eigenvector)
+: e(eigenval), v(eigenvector)
+{
+
+}
+
+void AutoseamEigenspace::split()
+{
+    m_fplus.clear();
+    m_fminus.clear();
+    int n = v.size();
+    for (int i=0; i<n;++i) {
+        if (v[i] >= 0) {
+            m_fplus.push_back(i);
+        } else {
+            m_fminus.push_back(i);
+        }
+    }
+}
+
+
+void AutoseamEigenspace::fill_adjacency(const Eigen::MatrixXd& adj, 
Eigen::MatrixXd& adj_plus, Eigen::MatrixXd& adj_minus)
+{
+    adj_plus.resize(m_fplus.size(), m_fplus.size());
+    adj_minus.resize(m_fminus.size(), m_fminus.size());
+    
+    int m, n;
+    for (m=0; m<m_fplus.size(); ++m) {
+        for (n=0; n<m_fplus.size(); ++n) {
+            adj_plus(m,n) = adj(m_fplus[m], m_fplus[n]);
+        }
+    }
+    for (m=0; m<m_fplus.size(); ++m) {
+        adj_plus(m,m) = 0.0;
+    }
+    for (m=0; m<m_fminus.size(); ++m) {
+        for (n=0; n<m_fminus.size(); ++n) {
+            adj_minus(m,n) = adj(m_fminus[m], m_fminus[n]);
+        }
+    }
+    for (m=0; m<m_fminus.size(); ++m) {
+        adj_minus(m,m) = 0.0;
+    }
+}
+
+
+void AutoseamEigenspace::get(int *fplus, unsigned int* nplus, int* fminus, 
unsigned int* nminus)
+{
+    for (int i=0; i<m_fplus.size(); ++i) {
+        fplus[i] = m_fplus[i];
+    }
+    
+    *nplus = m_fplus.size();
+    for (int i=0; i<m_fminus.size(); ++i) {
+        fminus[i] = m_fminus[i];
+    }
+    *nminus = m_fminus.size();
+}
+
+
+int AutoseamEigenspace::get_seam_length(const Eigen::MatrixXd& adj)
+{
+    int count= 0;
+    for (int m = 0; m < m_fplus.size(); ++m) 
+    {
+        for (int n = 0; n < m_fminus.size(); ++n) {
+            if (adj( m_fplus[m], m_fminus[n] ) > 0.05 ) {
+                count++;
+                break;
+            }
+        }
+    }
+    return count;
+}
+

Added: branches/soc-2011-avocado/blender/intern/autoseam/AutoseamEigenspace.h
===================================================================
--- branches/soc-2011-avocado/blender/intern/autoseam/AutoseamEigenspace.h      
                        (rev 0)
+++ branches/soc-2011-avocado/blender/intern/autoseam/AutoseamEigenspace.h      
2011-06-16 17:32:24 UTC (rev 37562)
@@ -0,0 +1,24 @@
+#ifndef AUTOSEAM_EIGENSPACE
+#define AUTOSEAM_EIGENSPACE
+
+#include <vector>
+#include "AutoseamUtility.h"
+
+class AutoseamEigenspace
+{
+    public:
+        AutoseamEigenspace(double eigenval, const Eigen::VectorXd& 
eigenvector);
+        void split();
+        void fill_adjacency(const Eigen::MatrixXd& adj, Eigen::MatrixXd& 
adj_plus, Eigen::MatrixXd& adj_minus);
+        void get(int *fplus, unsigned int* nplus, int* fminus, unsigned int* 
nminus);
+        int get_seam_length(const Eigen::MatrixXd& adj);
+    
+    private:
+       double e;
+       Eigen::VectorXd v;
+    
+       std::vector<int> m_fplus;
+       std::vector<int> m_fminus;
+};
+
+#endif

Modified: branches/soc-2011-avocado/blender/intern/autoseam/AutoseamUtility.cpp
===================================================================
--- branches/soc-2011-avocado/blender/intern/autoseam/AutoseamUtility.cpp       
2011-06-16 17:14:38 UTC (rev 37561)
+++ branches/soc-2011-avocado/blender/intern/autoseam/AutoseamUtility.cpp       
2011-06-16 17:32:24 UTC (rev 37562)
@@ -25,19 +25,8 @@
  *
  * ***** END GPL LICENSE BLOCK *****
  */
-
-#include <Eigen/Core>
-#include <Eigen/Dense>
-#include <Eigen/Eigenvalues> 
-
-#include <iostream>
-
 #include "AutoseamUtility.h"
 
-using Eigen::MatrixXd;
-
-
-
 AutoseamUtility::AutoseamUtility()
 {
        m_A <<  1.0f, 2.0f, 0.0f,

Modified: branches/soc-2011-avocado/blender/intern/autoseam/AutoseamUtility.h
===================================================================
--- branches/soc-2011-avocado/blender/intern/autoseam/AutoseamUtility.h 
2011-06-16 17:14:38 UTC (rev 37561)
+++ branches/soc-2011-avocado/blender/intern/autoseam/AutoseamUtility.h 
2011-06-16 17:32:24 UTC (rev 37562)
@@ -30,7 +30,15 @@
 #define DUMMY_CLASS_H_INCLUDED
 
 #include <Eigen/Core>
+#include <Eigen/Dense>
+#include <Eigen/Eigenvalues> 
+#include <iostream>
 
+using Eigen::MatrixXd;
+
+
+
+
 class AutoseamUtility
 {
        public:
@@ -44,4 +52,43 @@
 
 };
 
+enum GraphNodeColor { White, Gray, Black };
+
+static void depth_first_search(const MatrixXd& adjacency, int u, 
GraphNodeColor state[]) 
+{
+    int nNodes = adjacency.cols();
+    state[u] = Gray;
+    for (int v = 0; v < nNodes; v++) {
+        if (u != v) {
+            double adj = adjacency(u, v);
+            if ((adj>0.005) && state[v] == White) {
+                depth_first_search(adjacency, v, state);
+            }
+        }
+    }
+    state[u] = Black;
+}
+
+static bool is_graph_connected(const MatrixXd& adjacency) 
+{
+    int nNodes = adjacency.cols();
+    if (nNodes > 0) {
+        GraphNodeColor *state = new GraphNodeColor[nNodes];
+        for (int i = 0; i < nNodes; i++)
+            state[i] = White;
+        depth_first_search(adjacency, 0, state);
+        bool connected = true;
+        for (int i = 0; i < nNodes; i++) {
+            if ( state[i] != Black ) {
+                connected = false;
+                break;
+            }
+        }
+        delete [] state;
+        return connected;
+    } else {
+        return false;
+    }
+}
+
 #endif
\ No newline at end of file

Modified: branches/soc-2011-avocado/blender/intern/autoseam/CMakeLists.txt
===================================================================
--- branches/soc-2011-avocado/blender/intern/autoseam/CMakeLists.txt    
2011-06-16 17:14:38 UTC (rev 37561)
+++ branches/soc-2011-avocado/blender/intern/autoseam/CMakeLists.txt    
2011-06-16 17:32:24 UTC (rev 37562)
@@ -33,6 +33,10 @@
        autoseam_C_API.cpp

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to