ポリゴンに設定されたフェイスグループを面毎に分割する(スクリプト)

モデリングの材質表現や、FBXなどのファイル形式で形状をインポートすると、
ポリゴンメッシュの面に対しフェイスグループとしてマテリアルが適用されている場合があります。

・フェイスグループとは ?
https://knowledge.shade3d.jp/kb1462

フェイスグループは、ポリゴンメッシュの面に対してマスターマテリアルが適用されるため、
緻密なメッシュで構成された形状や複数な形状にマスターマテリアルが設定されている場合は、
マテリアルを確認するのが難しい場合があります。
その場合は、以下のスクリプトを実行することで、選択したポリゴンメッシュ、または、
パート内のポリゴンメッシュに対し設定したフェイスグループを面毎に分離することができます。
これによりフェイスグループを設定した面を個別のポリゴンメッシュとして分離し、
マスターマテリアルと形状として管理することができるようになります。

スクリプトの実行前と後

使用方法:
1・ナレッジベースに記載されたスクリプトの文頭「# @title \ja」から文末の「main()」までを選択し「コピー」してください。
2・表示メニューよりスクリプトを選択してください。
3・スクリプトウィンドウが表示されますので、フィールド上にマウスカーソルを合わせ「貼り付け」を行なってください。
4・スクリプトウィンドウ内にコピーしたスクリプトが貼り付けられます。
5・選択したポリゴンメッシュ、または、パート内のポリゴンメッシュを選択して「実行」ボタンをクリックしてください。

【注意】
スクリプトを実行した形状は、削除されずバックアップとして保持されます。
ブラウザより「形状の非表示」、「レンダリング非対象」が設定され図形ウィンドウからの
操作やレンダリング等は行われませんのでご注意ください。
ブラウザより「形状の非表示」、「レンダリング非対象」については、以下のwebサイトをご確認ください。

・図形ウィンドウ上で、形状を一時的に非表示にしたい
https://knowledge.shade3d.jp/kb505
・一部の形状をレンダリングしないようにしたい
https://knowledge.shade3d.jp/kb3070


# @title \ja 選択ポリゴンメッシュを、フェイスグループ毎の形状に分ける \endja
import time

#---------------------------------------.
# 対象の形状から、フェイスグループ毎に分けた形状を作成する.
# @param[in, out] create_shapes  作成された形状を追加するリスト.
# @param[in] shape  処理対象形状.
#---------------------------------------.
def divide_facegroup_from_polygonmesh(create_shapes, shape):
 scene = xshade.scene()
 target_shape = shape.copy_object(((1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1)))#元形状は複製し、複製後の形状を使って処理する
 scene.active_shapes = [target_shape] #新しい形状が、処理中の形状に下になるようにする。

 for fgId in range(shape.get_number_of_face_groups()):
 target_faceIds = [fi for fi in range(target_shape.number_of_faces) if target_shape.get_face_group_index(fi) == fgId] #フェイスグループがfgIdの面番号リストを取得
 if len(target_faceIds)==0:continue
 target_shape.active_face_indices = tuple(target_faceIds)#形状の選択面を設定
 target_shape.separate_selected_faces(False, True)#形状から選択面を新規形状として分離:分離された形状がアクティブ形状になる
 new_shape = scene.active_shapes[0]
 new_shape.name = target_shape.name + "_group" + str(fgId);#名前変更
 #分離した形状として、対応するマスターマテリアルを割り当てる。フェイスグループに材質登録が無ければ、元の形状の材質が割り当たる
 mm = target_shape.get_face_group_surface(fgId)
 if not mm == None: new_shape.master_surface = mm
 new_shape.clear_face_group()#フェイスグループ削除
 create_shapes.append(new_shape)
 scene.active_shapes = [target_shape] #アクティブ形状を元の形状に戻す。
 #元の形状は、面がなくなっていれば削除する
 if target_shape.number_of_faces == 0:target_shape.remove() 
 else: 
 target_shape.clear_face_group()#フェイスグループ削除
 create_shapes.append(target_shape)
 target_shape.name = target_shape.name + "_independent"#名前変更
 
 
#---------------------------------------.
# 形状がフェイスグループを持つポリゴンメッシュ形状か否か.
# @param[in] shape  判定対象形状.
# @return フェイスグループを持つポリゴンメッシュであればTrue .
#---------------------------------------.
def has_facegroupe (shape):
 if shape.type == 7:#ポリゴンメッシュ
 if shape.get_number_of_face_groups() > 0:
  return True
 return False

#---------------------------------------.
# 条件にあう形状を抽出する.
# @param[in, out] dst_list  抽出された形状を追加するリスト.
# @param[in] shape  処理対象形状.
# @param[in] extraction_function  形状に対する抽出条件関数(抽出対象であればTrueを返す).
# @param[in] search_child  子形状を探索対象とするか否か.
#---------------------------------------.
def extract_shpaes (dst_list, shape, extraction_function, search_child ): #条件にあう形状の抽出
 if (extraction_function(shape)):
 dst_list.append(shape)
 if search_child and shape.has_son:
 son = shape.son
 while son.has_bro:
  son = son.bro
  extract_shpaes(dst_list, son, extraction_function, search_child)
  
#---------------------------------------.
# 「選択ポリゴンメッシュを、フェイスグループ毎の形状に分ける」処理を実行するメイン関数.
#---------------------------------------.
def main():
 start_time = time.time()
 scene = xshade.scene()
 select_shapes = scene.active_shapes
 #フェイスグループを持つポリゴンメッシュ形状のみを抽出する。
 used_facegroup_shapes = []
 for target_shape in select_shapes:
 extract_shpaes(used_facegroup_shapes, target_shape, has_facegroupe, True)
 #フェイスグループを持つポリゴンメッシュ形状が無ければそこで終了。
 if len(used_facegroup_shapes) == 0:
 print("選択形状や選択パートの中にフェイスグループのある形状が有りません")
 return
 #フェイスグループを持つポリゴンメッシュ形状からフェイスグループ毎に形状を作成する。
 create_shapes = []
 ite = 1
 endite = len(used_facegroup_shapes)
 for target_shape in used_facegroup_shapes:
 print(str(ite) + "/" + str(endite) + ":" + target_shape.name + "を処理..."+str(time.time() - start_time)+"s...面数"+str(target_shape.number_of_faces)) 
 divide_facegroup_from_polygonmesh(create_shapes, target_shape)
 ite += 1
 #後処理として、元形状に処理を行う
 for target_shape in used_facegroup_shapes:
 target_shape.show_flag = 0 #非表示化
 target_shape.render_flag = 0 #レンダリング非対象化
 #target_shape.remove()#形状の削除 
 #作成した形状を選択状態にして終了
 scene.active_shapes = create_shapes

 end_time = time.time()
 print("処理時間(秒数):" +str(end_time - start_time))
 print("■処理終了")
main()
この記事のタイトルとURLをコピーする
Translate »