import copy #指定位置で分割 #上位パートに変換がかかっていると使用できないように変更(2010.03.03) #shade1202に対応 #ポリゴンメッシュの辺編集モードで辺を一つだけ選択し、 #辺でない場所をクリックして実行すると #交差方向を指定位置で分割してくれます #動作条件 #選択形状がポリゴンメッシュ #編集モードに入っている #辺編集モード #選択辺の数が一つのみ #隣接面を一つ以上持ち、かつ隣接面の頂点数が4個のが一つはあること #ローカル座標モードや、ろくろ機能で回転させてる場合、上位パートに変換がかかっている場合は結果が不正になります 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 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_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 break if xshade.scene().active_shape().edge(i).v1==pointnum1 and xshade.scene().active_shape().edge(i).v0==pointnum2: returnnum=i break return returnnum def return_henkan_pos(pos,mat): #posをmatで変換した座標(タプル)を返す tempx=pos[0] tempy=pos[1] tempz=pos[2] x1=mat[0][0]*tempx+mat[1][0]*tempy+mat[2][0]*tempz+mat[3][0]*1 y1=mat[0][1]*tempx+mat[1][1]*tempy+mat[2][1]*tempz+mat[3][1]*1 z1=mat[0][2]*tempx+mat[1][2]*tempy+mat[2][2]*tempz+mat[3][2]*1 return [x1,y1,z1] dousasuru=0 if xshade.scene().is_modify_mode==True and xshade.scene().active_shape().type==7 and xshade.scene().selection_mode ==1: 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) vvlist=[]#頂点に接続されている頂点リストを頂点番号順に格納したもの for i in range(xshade.scene().active_shape().total_number_of_control_points): vvlist.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=vvlist[vv0] tempvv.append(vv1) vvlist[vv0]=tempvv tempvv=vvlist[vv1] tempvv.append(vv0) vvlist[vv1]=tempvv eflist=[]#辺に隣接されている面リストを辺番号順に格納したもの #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) for gg in thenlist: tempf=eflist[gg] tempf.append(i) eflist[gg]=tempf xshade.scene().active_shape().clean_winged_edge() if len(activeedgelist)==1: startedge=activeedgelist[0] menlist=eflist[startedge] if len(menlist)>0: for i in menlist: if len(xshade.scene().active_shape().face(i).vertex_indices)==4: 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: close=2#1がループしてる0はしてない 2はまだどっちかわかってない #選択辺一つからパラレル選択処理を行う startedge=activeedgelist[0] menlist=eflist[startedge] if len(menlist)==1: #開始辺の隣接面が一つの場合のリング辺リスト作成 alist=[] imamen=menlist[0] close=0 alist.append(startedge) vertexlist=list(xshade.scene().active_shape().face(menlist[0]).vertex_indices) vertexlist.remove(xshade.scene().active_shape().edge(startedge).v0) vertexlist.remove(xshade.scene().active_shape().edge(startedge).v1) imaedge=return_edge_number(vertexlist[0],vertexlist[1]) alist.append(imaedge) loop=1 while(loop==1): rinsetumenlist=eflist[imaedge] rinsetumenlist.remove(imamen) if len(rinsetumenlist)==0: loop=0 break else: tempvlist=list(xshade.scene().active_shape().face(rinsetumenlist[0]).vertex_indices) if len(tempvlist)!=4: loop=0 break else: imamen=rinsetumenlist[0] tempvlist.remove(xshade.scene().active_shape().edge(imaedge).v0) tempvlist.remove(xshade.scene().active_shape().edge(imaedge).v1) tempedge=return_edge_number(tempvlist[0],tempvlist[1]) alist.append(tempedge) imaedge=tempedge if len(menlist)==2: #開始辺の隣接面が二つの場合のリング辺リスト作成(片方が終わった際に反転する) alist=[] alist.append(startedge) imamen=menlist[0] vertexlist=list(xshade.scene().active_shape().face(menlist[0]).vertex_indices) vertexlist.remove(xshade.scene().active_shape().edge(startedge).v0) vertexlist.remove(xshade.scene().active_shape().edge(startedge).v1) if len(vertexlist)==2: imaedge=return_edge_number(vertexlist[0],vertexlist[1]) alist.append(imaedge) loop=1 else: loop=0 while(loop==1): rinsetumenlist=eflist[imaedge] rinsetumenlist.remove(imamen) if len(rinsetumenlist)==0: loop=0 break else: tempvlist=list(xshade.scene().active_shape().face(rinsetumenlist[0]).vertex_indices) if len(tempvlist)!=4: loop=0 break else: imamen=rinsetumenlist[0] tempvlist.remove(xshade.scene().active_shape().edge(imaedge).v0) tempvlist.remove(xshade.scene().active_shape().edge(imaedge).v1) tempedge=return_edge_number(tempvlist[0],tempvlist[1]) #すでに格納してないかチェック hantei=0 for i in alist: if i==tempedge:hantei=1 if hantei==1: loop=0 break else: alist.append(tempedge) imaedge=tempedge #片方の探索が終わったので逆転しておく if alist!=[]: acopylist=copy.copy(alist) for i in range(len(alist)): alist[i]=acopylist[len(alist)-i-1] #もう片方の探索 imamen=menlist[1] vertexlist=list(xshade.scene().active_shape().face(menlist[1]).vertex_indices) vertexlist.remove(xshade.scene().active_shape().edge(startedge).v0) vertexlist.remove(xshade.scene().active_shape().edge(startedge).v1) if len(vertexlist)==2: tempedge=return_edge_number(vertexlist[0],vertexlist[1]) #すでに格納してないかチェック hantei=0 for i in alist: if i==tempedge:hantei=1 if hantei==1: loop=0 close=1 else: imaedge=tempedge alist.append(imaedge) loop=1 close=0 else: loop=0 close=0 while(loop==1): rinsetumenlist=eflist[imaedge] rinsetumenlist.remove(imamen) if len(rinsetumenlist)==0: loop=0 break else: tempvlist=list(xshade.scene().active_shape().face(rinsetumenlist[0]).vertex_indices) if len(tempvlist)!=4: loop=0 break else: imamen=rinsetumenlist[0] tempvlist.remove(xshade.scene().active_shape().edge(imaedge).v0) tempvlist.remove(xshade.scene().active_shape().edge(imaedge).v1) tempedge=return_edge_number(tempvlist[0],tempvlist[1]) alist.append(tempedge) imaedge=tempedge honsuu=len(alist) #選択辺の状態を変更してからダイアログ表示して分割数を聞く #キャンセルの場合は選択辺の選択状態を元に戻す for i in alist: xshade.scene().active_shape().edge(i).active=True xshade.scene().exit_modify_mode() xshade.scene().enter_modify_mode() #ここでデフォルトの数値 renzoku=1 bunkatu=2 zahyou=0#参照座標 0がx、1がy、2がz #最初の辺だけ非選択状態に xshade.scene().active_shape().edge(startedge).active=False while(renzoku==1): #ダイアログ表示 dialog=xshade.create_dialog() idx1=dialog.append_radio_button('参照座標/X座標/Y座標/Z座標') dialog.set_value(idx1,zahyou) xshade.idle(10) kekka=dialog.ask('指定位置で分割') if kekka==False: renzoku=0 #選択状態を元に戻す for i in alist: xshade.scene().active_shape().edge(i).active=False xshade.scene().active_shape().edge(startedge).active=True xshade.scene().exit_modify_mode() xshade.scene().enter_modify_mode() if kekka==True: xshade.scene().inhibit_update() #カーソル位置 cursorpos=xshade.scene().cursor_position # tempcursorpos=xshade.scene().cursor_position # mat4=xshade.scene().active_shape().world_to_local_matrix # mat4=xshade.scene().active_shape().local_to_world_matrix # cursorpos=return_henkan_pos(tempcursorpos,mat4) #クリップボードに形状をコピー xshade.scene().copy() xshade.scene().enter_modify_mode() zahyou=dialog.get_value(idx1) max=xshade.scene().active_shape().total_number_of_control_points max2=max #エッジのパラレルリストから交差方向の頂点リストを二つ作成 l1list=[] l2list=[] kaisi=0 for i in alist: kaisi+=1 if kaisi==1: l1list.append(xshade.scene().active_shape().edge(i).v0) l2list.append(xshade.scene().active_shape().edge(i).v1) else: nagasa=len(l1list) if return_edge_number(l1list[nagasa-1],xshade.scene().active_shape().edge(i).v0)==-1: l1list.append(xshade.scene().active_shape().edge(i).v1) l2list.append(xshade.scene().active_shape().edge(i).v0) else: l1list.append(xshade.scene().active_shape().edge(i).v0) l2list.append(xshade.scene().active_shape().edge(i).v1) #頂点座標リストを作成 l1vlist=[] l2vlist=[] for i in l1list: l1vlist.append(xshade.scene().active_shape().vertex(i).position) for i in l2list: l2vlist.append(xshade.scene().active_shape().vertex(i).position) yokobunkatu=len(l1list)-1 #格子状の頂点リストを作成 tuikaposlist=[] tuikalist=[] for i in range(yokobunkatu+1): tempcpos=[] tempc=[] for j in range(bunkatu+1): tempcpos.append((0,0,0)) tempc.append(0) tuikaposlist.append(tempcpos) tuikalist.append(tempc) #nn(切込み位置)を求める for gg in range(len(l1list)): if l1list[gg]==xshade.scene().active_shape().edge(startedge).v0: templ1vlist=l1vlist[gg] templ2vlist=l2vlist[gg] if l1list[gg]==xshade.scene().active_shape().edge(startedge).v1: templ1vlist=l2vlist[gg] templ2vlist=l1vlist[gg] if zahyou==0: tempbunbo=templ2vlist[0]-templ1vlist[0] if tempbunbo==0:tempbunbo=1 nn=(cursorpos[0]-templ1vlist[0])/tempbunbo if zahyou==1: tempbunbo=templ2vlist[1]-templ1vlist[1] if tempbunbo==0:tempbunbo=1 nn=(cursorpos[1]-templ1vlist[1])/tempbunbo if zahyou==2: tempbunbo=templ2vlist[2]-templ1vlist[2] if tempbunbo==0:tempbunbo=1 nn=(cursorpos[2]-templ1vlist[2])/tempbunbo for i in range(yokobunkatu+1): for j in range(bunkatu+1): if j==0: tuikaposlist[i][j]=l1vlist[i] tuikalist[i][j]=l1list[i] if j==bunkatu: tuikaposlist[i][j]=l2vlist[i] tuikalist[i][j]=l2list[i] # if j!=0 and j!=bunkatu: # temp=(l2vlist[i][0]-l1vlist[i][0],l2vlist[i][1]-l1vlist[i][1],l2vlist[i][2]-l1vlist[i][2]) # temppos=(l1vlist[i][0]+temp[0]*j/bunkatu,l1vlist[i][1]+temp[1]*j/bunkatu,l1vlist[i][2]+temp[2]*j/bunkatu) # tuikaposlist[i][j]=temppos # tuikalist[i][j]=max2 # max2+=1 if j!=0 and j!=bunkatu: temp=(l2vlist[i][0]-l1vlist[i][0],l2vlist[i][1]-l1vlist[i][1],l2vlist[i][2]-l1vlist[i][2]) temppos=(l1vlist[i][0]+temp[0]*nn,l1vlist[i][1]+temp[1]*nn,l1vlist[i][2]+temp[2]*nn) tuikaposlist[i][j]=temppos tuikalist[i][j]=max2 max2+=1 #元の辺を削除し、頂点をつけたす xshade.scene().active_shape().begin_removing_edges() for i in alist: xshade.scene().active_shape().edge(i).remove() xshade.scene().active_shape().end_removing_edges() for i in range(yokobunkatu+1): for j in range(bunkatu+1): if j!=0 and j!=bunkatu: xshade.scene().active_shape().append_point(tuikaposlist[i][j]) #頂点を結ぶ(横方向) for j in range(bunkatu+1): if j!=0 and j!=bunkatu: if close==1: xshade.scene().active_shape().append_edge(tuikalist[0][j],tuikalist[yokobunkatu][j]) for g in range(yokobunkatu+1): if g!=yokobunkatu: xshade.scene().active_shape().append_edge(tuikalist[g][j],tuikalist[g+1][j]) #頂点を結ぶ(縦方向) # print tuikalist for i in range(yokobunkatu+1): for j in range(bunkatu+1): if j!=bunkatu: xshade.scene().active_shape().append_edge(tuikalist[i][j],tuikalist[i][j+1]) #面の向き統一 xshade.scene().active_shape().adjust_face_direction() # xshade.scene().active_shape().cleanup_redundant_vertices() #やり直すか聞く xshade.scene().allow_update() kekka1=True imasele=xshade.scene().selection_mode #ダイアログを表示して、結果を確認してもらう #okで確定(何もせず)cancelだと元に戻す dialog=xshade.create_dialog() idx33=dialog.append_push_button('処理を確定する場合はokを') idx44=dialog.append_push_button('取り消す場合はcancelを押してください') xshade.idle(10) kekka1=dialog.ask('指定位置で分割') if kekka1==True:renzoku=0 #内包面の検出と処理 if kekka1==True: if honsuu==4 or honsuu==3: nailist=[] eflist=[]#辺に隣接されている面リストを辺番号順に格納したもの #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) for gg in thenlist: tempf=eflist[gg] tempf.append(i) eflist[gg]=tempf for i in range(xshade.scene().active_shape().number_of_faces): thenlist2=return_henlist(i) kazu=len(thenlist2) hantei=0 for ggg in thenlist2: if len(eflist[ggg])>2:hantei+=1 if hantei==kazu: nailist.append(i) xshade.scene().active_shape().clean_winged_edge() if len(nailist)>0: sagyou=0 #ダイアログの表示 dialog5=xshade.create_dialog() dialog5.append_push_button('内包面が生成されました') dialog5.append_push_button('処理を選択してください') idxxx1=dialog5.append_radio_button('/選択状態にする/削除する/何もしない') dialog5.set_value(idxxx1,sagyou) xshade.idle(10) kekka33=dialog5.ask('アラート') if kekka33==True: sagyou=dialog5.get_value(idxxx1) if sagyou==0: xshade.scene().selection_mode=0 for i in range(xshade.scene().active_shape().number_of_faces): xshade.scene().active_shape().face(i).active=False for i in nailist: xshade.scene().active_shape().face(i).active=True if sagyou==1: xshade.scene().active_shape().begin_removing_faces() for i in nailist: xshade.scene().active_shape().face(i).remove() xshade.scene().active_shape().end_removing_faces() xshade.scene().active_shape().adjust_face_direction() xshade.scene().selection_mode=1 # if kekka33==False: # kakka1=False # renzoku=1 #キャンセルなら形状を削除してクリップボードの形状を元に戻す #さらに頂点や辺の選択状態も元に戻す? if kekka1==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().active_shape().edge(startedge).active=True xshade.idle(10)