import math import copy #選択の拡張(回転) #2010.09.30 #shade1301に対応 #選択している要素(頂点、辺、面)を、特定の場所を中心に、回転しながら選択を拡張します #パラメーター #angle・・・角度(間隔) #cent1・・・0の場合はオブジェクトのバウンディングボックスの中心を回転の中心に、1の場合は弟階層にある円か球の中心を中心に #axis・・・0でX軸(と並行な直線)まわりに回転、1でY軸まわりに回転、2でZ軸まわりに回転 #gosa・・・・誤差 #動作条件 #選択形状がポリゴンメッシュ #編集モードに入っている #要素(頂点、辺、面)が1個以上選択されている def return_kaiten(pos,cpos,kakudo2,ziku): #posをcposを中心にziku(0x軸、1y軸、2z軸)まわりにkakudoだけ回転させて返す kakudo=(2*math.pi*kakudo2)/360 # kakudo=kakudo2 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 def faceal(): #面の場合 ashape=xshade.scene().active_shape() xscene=xshade.scene() #選択面をリストに格納 aflist=[] for i in range(ashape.number_of_faces): if ashape.face(i).active==True: aflist.append(i) #選択順にソート aflist=sort_faces_by_active_order(aflist) dousasuru=0 if len(aflist)>0:dousasuru=1 if dousasuru==1: renzoku=1 gosa=0.0001 angle=60 axis=0 cent1=0 while(renzoku): #ダイアログ開く dialog22=xshade.create_dialog() idxf1=dialog22.append_double('回転角度(0より大)') dialog22.begin_group() idxf3=dialog22.append_radio_button('回転の中心/オブジェクトの中心/弟階層の円か球の中心') dialog22.end_group() dialog22.begin_group() idxf4=dialog22.append_radio_button('回転軸/X軸と並行/Y軸と並行/Z軸と並行') dialog22.end_group() idxf2=dialog22.append_double('誤差') dialog22.set_value(idxf1,angle) dialog22.set_value(idxf2,gosa) dialog22.set_value(idxf3,cent1) dialog22.set_value(idxf4,axis) xshade.idle(120) xshade.scene().update_figure_window() kekka1=dialog22.ask('選択の拡張 回転') if kekka1==False:renzoku=0 else: angle=dialog22.get_value(idxf1) if angle<=0:angle=1 gosa=dialog22.get_value(idxf2) cent1=dialog22.get_value(idxf3) axis=dialog22.get_value(idxf4) #回転の中心の位置を求める (弟階層に円球が無い場合は・・・) if cent1==1: if ashape.has_bro==True: if ashape.bro.type==5 or ashape.bro.type==6: cpos=ashape.bro.center else:cent1=0 else:cent1=0 if cent1==0: #オブジェクトのバウンディングボックスを計算 tpoint=ashape.vertex(0).position xmin=tpoint[0] xmax=tpoint[0] ymin=tpoint[1] ymax=tpoint[1] zmin=tpoint[2] zmax=tpoint[2] for i in range(ashape.total_number_of_control_points): tp2=ashape.vertex(i).position if tp2[0]xmax:xmax=tp2[0] if tp2[1]ymax:ymax=tp2[1] if tp2[2]zmax:zmax=tp2[2] cpos=[(xmin+xmax)/2,(ymin+ymax)/2,(zmin+zmax)/2] #選択面の中心位置リストを作成 afcenter=[] for gg in aflist: templist2=ashape.face(gg).vertex_indices tempc=[0,0,0] for jj in templist2: tempos=ashape.vertex(jj).position tempc=[tempc[0]+tempos[0],tempc[1]+tempos[1],tempc[2]+tempos[2]] tempc=[tempc[0]/len(templist2),tempc[1]/len(templist2),tempc[2]/len(templist2)] afcenter.append(tempc) #全ての面の中心位置リストを作成 allcenter=[] for gg in range(ashape.number_of_faces): templist2=ashape.face(gg).vertex_indices tempc=[0,0,0] for jj in templist2: tempos=ashape.vertex(jj).position tempc=[tempc[0]+tempos[0],tempc[1]+tempos[1],tempc[2]+tempos[2]] tempc=[tempc[0]/len(templist2),tempc[1]/len(templist2),tempc[2]/len(templist2)] allcenter.append(tempc) #360を回転数でわる num=int(360/angle) if angle*num==360:num=num-1 # print num #検査する面の中心位置リストを作成 centerlist=[] for gg in range(num): ang=(gg+1)*angle for jj in range(len(afcenter)): #回転 tempos=return_kaiten(afcenter[jj],cpos,ang,axis) centerlist.append(tempos) #面の検査と追加リスト作成 tuikalist=[] for gg in centerlist: for jj in range(len(allcenter)): if ((allcenter[jj][0]-gg[0])**2+(allcenter[jj][1]-gg[1])**2+(allcenter[jj][2]-gg[2])**2)0:dousasuru=1 if dousasuru==1: renzoku=1 gosa=0.0001 angle=60 axis=0 cent1=0 while(renzoku): #ダイアログ開く dialog22=xshade.create_dialog() idxf1=dialog22.append_double('回転角度(0より大)') dialog22.begin_group() idxf3=dialog22.append_radio_button('回転の中心/オブジェクトの中心/弟階層の円か球の中心') dialog22.end_group() dialog22.begin_group() idxf4=dialog22.append_radio_button('回転軸/X軸と並行/Y軸と並行/Z軸と並行') dialog22.end_group() idxf2=dialog22.append_double('誤差') dialog22.set_value(idxf1,angle) dialog22.set_value(idxf2,gosa) dialog22.set_value(idxf3,cent1) dialog22.set_value(idxf4,axis) xshade.idle(120) xshade.scene().update_figure_window() kekka1=dialog22.ask('選択の拡張 回転') if kekka1==False:renzoku=0 else: angle=dialog22.get_value(idxf1) if angle<=0:angle=1 gosa=dialog22.get_value(idxf2) cent1=dialog22.get_value(idxf3) axis=dialog22.get_value(idxf4) #回転の中心の位置を求める (弟階層に円球が無い場合は・・・) if cent1==1: if ashape.has_bro==True: if ashape.bro.type==5 or ashape.bro.type==6: cpos=ashape.bro.center else:cent1=0 else:cent1=0 if cent1==0: #オブジェクトのバウンディングボックスを計算 tpoint=ashape.vertex(0).position xmin=tpoint[0] xmax=tpoint[0] ymin=tpoint[1] ymax=tpoint[1] zmin=tpoint[2] zmax=tpoint[2] for i in range(ashape.total_number_of_control_points): tp2=ashape.vertex(i).position if tp2[0]xmax:xmax=tp2[0] if tp2[1]ymax:ymax=tp2[1] if tp2[2]zmax:zmax=tp2[2] cpos=[(xmin+xmax)/2,(ymin+ymax)/2,(zmin+zmax)/2] #選択辺の中心位置リストを作成 aecenter=[] for gg in aelist: tv0=ashape.edge(gg).v0 tv0pos=ashape.vertex(tv0).position tv1=ashape.edge(gg).v1 tv1pos=ashape.vertex(tv1).position tempc=[(tv1pos[0]+tv0pos[0])/2,(tv1pos[1]+tv0pos[1])/2,(tv1pos[2]+tv0pos[2])/2] aecenter.append(tempc) #全ての辺の中心位置リストを作成 allcenter=[] for gg in range(ashape.number_of_edges): tv0=ashape.edge(gg).v0 tv0pos=ashape.vertex(tv0).position tv1=ashape.edge(gg).v1 tv1pos=ashape.vertex(tv1).position tempc=[(tv1pos[0]+tv0pos[0])/2,(tv1pos[1]+tv0pos[1])/2,(tv1pos[2]+tv0pos[2])/2] allcenter.append(tempc) #360を回転数でわる num=int(360/angle) if angle*num==360:num=num-1 # print num #検査する辺の中心位置リストを作成 centerlist=[] for gg in range(num): ang=(gg+1)*angle for jj in range(len(aecenter)): #回転 tempos=return_kaiten(aecenter[jj],cpos,ang,axis) centerlist.append(tempos) #辺の検査と追加リスト作成 tuikalist=[] for gg in centerlist: for jj in range(len(allcenter)): if ((allcenter[jj][0]-gg[0])**2+(allcenter[jj][1]-gg[1])**2+(allcenter[jj][2]-gg[2])**2)0:dousasuru=1 if dousasuru==1: renzoku=1 gosa=0.0001 angle=60 axis=0 cent1=0 while(renzoku): #ダイアログ開く dialog22=xshade.create_dialog() idxf1=dialog22.append_double('回転角度(0より大)') dialog22.begin_group() idxf3=dialog22.append_radio_button('回転の中心/オブジェクトの中心/弟階層の円か球の中心') dialog22.end_group() dialog22.begin_group() idxf4=dialog22.append_radio_button('回転軸/X軸と並行/Y軸と並行/Z軸と並行') dialog22.end_group() idxf2=dialog22.append_double('誤差') dialog22.set_value(idxf1,angle) dialog22.set_value(idxf2,gosa) dialog22.set_value(idxf3,cent1) dialog22.set_value(idxf4,axis) xshade.idle(120) xshade.scene().update_figure_window() kekka1=dialog22.ask('選択の拡張 回転') if kekka1==False:renzoku=0 else: angle=dialog22.get_value(idxf1) if angle<=0:angle=1 gosa=dialog22.get_value(idxf2) cent1=dialog22.get_value(idxf3) axis=dialog22.get_value(idxf4) #回転の中心の位置を求める (弟階層に円球が無い場合は・・・) if cent1==1: if ashape.has_bro==True: if ashape.bro.type==5 or ashape.bro.type==6: cpos=ashape.bro.center else:cent1=0 else:cent1=0 if cent1==0: #オブジェクトのバウンディングボックスを計算 tpoint=ashape.vertex(0).position xmin=tpoint[0] xmax=tpoint[0] ymin=tpoint[1] ymax=tpoint[1] zmin=tpoint[2] zmax=tpoint[2] for i in range(ashape.total_number_of_control_points): tp2=ashape.vertex(i).position if tp2[0]xmax:xmax=tp2[0] if tp2[1]ymax:ymax=tp2[1] if tp2[2]zmax:zmax=tp2[2] cpos=[(xmin+xmax)/2,(ymin+ymax)/2,(zmin+zmax)/2] #選択頂点の位置リストを作成 apcenter=[] for gg in aplist: tempc=ashape.vertex(gg).position apcenter.append(tempc) #全ての辺の中心位置リストを作成 allcenter=[] for gg in range(ashape.total_number_of_control_points): tempc=ashape.vertex(gg).position allcenter.append(tempc) #360を回転数でわる num=int(360/angle) if angle*num==360:num=num-1 # print num #検査する頂点の中心位置リストを作成 centerlist=[] for gg in range(num): ang=(gg+1)*angle for jj in range(len(apcenter)): #回転 tempos=return_kaiten(apcenter[jj],cpos,ang,axis) centerlist.append(tempos) #頂点の検査と追加リスト作成 tuikalist=[] for gg in centerlist: for jj in range(len(allcenter)): if ((allcenter[jj][0]-gg[0])**2+(allcenter[jj][1]-gg[1])**2+(allcenter[jj][2]-gg[2])**2)