PageRenderTime 53ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/MatlabCode/branches/Greg's Branch/Online/isosamp/iso2mesh/savesurfpoly.m

http://horwitzlab.googlecode.com/
MATLAB | 227 lines | 192 code | 12 blank | 23 comment | 38 complexity | 5f600d53da829f0205e1e6b1bc2600dc MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
  1. function savesurfpoly(v, f, holelist, regionlist, p0, p1, fname, forcebox)
  2. %
  3. % savesurfpoly(v,f,holelist,regionlist,p0,p1,fname)
  4. %
  5. % save a set of surfaces into poly format (for tetgen)
  6. %
  7. % author: Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
  8. % date: 2007/11/21
  9. %
  10. % input:
  11. % v: input, surface node list, dimension (nn,3)
  12. % if v has 4 columns, the last column specifies mesh density near each node
  13. % f: input, surface face element list, dimension (be,3)
  14. % holelist: list of holes, each hole is represented by an internal point
  15. % regionlist: list of regions, similar to holelist
  16. % p0: coordinate of one of the end of the bounding box
  17. % p1: coordinate for the other end of the bounding box
  18. % fname: output file name
  19. % forcebox: non-empty: add bounding box, []: automatic
  20. % if forcebox is a 8x1 vector, it will be used to
  21. % specify max-edge size near the bounding box corners
  22. %
  23. % -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
  24. %
  25. dobbx=0;
  26. if nargin >= 8
  27. dobbx = ~isempty(forcebox) & all(forcebox);
  28. end
  29. if ~iscell(f) && size(f, 2) == 4
  30. faceid = f(:,4);
  31. f = f(:,1:3);
  32. end
  33. if ~iscell(f)
  34. edges = surfedge(f);
  35. else
  36. edges = [];
  37. end
  38. bbxnum = 0;
  39. nodesize = [];
  40. if size(v, 2) == 4
  41. nodesize = v(:,4);
  42. v = v(:,1:3);
  43. end
  44. node = v;
  45. loopid = [];
  46. if ~isempty(edges)
  47. loops = extractloops(edges);
  48. if length(loops) < 3
  49. error('degenerated loops detected');
  50. end
  51. seg = [0 find(isnan(loops))];
  52. segnum = length(seg)-1;
  53. newloops = [];
  54. for i=1:segnum
  55. if seg(i+1)-(seg(i)+1) == 0, continue; end
  56. newloops = [newloops nan bbxflatsegment(node, loops(seg(i)+1:seg(i+1)-1))];
  57. end
  58. loops = [newloops nan];
  59. seg = [0 find(isnan(loops))];
  60. segnum = length(seg)-1;
  61. bbxnum = 6;
  62. loopcount = zeros(bbxnum, 1);
  63. loopid = zeros(segnum, 1);
  64. for i = 1:segnum % walk through the edge loops
  65. subloop = loops(seg(i)+1:seg(i+1)-1);
  66. if isempty(subloop), continue; end
  67. boxfacet = find(sum(abs(diff(v(subloop,:)))) < 1e-8); % find a flat loop
  68. if length(boxfacet) == 1 % if the loop is flat along x/y/z dir
  69. bf = boxfacet(1); % no degeneracy allowed
  70. if sum(abs(v(subloop(1), bf)-p0(bf))) < 1e-2
  71. loopcount(bf) = loopcount(bf)+1;
  72. v(subloop,bf) = p0(bf);
  73. loopid(i) = bf;
  74. elseif sum(abs(v(subloop(1), bf)-p1(bf))) < 1e-2
  75. loopcount(bf+3) = loopcount(bf+3)+1;
  76. v(subloop,bf) = p1(bf);
  77. loopid(i) = bf+3;
  78. end
  79. end
  80. end
  81. end
  82. if dobbx && isempty(edges)
  83. bbxnum = 6;
  84. loopcount = zeros(bbxnum, 1);
  85. end
  86. if dobbx || ~isempty(edges)
  87. nn = size(v, 1);
  88. boxnode = [p0;p1(1) p0(2:3);p1(1:2) p0(3);p0(1) p1(2) p0(3);
  89. p0(1:2) p1(3);p1(1) p0(2) p1(3);p1;p0(1) p1(2:3)];
  90. boxelem = [
  91. 4 nn nn+3 nn+7 nn+4; % x=xmin
  92. 4 nn nn+1 nn+5 nn+4; % y=ymin
  93. 4 nn nn+1 nn+2 nn+3; % z=zmin
  94. 4 nn+1 nn+2 nn+6 nn+5; % x=xmax
  95. 4 nn+2 nn+3 nn+7 nn+6; % y=ymax
  96. 4 nn+4 nn+5 nn+6 nn+7];% z=zmax
  97. node = [v;boxnode];
  98. end
  99. node = [(0:size(node,1)-1)' node];
  100. fp = fopen(fname, 'w');
  101. fprintf(fp, '#node list\n%d 3 0 0\n', length(node));
  102. fprintf(fp, '%d %f %f %f\n', node');
  103. if ~iscell(f)
  104. fprintf(fp, '#facet list\n%d 1\n', length(f)+bbxnum);
  105. elem = [3*ones(length(f), 1) f-1 ones(length(f), 1)];
  106. if ~isempty(elem)
  107. fprintf(fp,'1 0\n%d %d %d %d %d\n', elem');
  108. end
  109. else % if the surface is recorded as a cell array
  110. totalplc = 0;
  111. for i = 1:length(f)
  112. if ~iscell(f{i})
  113. totalplc = totalplc+size(f{i}, 1);
  114. else
  115. totalplc = totalplc+size(f{i}{1}, 1);
  116. end
  117. end
  118. fprintf(fp, '#facet list\n%d 1\n', totalplc+bbxnum);
  119. for i = 1:length(f)
  120. plcs = f{i};
  121. faceid = -1;
  122. if iscell(plcs) % if each face is a cell, use plc{2} for face id
  123. if length(plcs) > 1
  124. faceid = plcs{2};
  125. end
  126. plcs = plcs{1};
  127. end
  128. for row = 1:size(plcs, 1);
  129. plc = plcs(row,:);
  130. if any(isnan(plc)) % we use nan to separate outter contours and holes
  131. holeid = find(isnan(plc));
  132. if faceid > 0
  133. fprintf(fp, '%d %d %d\n%d', length(holeid)+1, length(holeid), faceid, holeid(1)-1);
  134. else
  135. fprintf(fp, '%d %d\n%d', length(holeid)+1, length(holeid), holeid(1)-1);
  136. end
  137. fprintf(fp, '\t%d', plc(1:holeid(1)-1)-1);
  138. fprintf(fp, '\t1\n');
  139. for j = 1:length(holeid)
  140. if j == length(holeid)
  141. fprintf(fp, '%d', length(plc(holeid(j)+1:end)));
  142. fprintf(fp, '\t%d', plc(holeid(j)+1:end)-1);
  143. else
  144. fprintf(fp, '%d', length(plc(holeid(j)+1:holeid(j+1)-1)));
  145. fprintf(fp, '\t%d', plc(holeid(j)+1:holeid(j+1)-1)-1);
  146. end
  147. fprintf(fp, '\t1\n');
  148. end
  149. for j = 1:length(holeid)
  150. if j == length(holeid)
  151. fprintf(fp, '%d %f %f %f\n', j, mean(node(plc(holeid(j)+1:end),2:4)));
  152. else
  153. fprintf(fp, '%d %f %f %f\n', j, mean(node(plc(holeid(j)+1:holeid(j+1)-1),2:4)));
  154. end
  155. end
  156. else
  157. if faceid > 0
  158. fprintf(fp, '1 0 %d\n%d', faceid, length(plc));
  159. else
  160. fprintf(fp, '1 0\n%d', length(plc));
  161. end
  162. fprintf(fp, '\t%d', plc-1);
  163. fprintf(fp, '\t1\n');
  164. end
  165. end
  166. end
  167. end
  168. if dobbx || ~isempty(edges)
  169. for i = 1:bbxnum
  170. fprintf(fp, '%d %d 1\n', 1+loopcount(i), loopcount(i));
  171. fprintf(fp, '%d %d %d %d %d\n', boxelem(i,:));
  172. if ~isempty(edges) && loopcount(i) && ~isempty(find(loopid == i, 1))
  173. endid = find(loopid == i);
  174. for k = 1:length(endid)
  175. j = endid(k);
  176. subloop = loops(seg(j)+1:seg(j+1)-1);
  177. fprintf(fp, '%d ', length(subloop));
  178. fprintf(fp, '%d ', subloop-1);
  179. fprintf(fp, '\n');
  180. end
  181. for k = 1:length(endid)
  182. j = endid(k);
  183. subloop = loops(seg(j)+1:seg(j+1)-1);
  184. fprintf(fp, '%d %f %f %f\n', k, internalpoint(v, subloop)); %mean(v(subloop,:)));
  185. end
  186. end
  187. end
  188. end
  189. if size(holelist,1)
  190. fprintf(fp, '#hole list\n%d\n', size(holelist, 1));
  191. for i = 1:size(holelist, 1)
  192. fprintf(fp, '%d %f %f %f\n', i, holelist(i,:));
  193. end
  194. else
  195. fprintf(fp, '#hole list\n0\n');
  196. end
  197. if size(regionlist, 1)
  198. fprintf(fp, '#region list\n%d\n', size(regionlist, 1));
  199. for i = 1:size(regionlist, 1)
  200. fprintf(fp, '%d %f %f %f %d\n', i, regionlist(i,:), i);
  201. end
  202. end
  203. fclose(fp);
  204. if ~isempty(nodesize)
  205. if size(nodesize, 1)+size(forcebox(:), 1) == size(node, 1)
  206. nodesize = [nodesize; forcebox(:)];
  207. end
  208. fid = fopen(regexprep(fname, '\.poly$', '.mtr'), 'w');
  209. fprintf(fid, '%d 1\n', size(nodesize, 1));
  210. fprintf(fid, '%f\n', nodesize);
  211. fclose(fid);
  212. end
  213. end