/toolboxes/fieldtrip/external/iso2mesh/binsurface.m

http://brainstream.googlecode.com/ · MATLAB · 91 lines · 46 code · 12 blank · 33 comment · 0 complexity · d5187a95ba217a9610cdbcbf36102efe MD5 · raw file

  1. function [node,elem]=binsurface(img,nface)
  2. %
  3. % [node,elem]=binsurface(img,nface)
  4. %
  5. % fast isosurface extraction from 3D binary images
  6. %
  7. % author: Qianqian Fang, <fangq at nmr.mgh.harvard.edu>
  8. %
  9. % input:
  10. % img: a 3D binary image
  11. % nface: nface=3 or ignored - for triangular faces,
  12. % nface=4 - square faces
  13. % nface=0 - return a boundary mask image via node
  14. %
  15. % output
  16. % elem: integer array with dimensions of NE x nface, each row represents
  17. % a surface mesh face element
  18. % node: node coordinates, 3 columns for x, y and z respectively
  19. %
  20. % the outputs of this subroutine can be easily plotted using
  21. % patch('Vertices',node,'faces',elem,'FaceVertexCData',node(:,3),
  22. % 'FaceColor','interp');
  23. % if the surface mesh has triangular faces, one can plot it with
  24. % trisurf(elem,node(:,1),node(:,2),node(:,3))
  25. %
  26. % -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
  27. %
  28. dim=size(img);
  29. newdim=dim+[1 1 1];
  30. % find the jumps (0->1 or 1->0) for all directions
  31. d1=diff(img,1,1);
  32. d2=diff(img,1,2);
  33. d3=diff(img,1,3);
  34. [ix,iy]=find(d1==1|d1==-1);
  35. [jx,jy]=find(d2==1|d2==-1);
  36. [kx,ky]=find(d3==1|d3==-1);
  37. % compensate the dim. reduction due to diff, and
  38. % wrap the indices in a bigger array (newdim)
  39. ix=ix+1;
  40. [iy,iz]=ind2sub(dim(2:3),iy);
  41. iy=sub2ind(newdim(2:3),iy,iz);
  42. [jy,jz]=ind2sub([dim(2)-1,dim(3)],jy);
  43. jy=jy+1;
  44. jy=sub2ind(newdim(2:3),jy,jz);
  45. [ky,kz]=ind2sub([dim(2),dim(3)-1],ky);
  46. kz=kz+1;
  47. ky=sub2ind(newdim(2:3),ky,kz);
  48. id1=sub2ind(newdim,ix,iy);
  49. id2=sub2ind(newdim,jx,jy);
  50. id3=sub2ind(newdim,kx,ky);
  51. if(nargin==2 && nface==0)
  52. elem=[id1 id2 id3];
  53. node=zeros(newdim);
  54. node(elem)=1;
  55. node=node(2:end-1,2:end-1,2:end-1)-1;
  56. return
  57. end
  58. % populate all the triangles
  59. xy=newdim(1)*newdim(2);
  60. if(nargin==1 || nface==3) % create triangular elements
  61. elem=[id1 id1+newdim(1) id1+newdim(1)+xy; id1 id1+newdim(1)+xy id1+xy];
  62. elem=[elem; id2 id2+1 id2+1+xy; id2 id2+1+xy id2+xy];
  63. elem=[elem; id3 id3+1 id3+1+newdim(1); id3 id3+1+newdim(1) id3+newdim(1)];
  64. else % create box elements
  65. elem=[id1 id1+newdim(1) id1+newdim(1)+xy id1+xy];
  66. elem=[elem; id2 id2+1 id2+1+xy id2+xy];
  67. elem=[elem; id3 id3+1 id3+1+newdim(1) id3+newdim(1)];
  68. end
  69. % compress the node indices
  70. nodemap=zeros(max(elem(:)),1);
  71. nodemap(elem(:))=1;
  72. id=find(nodemap);
  73. nodemap=0;
  74. nodemap(id)=1:length(id);
  75. elem=nodemap(elem);
  76. % create the coordiniates
  77. [xi,yi,zi]=ind2sub(newdim,id);
  78. % assuming the origin [0 0 0] is located at the lower-bottom corner of the image
  79. node=[xi(:),yi(:),zi(:)]-1;