import copy #面張りと削除 #上位パートに変換がかかっていると使用できないように変更(2010.03.03) #アルゴリズム変更(2010.03.06) #shade標準の「face(面張り)」ツール同様、複数の頂点を選択状態で実行すると #そこに面を張ります #おまけとして、すでに面を張ってる場合はその面を削除します(ただし三角形面は削除できない) #shade標準の「face」ツールは実行するとポリラインが全て削除されてしまうという仕様に #なっているのですが、こっちはポリラインはそのまま残して面が張れます #「穴をふさぐ」スクリプトではうまく面が張れない箇所にご使用ください #動作条件 #選択形状がポリゴンメッシュ #編集モードに入っている #頂点編集モード #頂点が三つ以上選択されている #選択頂点は面を構成できるようにおのおのエッジがつながっている事 def return_edge_number(point1,point2): #頂点二つの頂点番号を与えると、その頂点で構成される辺の辺番号を返す #エラー(辺の両端のポイントでは無い)の場合は-1を返す #velist(頂点の接続辺リストを頂点番号順に格納したもの)が必要 thenlist12=velist[point1] for i in thenlist12: if xshade.scene().active_shape().edge(i).v0==point1 and xshade.scene().active_shape().edge(i).v1==point2: return i if xshade.scene().active_shape().edge(i).v1==point1 and xshade.scene().active_shape().edge(i).v0==point2: return i return -1 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 dousasuru=0 xscene=xshade.scene() ashape=xshade.scene().active_shape() #処理をキャンセルした場合はashapeの更新を忘れずに if ashape.type==7: if xscene.is_modify_mode==True: if xscene.selection_mode==1 or xscene.selection_mode==0: xscene.selection_mode=2 if xscene.selection_mode==2: aplist=[]# 選択頂点リスト for i in range(ashape.total_number_of_control_points): if ashape.vertex(i).active==True: aplist.append(i) if len(aplist)>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: menhari=1#1の時は面を張る vvlist=[]#頂点に接続されている頂点リストを頂点番号順に格納したもの velist=[]#頂点に接続されている辺リストを頂点番号順に格納したもの for i in range(xshade.scene().active_shape().total_number_of_control_points): vvlist.append([]) 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=vvlist[vv0] tempvv.append(vv1) vvlist[vv0]=tempvv tempvv=vvlist[vv1] tempvv.append(vv0) vvlist[vv1]=tempvv tempve=velist[vv1] tempve.append(i) velist[vv1]=tempve tempve=velist[vv0] tempve.append(i) velist[vv0]=tempve 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() aplistc=copy.copy(aplist) vplist=[] imap=aplistc[0] vplist.append(imap) aplistc.remove(imap) while(len(aplistc)>0): tempvlist=vvlist[imap] error=1 for i in tempvlist: for gg in aplistc: if i==gg: imap=gg vplist.append(imap) aplistc.remove(imap) error=0 break if error==0:break if error==1:break okk=0 if len(aplistc)==0: tempvlist=vvlist[vplist[0]] for i in tempvlist: if i==vplist[len(vplist)-1]:okk=1 if okk==1: #同じ辺で構成される面がすでに存在してないか? henlist=[] for i in range(len(vplist)): if i!=(len(vplist)-1): henlist.append(return_edge_number(vplist[i],vplist[i+1])) else: henlist.append(return_edge_number(vplist[i],vplist[0])) henlist.sort() for i in range(len(felist)): tlist=felist[i] tlist.sort() if henlist==tlist: menhari=0 facenum=i if okk==1: #元の形状をクリップボードにコピー ashape.copy() #面を張る場合 if menhari==1: ashape.append_face(vplist) #面を消す場合 if menhari==0: ashape.remove_face(facenum) # kesuedge=ashape.number_of_edges # if len(vplist)>3: # half=len(vplist)/2 # ashape.append_edge(vplist[0],vplist[half]) # ashape.edge(kesuedge).remove() for i in aplist: ashape.vertex(i).active=True ashape.adjust_face_direction #元に戻すか聞く? dialog=xshade.create_dialog() idx3=dialog.append_push_button('処理を確定しますか?') xshade.scene().enter_modify_mode() kekka=dialog.ask('面張り') #キャンセルなら形状を削除してクリップボードの形状を元に戻す #さらに頂点や辺の選択状態も元に戻す? 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()