#近くの頂点へウェルド #ポリゴンメッシュを選択状態で、編集モードに入っており、かつ頂点編集モードに入っている時のみ作動 #かつ頂点を一つだけ選択してる状態でのみ機能 #選択している頂点の近くにある頂点(自分はのぞく)へウェルドされる #実際の処理は #選択している頂点(点A)の最寄の点を探す(点B) #点Aを削除 #点Aとエッジを張っていた点群と、点Bの間にエッジを張る #面の向きを統一する #注意点 #上位のパートに変換マトリクスがかかっていると、作成される頂点の位置がおかしくなるかもしれません。 #元のポリゴンメッシュを構成する面の数が少ないと、面の向きが逆転するかもしれません(その場合は全ての面を選択してflipを行ってください) #三次元座標で距離を測定するため、三面図で近くにあるように見えても、実際は遠くにあると認識して意図しない場所へウェルドされる場合があります #意図しない結果になった場合は、元の形状がクリップボードにコピーされてますので、ctrl+vでペーストしてアンドゥしてください 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 if xshade.scene().active_shape().type==7 and xshade.scene().is_modify_mode==True and xshade.scene().selection_mode==2: if xshade.scene().active_shape().number_of_active_control_points==1 and xshade.scene().active_shape().total_number_of_control_points>2: #ポリゴンメッシュで一つの頂点を選択してる場合 #元の形状をクリップボードにコピー xshade.scene().active_shape().copy() xshade.scene().enter_modify_mode() pointnum=0 for i in range(xshade.scene().active_shape().total_number_of_control_points): if xshade.scene().active_shape().vertex(i).active_order>0: pointnum=i setuzokutenlist=return_pointlist(pointnum) tempnum=0 if pointnum==0:tempnum=1 for i in range(xshade.scene().active_shape().total_number_of_control_points): if i!=pointnum: iposition=xshade.scene().active_shape().vertex(i).position tposition=xshade.scene().active_shape().vertex(tempnum).position pposition=xshade.scene().active_shape().vertex(pointnum).position if ((iposition[0]-pposition[0])**2+(iposition[1]-pposition[1])**2+(iposition[2]-pposition[2])**2)<((tposition[0]-pposition[0])**2+(tposition[1]-pposition[1])**2+(tposition[2]-pposition[2])**2): tempnum=i #接続点とウェルド先の頂点の間に辺を結ぶ(ただし接続点が0の場合は何もしない。すでにエッジが張られてる場合も) xshade.scene().active_shape().begin_removing_control_points() xshade.scene().active_shape().vertex(pointnum).remove() if len(setuzokutenlist)>0: for g in setuzokutenlist: if g!=tempnum: if return_edge_number(g,tempnum)==-1: xshade.scene().active_shape().append_edge(g,tempnum) xshade.scene().active_shape().end_removing_control_points() #面の向きがおかしくならないよう面の向きを調整 xshade.scene().active_shape().adjust_face_direction()