#ベルト抜きスクリプト #アルゴリズム変更(2010.02.02) #上位パートに変換がかかっていると使用できないように変更(2010.03.03) #shade1202に対応(2010.04.09) #メタセコイアの「ナイフ>連続辺を連続消去」みたいなスクリプトです。(ただし消す辺は手動で全て選択しないといけない) #辺は消えるけど、辺を境に隣接する面同士を結合させていきます #頂点あるいは辺はあらかじめ手動で選択しておいてください。 #注意(辺を抜いた場合、5点以上で構成される面が残るケースでは面にポリゴンは張られません) def return_henlist(face): #面番号から面を構成する辺の番号を返す #前後にsetup_winged_edgeとclean_winged_edgeが必要 tempvlist=xshade.scene().active_shape().face(face).vertex_indices henlist=[] for i in tempvlist: tempf=xshade.scene().active_shape().eccwfv(face,i,False) henlist.append(tempf) return henlist def hantei_same_num(list1): #リスト内に同じ値が存在するなら1を返し、存在しないなら0を返す関数 例[1,1,3]→1 [1,3]→0 list1.sort() nagasa=len(list1) returnnum=0 if nagasa>1: kesu=[] for i in range(nagasa-1): if list1[i]==list1[i+1]: returnnum=1 return returnnum def return_menlist(edgenumber): #その辺を共有する面の面番号をリストで返す(引数 辺番号) menlist=[] edgevertex=[xshade.scene().active_shape().edge(edgenumber).v0,xshade.scene().active_shape().edge(edgenumber).v1] totalmenmen=xshade.scene().active_shape().number_of_faces for i in range(totalmenmen): konomen=0 temppoint=list(xshade.scene().active_shape().face(i).vertex_indices) for j in temppoint: if edgevertex[0]==j: konomen+=1 if edgevertex[1]==j: konomen+=1 if konomen==2: menlist.append(i) return menlist 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 substract_b_from_a(lista,listb): #リストAからリストBに存在する要素を抜く a[1,2,3,4,4,5] b[3,4] 結果[1,2,5] #リストBに重複する値が存在するとエラーが出るので、あらかじめ重複する値は消しておく kesulis=[] for i in listb: for j in lista: if j==i: kesulis.append(i) for i in kesulis: lista.remove(i) return lista dousasuru=1 if dousasuru>0: #上位パートに変換がかかっているなら動作しない if xshade.scene().active_shape().local_to_world_matrix!=((1.0, 0.0, 0.0, 0.0), (0.0, 1.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0, 0.0, 0.0, 1.0)): dousasuru=0 dialog=xshade.create_dialog() dialog.append_push_button('上位パートに変換がかかっているため') dialog.append_push_button('スクリプトが実行できません') dialog.ask('エラー') if dousasuru==1 and xshade.scene().is_modify_mode==True and xshade.scene().active_shape().type==7: xscene=xshade.scene() ashape=xshade.scene().active_shape() imamodify=1 #念のため元の形状をクリップボードにコピー xshade.scene().active_shape().copy() xshade.scene().enter_modify_mode() #現在の選択モード(頂点、辺、面を記憶しておく) imamode=xshade.scene().selection_mode dousasuru=1 #1なら動作する 0なら動作しない if imamode==1: activeelist=[] for i in range(xshade.scene().active_shape().number_of_edges): if xshade.scene().active_shape().edge(i).active_order>0: activeelist.append(i) #ポリゴンメッシュかどうか if xshade.scene().active_shape().type!=7: dousasuru=0 #選択頂点数が三個以上か activevertexnum=0 activeplist=[] if xshade.scene().selection_mode!=2: xshade.scene().selection_mode=2 for i in range(xshade.scene().active_shape().total_number_of_control_points): if xshade.scene().active_shape().vertex(i).active_order>0: activevertexnum+=1 activeplist.append(i) if activevertexnum<3: dousasuru=0 eflist=[]#辺の隣接面リスト 辺の番号順に格納 for i in range(ashape.number_of_edges): eflist.append([]) #面の向きを統一 ashape.adjust_face_direction() ashape.setup_winged_edge() for i in range(ashape.number_of_faces): thenlist=return_henlist(i) for gg in thenlist: ttt=eflist[gg] ttt.append(i) eflist[gg]=ttt ashape.clean_winged_edge() #辺選択モードにして、辺に隣接する面を辺毎に調べ、同じ面を共有してないかチェックする xshade.scene().selection_mode=1 activeedgelist=[] testmenlist=[] for i in range(xshade.scene().active_shape().number_of_edges): if xshade.scene().active_shape().edge(i).active_order>0: activeedgelist.append(i) testmenlist+=eflist[i] if hantei_same_num(testmenlist)==1: dousasuru=0 if imamode!=1: xscene.selection_mode=2 for gg in range(ashape.total_number_of_control_points): ashape.vertex(gg).active=False for gg in activeplist: ashape.vertex(gg).active=True else: for gg in range(ashape.number_of_edges): ashape.edge(gg).active=False for gg in activeelist: ashape.edge(gg).active=True #95 if dousasuru==1: if xshade.scene().selection_mode!=2: xshade.scene().selection_mode=2 #選択されている頂点をリストに格納 activepointlist=[] for i in range(xshade.scene().active_shape().total_number_of_control_points): if xshade.scene().active_shape().vertex(i).active_order>0: activepointlist.append(i) 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 ttt=vvlist[vv0] ttt.append(vv1) vvlist[vv0]=ttt ttt=vvlist[vv1] ttt.append(vv0) vvlist[vv1]=ttt #選択頂点ごとに、その頂点とつながっていてかつ選択頂点ではない頂点のリストをリストに格納 setuzokulist=[] #リストの中に接続頂点のリストを入れる for i in activepointlist: templist=vvlist[i] templist=substract_b_from_a(templist,activepointlist) setuzokulist.append(templist) #その頂点とつながっていてかつ選択頂点ではない頂点の数が2個の場合のみ、その頂点を消して、接続頂点同士を接続する xshade.scene().active_shape().begin_removing_control_points() for i in range(len(activepointlist)): if len(setuzokulist[i])==2: xshade.scene().active_shape().remove_control_point(activepointlist[i]) temp2=setuzokulist[i] xshade.scene().active_shape().append_edge(temp2[0],temp2[1]) xshade.scene().active_shape().end_removing_control_points() if xshade.scene().selection_mode!=imamode: xshade.scene().selection_mode=imamode #クリップボードに形状をコピーした場合、以下の「編集モードに入る」を実行しないと編集モードでなくなってしまいます xshade.scene().enter_modify_mode() xshade.scene().active_shape().adjust_face_direction() kekka=True imasele=xshade.scene().selection_mode #ダイアログを表示して、選択頂点数と結果を確認してもらう #okで確定(何もせず)cancelだと元に戻す if dousasuru==1: xshade.idle(10) dialog=xshade.create_dialog() idx3=dialog.append_push_button('処理を確定する場合はokを') idx4=dialog.append_push_button('取り消す場合はcancelを押してください') if imamodify==1: xshade.scene().enter_modify_mode() kekka=dialog.ask('ベルト抜き(面を残して辺を一括消去)') #キャンセルなら形状を削除してクリップボードの形状を元に戻す #さらに頂点や辺の選択状態も元に戻す? if kekka==False: idou1=0 if xshade.scene().active_shape().has_sis==True: idou1=1 xshade.scene().paste() xshade.scene().select_sister(1) xshade.scene().clear() if idou1==1: xshade.scene().select_brother() xshade.scene().enter_modify_mode() xshade.scene().selection_mode=2 for i in activepointlist: xshade.scene().active_shape().vertex(i).active=True if imasele==1: xshade.scene().selection_mode=1 xshade.idle(10)