本日は Blender の技術調査枠です。
Blender2.8で利用可能なpythonスクリプトを作ります。
ノードタイプの判定とノード特有の情報
マテリアルの有効な出力ノードを取得して、サーフェス入力に接続されているノードがプリンシプルBSDFか判定します。
・Script_check_surface_bsdf.py
# bpyインポート import bpy # アクティブな出力ノードに接続されたノードがプリンシプルBSDFかチェックする # (オブジェクト名指定) def check_surface_bsdf_checker(arg_objectname="Default", arg_materialname:str="BakeTexture") -> bool: """アクティブな出力ノードに接続されたノードがプリンシプルBSDFかチェックする Args: arg_objectname (str, optional): 指定オブジェクト名. Defaults to "Default". arg_materialname (str, optional): 指定マテリアル名. Defaults to "BakeTexture". Returns: bool: 実行正否 """ # 指定オブジェクトを取得する # (get関数は対象が存在しない場合 None が返る) selectob = bpy.data.objects.get(arg_objectname) # 指定オブジェクトが存在するか確認する if selectob == None: # 指定オブジェクトが存在しない場合は処理しない return False # 指定オブジェクトがメッシュオブジェクトか確認する if selectob.type != 'MESH': # メッシュオブジェクトでない場合は処理しない return False # 指定マテリアルスロットを取得する selectmatslot = selectob.material_slots.get(arg_materialname) # 指定マテリアルスロットが存在するか確認する if selectmatslot == None: # 指定オブジェクトが存在しない場合は処理しない return False # 指定マテリアルを取得する selectmat = selectmatslot.material # 指定マテリアルが存在するか確認する if selectmat == None: # 指定オブジェクトが存在しない場合は処理しない return False result = check_surface_bsdf(arg_material=selectmat) # 結果を標準出力表示する print("active surface is BSDF : " + str(result)) return True # 指定マテリアルのアクティブな出力ノードに接続されたノードがプリンシプルBSDFかチェックする def check_surface_bsdf(arg_material:bpy.types.Material) -> bool: """指定マテリアルのアクティブな出力ノードに接続されたノードがプリンシプルBSDFかチェックする Args: arg_material (bpy.types.Material): 指定マテリアル Returns: bool: プリンシプルBSDFが接続されているか """ # マテリアルのノードを有効化する use_material_node(arg_material=arg_material) # アクティブな出力ノードに接続されたノードを取得する get_node = get_node_linkoutput(arg_material=arg_material) # ノードが取得できたか確認する if get_node == None: # サーフェスノードが存在しない場合はFalseを返す return False # ノードの種類がプリンシプルBSDFかチェックして結果を返す isBSDF = check_isnode_bsdf(get_node) return isBSDF # アクティブな出力ノードに接続されたノードを取得する def get_node_linkoutput(arg_material:bpy.types.Material) -> bpy.types.Node: """アクティブな出力ノードに接続されたノードを取得する Args: arg_material (bpy.types.Material): 指定マテリアル Returns: bpy.types.Node: アクティブな出力ノードに接続されたノード """ # 参照の保存用変数 name_mapping = {} # ノード操作のマニュアル # (https://docs.blender.org/api/current/bpy.types.Node.html) # ノードリスト操作のマニュアル # (https://docs.blender.org/api/current/bpy.types.Nodes.html) # ノードツリー操作のマニュアル # (https://docs.blender.org/api/current/bpy.types.NodeTree.html) # ターゲットマテリアルのノード参照を取得する mat_nodes = arg_material.node_tree.nodes # 出力ノードを取得する変数 output_node = None # 出力ノードの操作マニュアル # (https://docs.blender.org/api/current/bpy.types.ShaderNodeOutputMaterial.html) # 全ノードを走査する for check_node in mat_nodes: # ノードタイプを取得する node_idname = check_node.bl_idname # ノードタイプが出力ノードか確認する if node_idname == 'ShaderNodeOutputMaterial': # アクティブな出力ノードのフラグを取得する is_activeoutput = check_node.is_active_output # アクティブな出力ノードかチェックする if is_activeoutput == True: # アクティブな出力ノードなら保持する output_node = check_node # 出力ノードが取得できたか確認する if output_node == None: # 出力ノードが存在しない場合は処理しない return None # ノードソケット操作のマニュアル # (https://docs.blender.org/api/current/bpy.types.NodeSocket.html) # 出力ノードのサーフェス入力(1番目の入力)のリンクを確認する surface_input = output_node.inputs[0] # リンクが接続されているか確認する if surface_input.is_linked == False: # 出力ノードにサーフェスノードが接続されていない場合は処理しない return None # リンク操作のマニュアル # (https://docs.blender.org/api/current/bpy.types.NodeLink.html#bpy.types.NodeLink) # リンクの一覧を取得する mat_links = arg_material.node_tree.links # 接続元ノードを取得する変数 surface_node = None # リンクを走査する for check_link in mat_links: # 接続先が出力ノードのサーフェス入力か確認する if check_link.to_socket == surface_input: # リンクの接続元ノードを取得する surface_node = check_link.from_node # 接続元ノードが取得できたか確認する if surface_node == None: # 接続元ノードが存在しない場合は処理しない return None # 接続元となっているサーフェスノードを返却する return_node = surface_node return return_node # 対象マテリアルのノードを有効化する def use_material_node(arg_material:bpy.types.Material): """対象マテリアルのノードを有効化する Args: arg_material (bpy.types.Material): 対象マテリアル """ # マテリアル操作のマニュアル # (https://docs.blender.org/api/current/bpy.types.Material.html) # ノードが無効な場合、有効化する if arg_material.use_nodes == False: arg_material.use_nodes = True return # 指定ノードがプリンシプルBSDFかチェックする def check_isnode_bsdf(arg_node:bpy.types.Node) -> bool: """指定ノードがプリンシプルBSDFかチェックする Args: arg_node (bpy.types.Node): 指定ノード Returns: bool: プリンシプルBSDFか否か """ # チェック結果 isBSDF = False # ノードタイプを取得する node_idname = arg_node.bl_idname # ノードタイプがプリンシプルBSDFノードか確認する if node_idname == 'ShaderNodeBsdfPrincipled': # プリンシプルBSDFならTrueを返す isBSDF = True return isBSDF # 関数の実行例 check_surface_bsdf_checker( arg_objectname="Cube", arg_materialname="Material" )
・プリンシプルBSDFノード接続の出力ノード有効時
・値ノード接続の出力ノード有効時