facenb=faceneighbors(t,opt) to find 4 face-neighboring elements of a tetrahedron author: Qianqian Fang, <q.fang at neu.edu> input: t: tetrahedron element list, 4 columns of integers opt: if opt='surface', return boundary triangle list (should be the same as the face output from v2m) if opt='rowmajor', same as 'surface', except the order of the triangles are in the row-major order % otherwise, return the element list for each element: each row contains 4 numbers, representing the element indices sharing triangular faces [1 2 3],[1 2 4],[1 3 4] and [2 3 4] in order, where 1~4 is the node local index. if the index is 0, indicating the face has no neighbor (i.e. a boundary face) output: facenb: see opt -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
0001 function facenb=faceneighbors(t,opt) 0002 % 0003 % facenb=faceneighbors(t,opt) 0004 % 0005 % to find 4 face-neighboring elements of a tetrahedron 0006 % 0007 % author: Qianqian Fang, <q.fang at neu.edu> 0008 % 0009 % input: 0010 % t: tetrahedron element list, 4 columns of integers 0011 % opt: if opt='surface', return boundary triangle list 0012 % (should be the same as the face output from v2m) 0013 % if opt='rowmajor', same as 'surface', except the 0014 % order of the triangles are in the row-major order 0015 %% 0016 % otherwise, return the element list for each element: 0017 % each row contains 4 numbers, representing the element 0018 % indices sharing triangular faces [1 2 3],[1 2 4],[1 3 4] 0019 % and [2 3 4] in order, where 1~4 is the node local index. 0020 % if the index is 0, indicating the face has no neighbor 0021 % (i.e. a boundary face) 0022 % 0023 % output: 0024 % facenb: see opt 0025 % 0026 % -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net) 0027 % 0028 0029 faces=[t(:,[1,2,3]); 0030 t(:,[1,2,4]); 0031 t(:,[1,3,4]); 0032 t(:,[2,3,4])]; 0033 0034 faces=sort(faces,2); 0035 [foo,ix,jx]=unique(faces,'rows'); 0036 if(isoctavemesh) 0037 u=unique(jx); 0038 qx=u(hist(jx,u)==2); 0039 else 0040 vec=histc(jx,1:max(jx)); 0041 qx=find(vec==2); 0042 end 0043 0044 nn=max(t(:)); 0045 ne=size(t,1); 0046 facenb=zeros(size(t)); 0047 0048 % now I need to find all repeatitive elements 0049 % that share a face, to do this, unique('first') 0050 % will give me the 1st element, and 'last' will 0051 % give me the second. There will be no more than 2 0052 0053 % doing this is 60 times faster than doing find(jx==qx(i)) 0054 % inside a loop 0055 0056 if(isoctavemesh || datenum(version('-date'))>datenum('January 27 2006')) % compare to matlab 7.2 0057 [ujx,ii]=unique(jx,'first'); 0058 [ujx,ii2]=unique(jx,'last'); 0059 else 0060 ujx=unique(jx); 0061 [t1,ii2]=ismember(ujx,jx); 0062 [t1,ii]=ismember(ujx,flipwd(jx(:))); 0063 ii=length(jx)-ii+1; 0064 end 0065 0066 % iddup is the list of all pairs that share a common face 0067 0068 iddup=[ii(qx) ii2(qx)]; 0069 faceid=ceil(iddup/ne); 0070 eid=mod(iddup,ne); 0071 eid(eid==0)=ne; 0072 0073 % now rearrange this list into an element format 0074 0075 for i=1:length(qx) 0076 facenb(eid(i,1),faceid(i,1))=eid(i,2); 0077 facenb(eid(i,2),faceid(i,2))=eid(i,1); 0078 end 0079 0080 % facenb may contain 0s, that just means the corresponding 0081 % face is a boundary face and has no neighbor. 0082 0083 % if the second option is 'surface', I am going to find 0084 % and return surface patches only 0085 0086 if(nargin==2) 0087 if(strcmp(opt,'surface')) 0088 facenb=faces(find(facenb==0),:); 0089 elseif(strcmp(opt,'rowmajor')) 0090 index=[1:length(faces)]; 0091 index=(reshape(index,[],4))'; 0092 faces=faces(index(:),:); 0093 facenb=faces(find(facenb'==0),:); 0094 else 0095 error(['supplied option "' opt '" is not supported.']); 0096 end 0097 end