ポリゴンに設定されたフェイスグループを面毎に分割する(スクリプト)
モデリングの材質表現や、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()