extract connected surface & make normal vector outward [Fnew, Vnew, xxn, indx, ix_miss] = vb_out_normal_surf(F,V) --- Input V : vertex of surface F : patch index normal_mode --- Output normal_mode = 0 Vnew : vertex coordinate for connected surface Fnew : patch index for connected surface xxn : normal vector for connected surface points 'Vnew' indx : original vertex index of connected vertex points ix_miss : original vertex index of disconnected vertex points normal_mode = 1 (Default) Vnew = V Fnew : patch index for connected surface xxn : normal vector for 'V' xxn(n,:) = 0, if V(n,:) is disconnected point indx : vertex index of connected vertex points ix_miss : vertex index of disconnected vertex points M. Sato 2006-7-20 ポリゴンモデルの三角面法線の向きを外向きに揃える アルゴリズム 0.候補 周辺頂点リストに関するループ 1.候補 周辺頂点リストからルート頂点を選ぶ 2.ルート点の未処理隣接三角面を探す 3.隣接三角面の中で前回最終頂点を含むものを探す 4.三角面頂点の並び方を揃える 5.三角面のもう一つの頂点を今回の最終頂点にする 6.周辺頂点リストに向きを確定した辺の頂点を追加する 7.未処理面が残っていれば2へ戻る 8.未処理の周辺頂点が残っていれば1へ戻る 9.確定した周辺頂点リストを新しい候補リストにして0に戻る Copyright (C) 2011, ATR All Rights Reserved. License : New BSD License(see VBMEG_LICENSE.txt)
0001 function [Fnew, Vnew, xxn, indx, ix_miss] = vb_out_normal_surf(F,V,normal_mode) 0002 % extract connected surface & make normal vector outward 0003 % [Fnew, Vnew, xxn, indx, ix_miss] = vb_out_normal_surf(F,V) 0004 % --- Input 0005 % V : vertex of surface 0006 % F : patch index 0007 % normal_mode 0008 % --- Output 0009 % normal_mode = 0 0010 % Vnew : vertex coordinate for connected surface 0011 % Fnew : patch index for connected surface 0012 % xxn : normal vector for connected surface points 'Vnew' 0013 % indx : original vertex index of connected vertex points 0014 % ix_miss : original vertex index of disconnected vertex points 0015 % normal_mode = 1 (Default) 0016 % Vnew = V 0017 % Fnew : patch index for connected surface 0018 % xxn : normal vector for 'V' 0019 % xxn(n,:) = 0, if V(n,:) is disconnected point 0020 % indx : vertex index of connected vertex points 0021 % ix_miss : vertex index of disconnected vertex points 0022 % 0023 % M. Sato 2006-7-20 0024 % 0025 % ポリゴンモデルの三角面法線の向きを外向きに揃える 0026 % 0027 % アルゴリズム 0028 %0.候補 周辺頂点リストに関するループ 0029 %1.候補 周辺頂点リストからルート頂点を選ぶ 0030 %2.ルート点の未処理隣接三角面を探す 0031 %3.隣接三角面の中で前回最終頂点を含むものを探す 0032 %4.三角面頂点の並び方を揃える 0033 %5.三角面のもう一つの頂点を今回の最終頂点にする 0034 %6.周辺頂点リストに向きを確定した辺の頂点を追加する 0035 %7.未処理面が残っていれば2へ戻る 0036 %8.未処理の周辺頂点が残っていれば1へ戻る 0037 %9.確定した周辺頂点リストを新しい候補リストにして0に戻る 0038 % 0039 % Copyright (C) 2011, ATR All Rights Reserved. 0040 % License : New BSD License(see VBMEG_LICENSE.txt) 0041 0042 if ~exist('normal_mode','var'), normal_mode = 1; end; 0043 0044 seedID=1; 0045 0046 Npoint = size(V,1); % 頂点数 0047 Npatch = size(F,1); % 三角面数 0048 0049 xxn = zeros(Npoint,3); % 法線 0050 0051 Plist = zeros(Npoint,2); % 候補 周辺頂点リスト 0052 Vlist = zeros(Npoint,2); % 向き確定 周辺頂点リスト 0053 Vflg = zeros(Npoint,1); % 頂点処理済みフラグ 0054 Fflg = zeros(Npatch,1); % 三角面処理済みフラグ 0055 FF = zeros(Npatch,3); % 三角面インデックス 0056 0057 % 隣接点インデックスリストの作成 0058 xxF = vb_neighbor_index(V,F); 0059 0060 % ルートインデックス 0061 Plist(1,:) = [seedID, xxF{seedID}(1,1)]; 0062 0063 Nlist =1;% 候補 周辺頂点数 0064 Nroot =0;% 処理済み頂点数 0065 0066 while Nlist > 0, 0067 0068 Nedge = 0;% 向き確定 周辺頂点数 0069 0070 % 周辺頂点に関するループ 0071 for n=1:Nlist, 0072 % root インデックスと next インデックスの更新 0073 root = Plist(n,1); 0074 next = Plist(n,2); 0075 0076 % root の隣接点インデックスリスト 0077 nextID = xxF{root}; 0078 0079 % 隣接点リスト 0080 nlist1 = nextID(:,1); % 隣接点リスト1 0081 nlist2 = nextID(:,2); % 隣接点リスト2 0082 flist = nextID(:,3); % 隣接三角面リスト 0083 0084 % 未処理の面インデックスを探す 0085 nextix = find( Fflg(flist) == 0 ); 0086 0087 if isempty(nextix), 0088 continue; 0089 end; 0090 0091 % 未処理面のインデックスリスト 0092 nlist1 = nlist1(nextix); 0093 nlist2 = nlist2(nextix); 0094 flist = flist(nextix); 0095 0096 Nnext = length(nextix); 0097 Nnew = Nnext; 0098 0099 % root に隣接する未処理面ループ 0100 for i=1:Nnext, 0101 % nlist1/2 の中で、前回の隣接頂点 next を含む面の探索 0102 jx1 = find( nlist1==next ); 0103 jx2 = find( nlist2==next ); 0104 0105 if ~isempty(jx1), 0106 nold = next; 0107 jj = jx1(1); % next を含む面のリスト内番号 0108 fid = flist(jj); % next を含む面の面番号 0109 next = nlist2(jj); % この面のもう一つの三角面頂点 0110 0111 % 向き確定 周辺頂点リストに追加 0112 Nedge = Nedge + 1; 0113 Vlist(Nedge,:) = [next nold]; 0114 % 三角面頂点インデックスの入れ替え 0115 FF(fid,:) = [root, nold, next]; 0116 % この面を処理済みリストに入れる 0117 Fflg(fid) = 1; 0118 % この頂点を処理済みにする 0119 Vflg([root, nold, next]) = 1; 0120 0121 % この面を隣接面リストから削除 0122 inew = [1:(jj-1),(jj+1):Nnew]; 0123 flist = flist(inew); 0124 nlist1 = nlist1(inew); 0125 nlist2 = nlist2(inew); 0126 Nnew = Nnew-1; 0127 elseif ~isempty(jx2), 0128 nold = next; 0129 jj = jx2(1); % next を含む面のリスト内番号 0130 fid = flist(jj); % next を含む面の面番号 0131 next = nlist1(jj); % この面のもう一つの三角面頂点 0132 0133 % 向き確定 周辺頂点リストに追加 0134 Nedge = Nedge + 1; 0135 Vlist(Nedge,:) = [next nold]; 0136 % 三角面頂点インデックスの入れ替え 0137 FF(fid,:) = [root, nold, next]; 0138 % この面を処理済みリストに入れる 0139 Fflg(fid) = 1; 0140 % この頂点を処理済みにする 0141 Vflg([root, nold, next]) = 1; 0142 0143 % この面を隣接面リストから削除 0144 inew = [1:(jj-1),(jj+1):Nnew]; 0145 flist = flist(inew); 0146 nlist1 = nlist1(inew); 0147 nlist2 = nlist2(inew); 0148 Nnew = Nnew-1; 0149 end; 0150 end 0151 % END- (root) に隣接する未処理面ループ 0152 0153 end; 0154 % END-周辺頂点に関するループ 0155 0156 % 候補 周辺頂点リストの更新 0157 Nlist = Nedge; 0158 Plist(1:Nedge,:) = Vlist(1:Nedge,:); 0159 0160 end 0161 0162 % 処理済みの頂点と三角面を取り出す 0163 indx = find(Vflg == 1); 0164 inxf = find(Fflg == 1); 0165 Fnew = FF(inxf,:); 0166 0167 % 未処理の頂点と三角面を取り出す 0168 ix_miss = find(Vflg == 0); 0169 0170 switch normal_mode 0171 case 0 0172 % Vnew : connected surface vertex 0173 % xxn : normal vector for 'Vnew' 0174 [Vnew, Fnew] = vb_trans_index( V, Fnew, indx); 0175 % outward normal vector 0176 [xxn , Fnew] = vb_out_normal_vect(Vnew,Fnew); 0177 case 1 0178 % Vnew = V 0179 % xxn(n,:) = 0, if V(n,:) is disconnected point 0180 Vnew = V; 0181 % outward normal vector 0182 [xxn , Fnew] = vb_out_normal_vect(Vnew,Fnew); 0183 xxn(ix_miss,:) = 0; 0184 end 0185 0186 %fprintf('New version\n')