#重複辺検出(重複面検出) #複数の頂点を選択して一点集中した後、ウェルドしなかった場合、その近辺を間違って #重複辺と判断してしまうバグを修正(2010.02.04) #ついでに高速化 #同一の頂点からほぼ同じ方向に二本の線が出ていたら、「長い方(エッジの二頂点間の距離が遠い方)」を選択リストに加える #編集モードの辺選択モードに入り、一度全ての辺の選択を解除してから、重複辺のリストにしたがって辺を選択状態にする #重複辺が選択状態になったら、あとはユーザーがdelすれば良い #『まったく同じ長さ』の重複辺が同位置に2本以上ある場合は、重複辺のうち片方しか選択されません。長さが違ってる場合はどっちも選択されます。 #例)直線ABCD(AD間は一直線)があって、AB、BC、CD、AC、ADと辺ができてる状態では重複辺であるACとADが選択状態になりますが #AB、BC、CD、AC、AC、ADと、重複辺のACが2本できてる状態では、AC1本とAD1本しか選択状態になりません。 #そのため、念のため、重複辺検出→delキーで削除を行った後も、重複辺が残っていないか何回かスクリプトを実行してみてください。 #精度はいくらくらいにするか #極にエッジが集中してる箇所は計算が半端ない事にならないか(5点以上と接続されている頂点は計算から除外する?) #動作条件 #形状のタイプがポリゴンメッシュ(7) #編集モードに入ってるかどうかはどうでもいい #同じく選択モードがいずれか(頂点、辺、面)でもいい def return_kumiawase(list1): #リスト内の値を組み合わせたリストを返す [1,2,3,4]→[[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]] #def_erase_same_numが必要 returnlist=[] for i in list1: for j in list1: if i!=j: tempp=[i,j] tempp.sort() returnlist.append(tempp) erase_same_num(returnlist) return returnlist def erase_same_num(list1): #リスト内に同じ値が重複する場合は一つに減らす関数 例[1,1,1,3,3,4]→[1,3,4] list1.sort() nagasa=len(list1) if nagasa>1: kesu=[] for i in range(nagasa-1): if list1[i]==list1[i+1]: kesu.append(list1[i]) kesukaisuu=len(kesu) if kesukaisuu>0: for i in kesu: list1.remove(i) def return_pointlist(pointnum): #その点と接続されている頂点の頂点番号をリストで返す(引数 頂点番号) pointlist=[] totaledgesuu=xshade.scene().active_shape().number_of_edges for i in range(totaledgesuu): if xshade.scene().active_shape().edge(i).v0==pointnum: pointlist.append(xshade.scene().active_shape().edge(i).v1) if xshade.scene().active_shape().edge(i).v1==pointnum: pointlist.append(xshade.scene().active_shape().edge(i).v0) return pointlist def return_edge_number(pointnum1,pointnum2): #頂点二つの頂点番号を与えると、その頂点で構成される辺の辺番号を返す #エラー(辺の両端のポイントでは無い)の場合は-1を返す returnnum=-1 for i in range(xshade.scene().active_shape().number_of_edges): if xshade.scene().active_shape().edge(i).v0==pointnum1 and xshade.scene().active_shape().edge(i).v1==pointnum2: returnnum=i if xshade.scene().active_shape().edge(i).v1==pointnum1 and xshade.scene().active_shape().edge(i).v0==pointnum2: returnnum=i return returnnum xscene=xshade.scene() ashape=xshade.scene().active_shape() if xshade.scene().active_shape().type==7: pointlist=[] #全頂点のリスト tyouhukulist=[]#重複辺(長い方)の辺番号リスト vvlist=[]#頂点と接続されている頂点のリストを頂点番号順に格納したもの for i in range(ashape.total_number_of_control_points): vvlist.append([]) for i in range(ashape.number_of_edges): vv0=ashape.edge(i).v0 vv1=ashape.edge(i).v1 temp=vvlist[vv0] temp.append(vv1) vvlist[vv0]=temp temp=vvlist[vv1] temp.append(vv0) vvlist[vv1]=temp #各頂点ごとに重複辺の検査 for i in range(xshade.scene().active_shape().total_number_of_control_points): setuzokupointlist=[]#その頂点に接続されているポイントリスト setuzokupointlist=vvlist[i] if len(setuzokupointlist)<14: xii=xshade.scene().active_shape().vertex(i).position[0] yii=xshade.scene().active_shape().vertex(i).position[1] zii=xshade.scene().active_shape().vertex(i).position[2] veclist=[]#各接続頂点と頂点iのベクトルリスト for pp in setuzokupointlist: xpp=xshade.scene().active_shape().vertex(pp).position[0] ypp=xshade.scene().active_shape().vertex(pp).position[1] zpp=xshade.scene().active_shape().vertex(pp).position[2] # if xpp!=xii and yii!=ypp and zii!=zpp: # veclist.append([xpp-xii,ypp-yii,zpp-zii,pp])#四項目にppを入れるのは、後で辺番号を得るため veclist.append([xpp-xii,ypp-yii,zpp-zii,pp])#四項目にppを入れるのは、後で辺番号を得るため #ベクトルリストを比較 kumi=[] for jj in range(len(veclist)): kumi.append(jj) tempkumi=return_kumiawase(kumi) seido=0.0001 for jj in tempkumi: jj0long=veclist[jj[0]][0]*veclist[jj[0]][0]+veclist[jj[0]][1]*veclist[jj[0]][1]+veclist[jj[0]][2]*veclist[jj[0]][2] jj1long=veclist[jj[1]][0]*veclist[jj[1]][0]+veclist[jj[1]][1]*veclist[jj[1]][1]+veclist[jj[1]][2]*veclist[jj[1]][2] templong=pow(jj0long*jj1long,0.5) if jj0long!=0 and jj1long!=0: if abs(templong-(veclist[jj[0]][0]*veclist[jj[1]][0]+veclist[jj[0]][1]*veclist[jj[1]][1]+veclist[jj[0]][2]*veclist[jj[1]][2]))0: idx=dialog.append_push_button('重複辺のみを選択状態にしました') else: idx=dialog.append_push_button('重複辺は見つかりませんでした') dialog.ask('重複辺検出')