Эх сурвалжийг харах

header clustering scripts

Former-commit-id: ca40bbb8aba0c67848932c065900eab5669d49b8
Alec Jacobson (jalec 11 жил өмнө
parent
commit
f182dbbfb5

+ 1 - 1
libigl-teaser.pdf.REMOVED.git-id

@@ -1 +1 @@
-e88063d58a7d4775c0bc7d3f749120c119e519e3
+e3cd39bc873032bb79fbeb7608aa1e08aba4eac2

+ 49 - 0
scripts/header_adjacency.m

@@ -0,0 +1,49 @@
+function [A,H,f2H] = header_adjacency(files)
+  % HEADER_ADJACENCY given a list of .cpp/.h files find all <igl/*.h> header
+  % files and determine mutual inclusions.
+  %
+  % Inputs:
+  %   files  list of .cpp/.h files
+  % Outputs:
+  %   A  adjacency matrix so that A(i,j) is the number of mutual includes for
+  %     H(i) and H(j)
+  %   H  list of unique headers
+  %
+  % Example:
+  %   files = textscan([ ...
+  %     ls('/some/dir/*.cpp') ...
+  %     ls('/some/dir/*.h')],'%s', 'delimiter', '\n' );
+  %   files = files{1};
+  %   [A,H] = header_adjacency(files);
+  %
+
+  mH = containers.Map();
+  f2HI = [];
+  f2HJ = [];
+  for f = 1:numel(files)
+    if isempty(regexp(files{f},'include/igl/[^/]*$'))
+      fH = regexp(fileread(files{f}),'<igl/([^.]*.h)>','tokens');
+    else
+      fH = regexp(fileread(files{f}),'"([^.]*.h)"','tokens');
+    end
+    fH = [fH{:}]';
+    for h = 1:numel(fH)
+      h_str = fH{h};
+      if ~mH.isKey(h_str)
+        mH(h_str) = mH.size(1) + 1;
+      end
+      f2HI = [f2HI(:); f];
+      f2HJ = [f2HJ(:); mH(h_str)];
+    end
+  end
+  f2H = sparse(f2HI,f2HJ,1,numel(files),mH.size(1));
+  A = f2H'*f2H;
+  % diagonal is not interesting
+  A = A - diag(diag(A));
+  keys = mH.keys;
+  values = mH.values;
+  values = [values{:}];
+  [~,I] = sort(values);
+  H = keys(I);
+
+end

+ 61 - 0
scripts/header_cluster_demo.m

@@ -0,0 +1,61 @@
+[~,extra_h] = unix('ls -1 /usr/local/igl/libigl/include/igl/*/*.h');
+[~,extra_cpp] = unix('ls -1 /usr/local/igl/libigl/include/igl/*/*.cpp');
+[~,examples] = unix('ls -1 /usr/local/igl/libigl/examples/*/*.cpp');
+[~,dropbox] = unix('ls -1 ~/Dropbox/*/*.cpp');
+files = textscan([ ...
+  ls('~/Documents/Puppet/Code/C++/*.cpp') ...
+  ls('~/Documents/Puppet/Code/C++/*.h') ...
+  ls('~/Documents/EdgeBasedLaplacian/Code/C++/src/*.cpp') ...
+  ls('~/Documents/EdgeBasedLaplacian/Code/C++/src/*.h') ...
+  ls('~/Documents/volume/winding_number/*.cpp') ...
+  ls('~/Documents/volume/winding_number/*.h') ...
+  ls('~/Documents/volume/selfintersect/src/*.cpp') ...
+  ls('~/Documents/volume/selfintersect/src/*.h') ...
+  ls('~/Documents/volume/post_graph_cut/*.cpp') ...
+  ls('~/Documents/volume/post_graph_cut/*.h') ...
+  ls('~/Documents/AutoDOF/Code/skinning/skinning/*.cpp') ...
+  ls('~/Documents/AutoDOF/Code/skinning/skinning/*.h') ...
+  ls('/usr/local/igl/libigl/include/igl/*.h') ...
+  ls('/usr/local/igl/libigl/include/igl/*.cpp') ...
+  extra_h ...
+  extra_cpp ...
+  examples ...
+  dropbox  ...
+  ],'%s', 'delimiter', '\n' );
+files = files{1};
+[~,H,f2H] = header_adjacency(files);
+% Must be included at least twice
+H = H(sum(f2H,1) > 1);
+f2H = f2H(:,sum(f2H,1) > 1);
+A = f2H' * f2H;
+% diagonal is not interesting
+A = A - diag(diag(A));
+% Must have at least median mutual includes to be an edge
+A(A(:)<1) = 0;
+% Must have at least median other mutual includes
+H = H(sum(A,2)>median(sum(A,2)));
+A = A( sum(A,2)>median(sum(A,2)), sum(A,2)>median(sum(A,2)));
+
+P = rand(numel(H),2);
+[EI,EJ] = find(tril(A+A'));
+E = [EJ EI];
+L = (A-diag(sum(A,2)));
+I = 0*speye(size(L));
+[EV,ED] = eigs(L+I,ceil(sqrt(size(A,1))),'sm');
+EV = EV(:,2:end);
+ED = ED(2:end, 2:end);
+p = 1;
+B = EV * (inv(abs(ED))^(p/2));
+
+%nsp = 2;
+%subplot(1,nsp,1);
+%plot_edges(P,E);
+%subplot(1,nsp,2);
+plot_edges(B(:,1:3),E);
+
+C = kmeans(B,size(B,2));
+
+for c = 1:max(C)
+  fprintf('%s\n',H{C==c});
+  fprintf('\n');
+end