import copy #ステップ選択 #ポリゴンメッシュの面選択モードで、指定した間隔をあけて面をループ選択するスクリプト #ビトウィーンモードの場合は選択した範囲内でだけビトウィーン選択が行えます。 #メッシュツールウィジェットに追加する場合はutf-8の対応をしておく #辺もステップ選択できるように改良 #アルゴリズム変更(2010.02.10) #ダイアログを閉じても設定が保持されるよう変更 #ビトウィーン選択モード追加(2010.02.20) #内包面が存在すると無限ループする場合があるので、最初に内包面が存在しないかどうかをチェック(2010.02.22) #動作条件 #選択形状がポリゴンメッシュ #編集モードに入っている #面選択モード #面が一つ以上選択されている #最後に選択した面の頂点の数が4個(ループ選択は端か、面の頂点数が4個以外のところでとまる。) #設定項目 #方向(houkou) 縦か横か #向き(muki) 左周りか右周りか #モード(mode) 選択に追加するか、選択から除外するか #モード2(mode2) 通常モードかビトウィーン選択モードか #間隔(step) この間隔で選択に追加 def sort_face_by_active_order(facelist): #頂点の選択番号(active_order)順にリストの面番号をソートしてリストを返す #ソート templist=[] for i in facelist: templist.append(i) newlist=[] while(len(newlist)0: activefacelist.append(i) if len(activefacelist)>0: #選択番号順に並び替える activefacelist=sort_face_by_active_order(activefacelist) startface=activefacelist[len(activefacelist)-1] startfacevlist=xshade.scene().active_shape().face(startface).vertex_indices if len(startfacevlist)==4:dousasuru=1 if dousasuru==1: #ここに初期値 houkou=0 muki=0 mode=0 mode2=0 step=1 renzoku=1 dfhoukou=houkou dfmuki=muki dfmode=mode dfmode2=mode2 dfstep=step dfrenzoku=renzoku while(renzoku==1): #ダイアログ開く dialog=xshade.create_dialog_with_uuid('0x51900F55') dialog.append_default_button() dialog.begin_group() idx4=dialog.append_radio_button('/通常モード/ビトウィーンモード') dialog.end_group() dialog.begin_group() idx0=dialog.append_radio_button('/選択に追加する/選択から除外する') dialog.end_group() dialog.begin_group('通常モード時') idx1=dialog.append_radio_button('方向(縦・横)/A/B') idx2=dialog.append_radio_button('向き/1/2') dialog.end_group() idx3=dialog.append_selection('間隔/0/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30') dialog.set_default_value(idx0,dfmode) dialog.set_default_value(idx1,dfhoukou) dialog.set_default_value(idx2,dfmuki) dialog.set_default_value(idx3,dfstep) dialog.set_default_value(idx4,dfmode2) kekka=dialog.ask('ステップ選択') if kekka==False:renzoku=0 if kekka==True: mode=dialog.get_value(idx0) mode2=dialog.get_value(idx4) houkou=dialog.get_value(idx1) muki=dialog.get_value(idx2) step=dialog.get_value(idx3) if step<0:step=0 if mode2==1: #ビトゥーン選択モード tuikalist=[] if len(activefacelist)>2: sface=activefacelist[len(activefacelist)-1-2]#開始面 tface=activefacelist[len(activefacelist)-1-1]#方向を決めるための面 eface=activefacelist[len(activefacelist)-1]#終了面 #開始面の隣に方向を決めるための面があるか? thenlist1=felist[sface] thenlist2=felist[tface] han=-1 for mmm in thenlist1: for nnn in thenlist2: if mmm==nnn:han=mmm if han!=-1: imaedge=han imaface=sface imanum=0 #tfaceとefaceは非選択に ashape.face(tface).active=False ashape.face(eface).active=False tuikalist=[] tuikalist.append(sface) while True: tempvlist=list(ashape.face(imaface).vertex_indices) if len(tempvlist)!=4:break else: tempff=copy.copy(eflist[imaedge]) tempff.remove(imaface) if len(tempff)>0: tempface=tempff[0] imanum+=1 if imanum>step: imanum=0 if tempface!=sface: tuikalist.append(tempface) if tempface==eface or tempface==sface:break else: imaface=tempface tvlist5=list(ashape.face(imaface).vertex_indices) tvlist5.remove(ashape.edge(imaedge).v0) tvlist5.remove(ashape.edge(imaedge).v1) if len(tvlist5)>1: imaedge=return_edge_number(tvlist5[0],tvlist5[1]) else:imaedge=-1 # if imaedge==-1:break else:break # print tuikalist if mode2==0: #通常モード #開始辺を決める if houkou==0: hen1=return_edge_number(startfacevlist[0],startfacevlist[1]) hen2=return_edge_number(startfacevlist[2],startfacevlist[3]) else: hen1=return_edge_number(startfacevlist[1],startfacevlist[2]) hen2=return_edge_number(startfacevlist[0],startfacevlist[3]) if muki==1: temphen=hen1 hen1=hen2 hen2=temphen #追加リストを作っていく tuikalist=[] imaedge=hen1 startedge=hen1 imamen=startface tuikalist.append(startface) loop=1 syuuryou=0 imanum=0 while(loop==1): rinsetumen=copy.copy(eflist[imaedge]) rinsetumen.remove(imamen) if len(rinsetumen)<1: loop=0 else: if rinsetumen[0]==startface: loop=0 syuuryou=1 else: imanum+=1 if imanum>step:imanum=0 if imanum==0: tuikalist.append(rinsetumen[0]) imamen=rinsetumen[0] tempvlist2=list(xshade.scene().active_shape().face(imamen).vertex_indices) if len(tempvlist2)!=4: loop=0 else: tempvlist2.remove(xshade.scene().active_shape().edge(imaedge).v0) tempvlist2.remove(xshade.scene().active_shape().edge(imaedge).v1) imaedge=return_edge_number(tempvlist2[0],tempvlist2[1]) imaedge=hen2 imamen=startface loop=1 imanum=0 if syuuryou==0: while(loop==1): rinsetumen=copy.copy(eflist[imaedge]) rinsetumen.remove(imamen) if len(rinsetumen)<1: loop=0 else: imanum+=1 if imanum>step:imanum=0 if imanum==0: tuikalist.append(rinsetumen[0]) imamen=rinsetumen[0] tempvlist2=list(xshade.scene().active_shape().face(imamen).vertex_indices) if len(tempvlist2)!=4: loop=0 else: tempvlist2.remove(xshade.scene().active_shape().edge(imaedge).v0) tempvlist2.remove(xshade.scene().active_shape().edge(imaedge).v1) imaedge=return_edge_number(tempvlist2[0],tempvlist2[1]) #面の追加(あるいは除外)を行う for i in tuikalist: if mode==0:xshade.scene().active_shape().face(i).active=True else:xshade.scene().active_shape().face(i).active=False xshade.scene().exit_modify_mode() xshade.scene().enter_modify_mode() #ダイアログで確認して確定するかどうか決定 dialog2=xshade.create_dialog() iidx1=dialog2.append_push_button('選択を確定しますか?') kekka2=dialog2.ask('ステップ選択') if kekka2==True: renzoku=0 else: #選択状態を元に戻す for i in range(xshade.scene().active_shape().number_of_faces): xshade.scene().active_shape().face(i).active=False for i in activefacelist: xshade.scene().active_shape().face(i).active=True xshade.scene().active_shape().face(i).active_order=(i+1) xshade.scene().exit_modify_mode() xshade.scene().enter_modify_mode() #面ステップ選択終了 def step_sel_edge(): dousasuru=0 if xshade.scene().is_modify_mode==True and xshade.scene().active_shape().type==7: activeedgelist=[] for i in range(xshade.scene().active_shape().number_of_edges): if xshade.scene().active_shape().edge(i).active_order>0: activeedgelist.append(i) if len(activeedgelist)>0: #選択番号順に並び替える activeedgelist=sort_edge_by_active_order(activeedgelist) startedge=activeedgelist[len(activeedgelist)-1] temprin2=return_menlist(startedge) if len(temprin2)>0:dousasuru=1 if dousasuru==1: #ここに初期値 houkou=0 muki=0 mode=0 mode2=0 step=1 renzoku=1 dfhoukou=houkou dfmuki=muki dfmode=mode dfmode2=mode2 dfstep=step dfrenzoku=renzoku while(renzoku==1): #ダイアログ開く dialog=xshade.create_dialog_with_uuid('0x51900F66') dialog.append_default_button() dialog.begin_group() idx4=dialog.append_radio_button('/通常モード/ビトウィーンモード') dialog.end_group() dialog.begin_group() idx0=dialog.append_radio_button('/選択に追加する/選択から除外する') dialog.end_group() dialog.begin_group('通常モード時') idx2=dialog.append_radio_button('向き/1/2') dialog.end_group() idx3=dialog.append_selection('間隔/0/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30') dialog.set_default_value(idx0,dfmode) dialog.set_default_value(idx2,dfmuki) dialog.set_default_value(idx3,dfstep) dialog.set_default_value(idx4,dfmode2) kekka=dialog.ask('ステップ選択') if kekka==False:renzoku=0 if kekka==True: mode=dialog.get_value(idx0) muki=dialog.get_value(idx2) step=dialog.get_value(idx3) if step<0:step=0 mode2=dialog.get_value(idx4) if mode2==1:#ビトウィーン選択モード tuikalist=[] aelist=copy.copy(activeedgelist) if len(aelist)>2: sedge=aelist[len(aelist)-1-2]#開始辺 tedge=aelist[len(aelist)-1-1]#次の辺 eedge=aelist[len(aelist)-1]#終了辺 #開始辺の隣に次の辺があるか tflist1=eflist[sedge] tflist2=eflist[tedge] han=-1 for mmm in tflist1: for nnn in tflist2: if mmm==nnn:han=mmm if han!=-1: imaedge=sedge imanum=0 imaface=han tuikalist.append(imaedge) ashape.edge(tedge).active=False ashape.edge(eedge).active=False while True: tvlist=list(ashape.face(imaface).vertex_indices) if len(tvlist)!=4:break else: tvlist.remove(ashape.edge(imaedge).v0) tvlist.remove(ashape.edge(imaedge).v1) if len(tvlist)>1: tempedge=return_edge_number(tvlist[0],tvlist[1]) else:break imanum+=1 if imanum>step: imanum=0 if tempedge!=sedge: tuikalist.append(tempedge) if tempedge==eedge or tempedge==sedge:break else: imaedge=tempedge tfacel=copy.copy(eflist[imaedge]) tfacel.remove(imaface) if len(tfacel)<1:break else: imaface=tfacel[0] if mode2==0:#通常モード #開始面を決める tempmen4=eflist[startedge] if len(tempmen4)>1: men1=tempmen4[0] men2=tempmen4[1] else: men1=tempmen4[0] men2=tempmen4[0] if muki==1: tempmen=men1 men1=men2 men2=tempmen #追加リストを作っていく tuikalist=[] imaedge=startedge imamen=men1 tuikalist.append(startedge) loop=1 syuuryou=0 imanum=0 while(loop==1): tempvlist=list(xshade.scene().active_shape().face(imamen).vertex_indices) if len(tempvlist)!=4: loop=0 else: tempvlist.remove(xshade.scene().active_shape().edge(imaedge).v0) tempvlist.remove(xshade.scene().active_shape().edge(imaedge).v1) newedge=return_edge_number(tempvlist[0],tempvlist[1]) if newedge==startedge: loop=0 syuuryou=1 else: imanum+=1 if imanum>step:imanum=0 if imanum==0: tuikalist.append(newedge) temprin6=copy.copy(eflist[newedge]) if len(temprin6)<2: loop=0 else: temprin6.remove(imamen) imamen=temprin6[0] imaedge=newedge imaedge=startedge imamen=men2 loop=1 imanum=0 if syuuryou==0: while(loop==1): tempvlist=list(xshade.scene().active_shape().face(imamen).vertex_indices) if len(tempvlist)!=4: loop=0 else: tempvlist.remove(xshade.scene().active_shape().edge(imaedge).v0) tempvlist.remove(xshade.scene().active_shape().edge(imaedge).v1) newedge=return_edge_number(tempvlist[0],tempvlist[1]) imanum+=1 if imanum>step:imanum=0 if imanum==0: tuikalist.append(newedge) temprin6=copy.copy(eflist[newedge]) if len(temprin6)<2: loop=0 else: temprin6.remove(imamen) imamen=temprin6[0] imaedge=newedge #辺の追加(あるいは除外)を行う for i in tuikalist: if mode==0:xshade.scene().active_shape().edge(i).active=True else:xshade.scene().active_shape().edge(i).active=False xshade.scene().exit_modify_mode() xshade.scene().enter_modify_mode() #ダイアログで確認して確定するかどうか決定 dialog2=xshade.create_dialog() iidx1=dialog2.append_push_button('選択を確定しますか?') kekka2=dialog2.ask('ステップ選択') if kekka2==True: renzoku=0 else: #選択状態を元に戻す for i in range(xshade.scene().active_shape().number_of_edges): xshade.scene().active_shape().edge(i).active=False for i in activeedgelist: xshade.scene().active_shape().edge(i).active=True xshade.scene().active_shape().edge(i).active_order=(i+1) xshade.scene().exit_modify_mode() xshade.scene().enter_modify_mode() #辺ステップ選択終了 xscene=xshade.scene() ashape=xshade.scene().active_shape() if xshade.scene().active_shape().type==7: ashape.adjust_face_direction() velist=[]#頂点に接続されている辺リストを頂点番号順に格納したもの for i in range(xshade.scene().active_shape().total_number_of_control_points): velist.append([]) for i in range(xshade.scene().active_shape().number_of_edges): vv0=xshade.scene().active_shape().edge(i).v0 vv1=xshade.scene().active_shape().edge(i).v1 tempvv=velist[vv0] tempvv.append(i) velist[vv0]=tempvv tempvv=velist[vv1] tempvv.append(i) velist[vv1]=tempvv eflist=[]#辺に隣接されている面リストを辺番号順に格納したもの felist=[]#面を構成する辺リストを面番号順に格納したもの #return_henlist必要 for i in range(xshade.scene().active_shape().number_of_edges): eflist.append([]) xshade.scene().active_shape().setup_winged_edge() for i in range(xshade.scene().active_shape().number_of_faces): thenlist=return_henlist(i) felist.append(thenlist) for gg in thenlist: tempf=eflist[gg] tempf.append(i) eflist[gg]=tempf xshade.scene().active_shape().clean_winged_edge() #内包面が存在しないかどうか naiari=0 for i in range(ashape.number_of_faces): hani=0 templ=felist[i] for gg in templ: if len(eflist[gg])>2:hani+=1 if hani==len(templ):naiari=1 if naiari==0: if xshade.scene().selection_mode==0:step_sel_face() if xshade.scene().selection_mode==1:step_sel_edge() if naiari==1: dialog=xshade.create_dialog() dialog.append_push_button('内包面が存在するため') dialog.append_push_button('スクリプトが実行できません') dialog.ask('ステップ選択')