import copy import math #ガイドラインへフィット #選択している頂点だけを弟階層のガイドラインにフィットするように移動します #上位パートに変換がかかっていると使用できないように変更(2010.03.03) #shade1301に対応 #動作条件 #選択形状がポリゴンメッシュ #編集モードに入っている #頂点選択モード #頂点が二つ以上選択されている(x、y、z座標の値が異なる) #弟形状に「gfit」というパートとその中にガイドラインが存在する #ローカル座標モードや、上位パートに変換がかかっていると結果が不正になります #設定項目 #移動方向 「x軸」「y軸」「z軸」・・・ガイドラインの名前の頭につけておく #ガイドラインの分割数・・・・分割数が大きいほど精度が高くなる dousasuru=0 xscene=xshade.scene() ashape=xshade.scene().active_shape() if ashape.type==7 and xscene.is_modify_mode==True: 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)>1: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: #選択部のバウンディングボックス minx=ashape.vertex(aplist[0]).position[0] maxx=ashape.vertex(aplist[0]).position[0] miny=ashape.vertex(aplist[0]).position[1] maxy=ashape.vertex(aplist[0]).position[1] minz=ashape.vertex(aplist[0]).position[2] maxz=ashape.vertex(aplist[0]).position[2] minxp=aplist[0] minyp=aplist[0] minzp=aplist[0] maxxp=aplist[0] maxyp=aplist[0] maxzp=aplist[0] for i in aplist: tpos=ashape.vertex(i).position if tpos[0]maxx: maxxp=i maxx=tpos[0] if tpos[1]>maxy: maxyp=i maxy=tpos[1] if tpos[2]>maxz: maxzp=i maxz=tpos[2] #選択形状がポリゴンメッシュで弟階層にガイドラインが存在しない場合はまず作成して終了 #ある場合も「変形を行う」と「ガイドラインの新規作成」で選択 #軸をたずねる(ガイドラインの頭に軸x、y、zをつける) #ガイドラインはレンダリング対象外 if dousasuru==1: gkesu=0 if ashape.has_bro==True: if ashape.bro.name=='gfit': dialog=xshade.create_dialog() if len(aplist)!=2: idx=dialog.append_radio_button('/変形を行う') else: idx=dialog.append_radio_button('/変形を行う/ガイドラインの新規作成') dialog.set_value(idx,0) xshade.idle(120) kekka7=dialog.ask('ガイドラインへフィット') if kekka7==False:dousasuru=0 else: tmode=dialog.get_value(idx) if tmode==1: dousasuru=3 gkesu=1 else: if len(aplist)==2:dousasuru=3 else:dousasuru=0 else: if len(aplist)==2:dousasuru=3 else:dousasuru=0 if dousasuru==3: #ガイドラインの作成 dialog=xshade.create_dialog() dialog.append_push_button('ガイドラインへフィット用') idx=dialog.append_radio_button('ガイドライン/x軸方向/y軸方向/z軸方向') dialog.set_value(idx,0) xshade.idle(120) kekka8=dialog.ask('ガイドラインの作成') if kekka8==True: gmode=dialog.get_value(idx) #ガイドラインの新規作成の場合は前のガイドラインを非表示に if gkesu==1: xscene.select_brother(1) xscene.hide_active() xscene.select_sister() v0=ashape.vertex(aplist[0]).position v1=ashape.vertex(aplist[1]).position #パートの作成 xshade.scene().begin_creating() xshade.scene().create_part('gfit') xshade.scene().end_creating() #ガイドライン線形状の作成 xshade.scene().begin_creating() if gmode==0: xshade.scene().create_line('xガイドライン',[v0,v1],False) if gmode==1: xshade.scene().create_line('yガイドライン',[v0,v1],False) if gmode==2: xshade.scene().create_line('zガイドライン',[v0,v1],False) xshade.scene().end_creating() # xscene.select_parent() # xshade.scene().active_shape().rendering=0 # xscene.select_sister() if dousasuru==1: #変形を行う ziku=0#ガイドラインの軸 0がx軸、1がy軸、2がz軸 #ガイドライン(線形状)のコントロールポイント数を計測と軸の確認 xscene.select_brother() xscene.select_child() bunkatu=xshade.scene().active_shape().total_number_of_control_points-1 if xshade.scene().active_shape().name=='xガイドライン':ziku=0 if xshade.scene().active_shape().name=='yガイドライン':ziku=1 if xshade.scene().active_shape().name=='zガイドライン':ziku=2 xscene.select_parent() xscene.select_sister() #ここに初期値 renzoku=1 bunkatu=1000 hk=0 dfhk=hk dfbunkatu=bunkatu while(renzoku==1): #ダイアログ表示 dialog=xshade.create_dialog_with_uuid('0x51900243') dialog.append_default_button() if ziku==0: idx2=dialog.append_radio_button('選択頂点の移動方向/Y軸方向/Z軸方向') if ziku==1: idx2=dialog.append_radio_button('選択頂点の移動方向/X軸方向/Z軸方向') if ziku==2: idx2=dialog.append_radio_button('選択頂点の移動方向/X軸方向/Y軸方向') idx3=dialog.append_int('ガイドラインの分割数(デフォルト:'+str(dfbunkatu)+')') dialog.set_default_value(idx2,dfhk) dialog.set_default_value(idx3,dfbunkatu) xshade.idle(120) kekka=dialog.ask('ガイドラインへフィット') if kekka==False:renzoku=0 else: bunkatu=dialog.get_value(idx3) if bunkatu<1:bunkatu=1 hk=dialog.get_value(idx2) if ziku==0: if hk==0:houkou=1 else:houkou=2 if ziku==1: if hk==0:houkou=0 else:houkou=2 if ziku==2: if hk==0:houkou=0 else:houkou=1 #ガイドライン(のコピー)を自由曲面パートに入れて複製つくってポリゴンメッシュに変換して頂点情報を取得 pposlist=[] xscene.select_brother() xscene.select_child() xscene.copy() xscene.begin_creating() xscene.create_surface_part() xscene.end_creating() xscene.paste() xscene.paste() if ziku==0: xscene.move_object([0,0,0],None,None,[0,0,50]) if ziku==1: xscene.move_object([0,0,0],None,None,[50,0,0]) if ziku==2: xscene.move_object([0,0,0],None,None,[0,50,0]) xscene.select_parent() xscene.active_shape().convert_to_polygon_mesh_with_divisions(1,bunkatu) for i in range(bunkatu+1): tposp=xscene.active_shape().vertex(i).position pposlist.append([tposp[0],tposp[1],tposp[2]]) #バウンディングボックス pminx=pposlist[0][0] pmaxx=pposlist[0][0] pminy=pposlist[0][1] pmaxy=pposlist[0][1] pminz=pposlist[0][2] pmaxz=pposlist[0][2] for i in pposlist: if i[0]pmaxx:pmaxx=i[0] if i[1]pmaxy:pmaxy=i[1] if i[2]pmaxz:pmaxz=i[2] xscene.clear() xscene.select_parent() xscene.select_sister() #元の形状をクリップボードにコピー ashape.copy() xscene.enter_modify_mode() #個々の頂点を移動 for i in aplist: tpos=ashape.vertex(i).position motopos=[tpos[0],tpos[1],tpos[2]] if ziku==0: dist2=abs(pposlist[0][0]-tpos[0]) nearpos=pposlist[0] for gg in pposlist: tdist=abs(gg[0]-tpos[0]) if tdist>dist2:break else: dist2=tdist nearpos=gg if ziku==1: dist2=abs(pposlist[0][1]-tpos[1]) nearpos=pposlist[0] for gg in pposlist: tdist=abs(gg[1]-tpos[1]) if tdist>dist2:break else: dist2=tdist nearpos=gg if ziku==2: dist2=abs(pposlist[0][2]-tpos[2]) nearpos=pposlist[0] for gg in pposlist: tdist=abs(gg[2]-tpos[2]) if tdist>dist2:break else: dist2=tdist nearpos=gg ttpos=[nearpos[0],nearpos[1],nearpos[2]] # if ziku==0:ttpos[0]=motopos[0] # if ziku==1:ttpos[1]=motopos[1] # if ziku==2:ttpos[2]=motopos[2] if houkou==0: ttpos=[ttpos[0],motopos[1],motopos[2]] if houkou==1: ttpos=[motopos[0],ttpos[1],motopos[2]] if houkou==2: ttpos=[motopos[0],motopos[1],ttpos[2]] ashape.vertex(i).position=ttpos #頂点のマージ # ashape.cleanup_redundant_vertices() # print [ziku,houkou] #選択箇所の再選択 xshade.scene().enter_modify_mode() for i in aplist: ashape.vertex(i).active=True #元に戻すか聞く dialog=xshade.create_dialog() idx3=dialog.append_push_button('処理を確定しますか?') xshade.idle(120) 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 aplist: ashape.vertex(i).active=True