import copy import math #リング単位で拡大縮小 #ポリゴンメッシュで選択している辺をリング単位(*)で拡大縮小します。 #リング・・・選択辺がループ状につながっている状態 #リングの数が複数ある場合は、各々のリングの中心を拡大縮小の中心としてスケーリング処理を行います。 #動作条件 #選択形状がポリゴンメッシュ #編集モードに入っている #辺選択モード #辺が三つ以上選択されている #上位パートに変換がかかっていると動作しません。 #パラメータ #拡大縮小率 0より大 def erase_same_num(list1): #リスト内に同じ値が重複する場合は一つに減らす関数 例[1,1,1,3,3,4]→[1,3,4] #呼び出す時はlist=erase_same_num(list)ではなく、erase_same_num(list)で良い 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 substract_b_from_a(lista,listb): #リストAからリストBに存在する要素を抜いたリストを返す a[1,2,3,4,4,5] b[3,4] 結果[1,2,5] #リストBに重複する値が存在するとエラーが出るので、あらかじめ重複する値は消しておく listacopy=[] for i in range(len(lista)): listacopy.append(lista[i]) listbcopy=[] for i in range(len(listb)): listbcopy.append(listb[i]) kesulis=[] for i in listbcopy: for j in listacopy: if j==i: kesulis.append(i) for i in kesulis: listacopy.remove(i) return listacopy 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] def return_kaiten(pos,cpos,kakudo2,ziku): #posをcposを中心にziku(0x軸、1y軸、2z軸)まわりにkakudoだけ回転させて返す kakudo=(2*math.pi*kakudo2)/360 tempos5=[pos[0]-cpos[0],pos[1]-cpos[1],pos[2]-cpos[2]] newpos=[tempos5[0],tempos5[1],tempos5[2]] if ziku==0: newpos[1]=tempos5[1]*math.cos(kakudo)-tempos5[2]*math.sin(kakudo) newpos[2]=tempos5[1]*math.sin(kakudo)+tempos5[2]*math.cos(kakudo) if ziku==1: newpos[2]=tempos5[2]*math.cos(kakudo)-tempos5[0]*math.sin(kakudo) newpos[0]=tempos5[2]*math.sin(kakudo)+tempos5[0]*math.cos(kakudo) if ziku==2: newpos[0]=tempos5[0]*math.cos(kakudo)-tempos5[1]*math.sin(kakudo) newpos[1]=tempos5[0]*math.sin(kakudo)+tempos5[1]*math.cos(kakudo) newpos=[newpos[0]+cpos[0],newpos[1]+cpos[1],newpos[2]+cpos[2]] return newpos dousasuru=0 xscene=xshade.scene() ashape=xshade.scene().active_shape() if ashape.type==7 and xscene.is_modify_mode==True: if xscene.selection_mode==1: aelist=[]#選択辺リスト for i in range(ashape.number_of_edges): if ashape.edge(i).active==True: aelist.append(i) if len(aelist)>2: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: #ここに初期値 renzoku=1 scale=0.5 dfscale=scale while(renzoku==1): #ダイアログ表示 dialog=xshade.create_dialog_with_uuid('0x51900013') dialog.append_default_button() idx1=dialog.append_double('拡大縮小率(0より大)') dialog.set_default_value(idx1,dfscale) # dialog.set_value(idx1,ctype) # dialog.set_value(idx2,spos) # dialog.set_value(idx3,ziku) # dialog.set_value(idx4,muki) # dialog.set_value(idx5,vtype) # dialog.set_value(idx6,rval) # dialog.set_value(idx7,kaiten) # dialog.set_value(idx8,nezip) # dialog.set_value(idx9,issyo) kekka=dialog.ask('リング単位で拡大縮小') if kekka==False:renzoku=0 else: scale=dialog.get_value(idx1) if scale<0:scale=0.1 #元の形状をクリップボードにコピー ashape.copy() xscene.enter_modify_mode() #選択辺をリング単位にまとめたリストを作成 loop1=1 alllist=[] aelistcopy=copy.copy(aelist) err=0 while(loop1==1): if len(aelistcopy)==0:break stedge=aelistcopy[0] imaedge=stedge # maeedge=stedge kesulist=[] kesulist.append(stedge) ch1=0 pnum=0 while(1): if ch1==2:break imav0=ashape.edge(imaedge).v0 imav1=ashape.edge(imaedge).v1 ch1=0 for gg in aelistcopy: tv0=ashape.edge(gg).v0 tv1=ashape.edge(gg).v1 if imav0==tv0 or imav0==tv1 or imav1==tv0 or imav1==tv1: hantei=0 for cc in kesulist: if cc==gg: hantei=1 break if hantei==0: kesulist.append(gg) imaedge=gg pnum+=1 ch1=1 break if gg==stedge and imaedge!=stedge and pnum>1: ch1=2 alllist.append(kesulist) aelistcopy=substract_b_from_a(aelistcopy,kesulist) break if ch1==0: # print alllist dialoger=xshade.create_dialog() dialoger.append_push_button('辺はリング状に選択') dialoger.append_push_button('してください') kekkaa=dialoger.ask('エラー') err=1 loop1=0 break if err==1: renzoku=0 break #リング単位で拡大縮小 for i in alllist: #各リングの中心を求める sum=[0,0,0] num=0 vlist=[] for gg in i: # num+=1 sv0=ashape.edge(gg).v0 sv1=ashape.edge(gg).v1 vlist.append(sv0) vlist.append(sv1) # sv0p=ashape.vertex(sv0).position # sv1p=ashape.vertex(sv1).position # sum=[sum[0]+(sv0p[0]+sv1p[0])/2,sum[1]+(sv0p[1]+sv1p[1])/2,sum[2]+(sv0p[2]+sv1p[2])/2] # cpos=[sum[0]/num,sum[1]/num,sum[2]/num] erase_same_num(vlist) for gg in vlist: tp3=ashape.vertex(gg).position num+=1 sum=[sum[0]+tp3[0],sum[1]+tp3[1],sum[2]+tp3[2]] cpos=[sum[0]/num,sum[1]/num,sum[2]/num] #中心方向へスケーリング for gg in vlist: tpos=ashape.vertex(gg).position vec1=[tpos[0]-cpos[0],tpos[1]-cpos[1],tpos[2]-cpos[2]] newpos=[cpos[0]+vec1[0]*scale,cpos[1]+vec1[1]*scale,cpos[2]+vec1[2]*scale] ashape.vertex(gg).position=newpos #元に戻すか聞く dialog=xshade.create_dialog() idx3=dialog.append_push_button('処理を確定しますか?') xshade.scene().enter_modify_mode() kekka=dialog.ask('リング単位で拡大縮小') if kekka==True:renzoku=0 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() ashape=xshade.scene().active_shape() for i in aelist: ashape.edge(i).active=True