import copy #コーナーポイントの丸めとベベル #ポリゴン(あるいはポリライン)の角となる頂点を一つだけ選択して実行すると #分割数と幅を指定して丸めやベベルが行えます。 #上位パートに変換がかかっていると使用できないように変更(2010.03.03) #shade12用にプログラム変更(2010.12.28) #動作条件 #選択形状がポリゴンメッシュ #編集モードに入っている #頂点編集モード #頂点を一つだけ選択している #選択頂点に接続されている辺の数が3以下 #選択頂点に接続されている辺のうち、隣接面が1以下の辺が2個のみ 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 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().active_shape().type==7 and xshade.scene().is_modify_mode==True: if 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) if len(activepointlist)==1: cpoint=activepointlist[0] setuzokutenlist=return_pointlist(cpoint) if len(setuzokutenlist)<=3: hantei=0 for i in setuzokutenlist: if len(return_menlist(return_edge_number(cpoint,i)))<2:hantei+=1 if hantei==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: #角のタイプを調べる #1はポリラインコーナー、2は三辺と接続し、二面と接している角、3は2辺と接続し、一面と接している角 type=2 if len(setuzokutenlist)!=3: hantei2=0 for i in setuzokutenlist: if len(return_menlist(return_edge_number(cpoint,i)))==0:hantei2+=1 if hantei2==2: type=1 else: type=3 #角の点を真ん中として、角に該当する点を順番に並べる #type2の時だけ余計な接続点をのぞく setuzokutenlist2=copy.copy(setuzokutenlist) if type==2: kesulist=[] for i in setuzokutenlist2: if len(return_menlist(return_edge_number(cpoint,i)))==2: kesulist.append(i) if len(kesulist)>0: for i in kesulist: setuzokutenlist2.remove(i) #順番に格納 cpointlist=[] cpointlist.append(setuzokutenlist2[0]) cpointlist.append(cpoint) cpointlist.append(setuzokutenlist2[1]) # print cpointlist #typeが2の時、隣接面の頂点数がどっちも4であるかどうか(4でないときは作動しない) if type==2: rinsetumenlist=[] setuzokutenlist4=copy.copy(setuzokutenlist) setuzokutenlist4.remove(setuzokutenlist2[0]) setuzokutenlist4.remove(setuzokutenlist2[1]) rinsetumenlist=return_menlist(return_edge_number(cpoint,setuzokutenlist4[0])) for gg in rinsetumenlist: if len(xshade.scene().active_shape().face(gg).vertex_indices)>4:dousasuru=0 #typeが3の時は順番を調整 if type==3: menlist4=return_menlist(return_edge_number(cpoint,cpointlist[0])) vlist=xshade.scene().active_shape().face(menlist4[0]).vertex_indices vlist55=copy.copy(vlist) vlist55=vlist55+vlist55 vlist55a=[] kaisi=0 for i in vlist55: if i==cpoint:kaisi=1-kaisi if kaisi==1: vlist55a.append(i) cpointlist[2]=vlist55a[1] cpointlist[0]=vlist55a[len(vlist55a)-1] tempvlist=copy.copy(vlist) tempvlist+=tempvlist motovlist=[] flag33=0 for i in range(len(tempvlist)): if tempvlist[i]==cpoint: flag33=1-flag33 else: if flag33==1:motovlist.append(tempvlist[i]) if dousasuru==1: #ここに初期値 renzoku=1 bunkatu=5 haba=200 musubu=1 tempbunkatu=bunkatu temphaba=haba tempmusubu=musubu while(renzoku==1): #ダイアログ開いて分割数と幅を聞く(ダイアログにはuuidをつける) dialog=xshade.create_dialog_with_uuid('0x51900F26') dialog.append_default_button() idx15=dialog.append_int('分割数(1以上)') idx25=dialog.append_float('幅(0より大)') if type==2: idx35=dialog.append_bool('結ぶ') dialog.set_default_value(idx35,tempmusubu) dialog.set_value(idx35,musubu) dialog.set_default_value(idx15,tempbunkatu) dialog.set_default_value(idx25,temphaba) kekka=dialog.ask('コーナーポイントの丸めとベベル') if kekka==False:renzoku=0 if kekka==True: xshade.scene().inhibit_update() if type==2: musubu=dialog.get_value(idx35) bunkatu=dialog.get_value(idx15) if bunkatu<1:bunkatu=1 haba=dialog.get_value(idx25) if haba<=0:haba=0.0001 #元の形状をクリップボードにコピー xshade.scene().copy() xshade.scene().enter_modify_mode() #座標リスト cposlist=[] for i in cpointlist: cposlist.append(xshade.scene().active_shape().vertex(i).position) #3点からなる開いた線形状を作る xshade.scene().begin_creating() xshade.scene().create_surface_part() xshade.scene().end_creating() xshade.scene().begin_creating() xshade.scene().begin_line(None,0) for i in cposlist: xshade.scene().append_point(i) xshade.scene().end_line() xshade.scene().begin_line(None,0) for i in cposlist: tempp=[i[0]+100,i[1]+100,i[2]+100] xshade.scene().append_point(tempp) xshade.scene().end_line() xshade.scene().end_creating() #角を丸める # xshade.scene().enter_modify_mode() # xshade.scene().active_shape().is_control_point_selected(1)=True # xshade.scene().round_edge(haba) xshade.scene().select_parent() xshade.scene().switch() xshade.scene().select_child(1) xshade.scene().select_brother(1) xshade.scene().exit_modify_mode() xshade.scene().round_edge(haba) xshade.scene().select_brother(1) xshade.scene().select_brother(1) xshade.scene().clear() xshade.scene().select_sister(1) xshade.scene().select_sister(1) xshade.scene().clear() xshade.scene().select_parent(1) xshade.scene().active_shape().convert_to_polygon_mesh_with_divisions(bunkatu,1) xshade.scene().enter_modify_mode() xshade.scene().active_shape().vertex(0)==True #必要な頂点情報だけ貰う tuikapointlist=[] flag=0 for i in range(xshade.scene().active_shape().total_number_of_control_points): if flag==0: tuikapointlist.append(i) flag=1-flag # print tuikapointlist #追加座標リストを作成 tposlist=[] for i in range(len(tuikapointlist)): tpos2=xshade.scene().active_shape().vertex(tuikapointlist[i]).position tposlist.append([tpos2[0],tpos2[1],tpos2[2]]) #エッジリスト作成 tedgelist=[] for i in range(len(tuikapointlist)-1): tedgelist.append([i,i+1]) #削除して元のポリゴンメッシュに足す tasu2=len(tuikapointlist) xshade.scene().clear() # xshade.scene().select_sister() tasu=xshade.scene().active_shape().total_number_of_control_points for i in range(len(tuikapointlist)): xshade.scene().active_shape().append_point(tposlist[i]) for i in range(len(tedgelist)): ten=tedgelist[i] xshade.scene().active_shape().append_edge(ten[0]+tasu,ten[1]+tasu) #角の最初の点とつけたした最初の点、角の最後の点とつけたした最後の点を結ぶ xshade.scene().active_shape().append_edge(cpointlist[0],tasu) xshade.scene().active_shape().append_edge(cpointlist[2],(tasu+tasu2-1)) #typeが3の時は穴を閉じる if type==3: motovlist2=copy.copy(motovlist) for i in range(len(tuikapointlist)): motovlist2.append(i+tasu) xshade.scene().active_shape().append_face(motovlist2) # print motovlist2 #元の頂点を削除 xshade.scene().active_shape().vertex(cpoint).remove() #typeが2でmusubuが1の時は結ぶ if type==2 and musubu==1: setuzokutenlist3=copy.copy(setuzokutenlist) setuzokutenlist3.remove(setuzokutenlist2[0]) setuzokutenlist3.remove(setuzokutenlist2[1]) for i in range(len(tuikapointlist)): temp44=setuzokutenlist3[0] if temp44>=cpoint:temp44-=1 xshade.scene().active_shape().append_edge(temp44,i+tasu-1) if type==2 or type==3: #面の向きをそろえる xshade.scene().active_shape().adjust_face_direction() #デバッグ用 # print 'hanten',hanten # print 'vlist',vlist # print 'motovlist2',motovlist2 # print 'cpointlist[0]',cpointlist[0] #やり直す?  xshade.scene().allow_update() dialog=xshade.create_dialog() idx3=dialog.append_push_button('結果を確定する場合はokを') idx4=dialog.append_push_button('取り消す場合はcancelを押してください') kekka2=dialog.ask('角の丸めとベベル') #キャンセルなら形状を削除してクリップボードの形状を元に戻す #さらに頂点の選択状態も元に戻す? if kekka2==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().vertex(cpoint).active=True if kekka2==True: renzoku=0 #戻す終わり