import copy #指定数で分割 #ポリゴンメッシュの辺編集モードで辺を一つだけ選択状態で実行すると #交差方向を指定数に従って分割してくれます #動作条件 #選択形状がポリゴンメッシュ #編集モードに入っている #辺編集モード #選択辺の数が一つのみ #隣接面を一つ以上持ち、かつ隣接面の頂点数が4個のが一つはあること #上位パートに変換マトリクスがかかっていると結果が不正になる場合があります 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 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) if len(activeedgelist)==1: startedge=activeedgelist[0] menlist=return_menlist(startedge) if len(menlist)>0: for i in menlist: if len(xshade.scene().active_shape().face(i).vertex_indices)==4: dousasuru=1 if dousasuru==1: close=2#1がループしてる0はしてない 2はまだどっちかわかってない #選択辺一つからパラレル選択処理を行う startedge=activeedgelist[0] menlist=return_menlist(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=return_menlist(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=return_menlist(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=return_menlist(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 #選択辺の状態を変更してからダイアログ表示して分割数を聞く #キャンセルの場合は選択辺の選択状態を元に戻す 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 while(renzoku==1): #ダイアログ表示 dialog=xshade.create_dialog() idx1=dialog.append_int('分割数(2以上の整数)') dialog.set_value(idx1,bunkatu) 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().copy() xshade.scene().enter_modify_mode() bunkatu=dialog.get_value(idx1) if bunkatu<2:bunkatu=2 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) 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 #元の辺を削除し、頂点をつけたす 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() #やり直すか聞く 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を押してください') kekka1=dialog.ask('指定数で分割') if kekka1==True:renzoku=0 #キャンセルなら形状を削除してクリップボードの形状を元に戻す #さらに頂点や辺の選択状態も元に戻す? 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