本日は Blender の技術調査枠です。
Blender2.8で利用可能なpythonスクリプトを作ります。
プリンシプルBSDFのベースカラー端子の情報
プリンシプルBSDFのベースカラー端子の情報をチェックし、デフォルト値が有効な場合はベースカラー端子のデフォルト値を取得します。
本スクリプトは以下のチェックを行います。
1.指定マテリアルのアクティブな出力ノードにノードが接続されているか
2.アクティブな出力ノードに接続されたノードはプリンシプルBSDFか
3.プリンシプルBSDFのベースカラー端子にリンクが貼られておらず、デフォルト値が有効か
これらのチェックが通った場合、ベースカラー端子のデフォルト値を取得します。
・Script_get_basecolor_bsdf.py
# bpyインポート import bpy # 指定マテリアルのアクティブな出力ノードに接続されたプリンシプルBSDFのベースカラーを取得する def get_basecolor_bsdf(arg_material:bpy.types.Material) -> bpy.types.NodeSocketColor: """指定マテリアルのアクティブな出力ノードに接続されたプリンシプルBSDFのベースカラーを取得する Args: arg_material (bpy.types.Material): 指定マテリアル Returns: bpy.types.NodeSocketColor: ベースカラー(取得失敗時 None) """ # カラーの取得変数を初期化する getBaseColor = None # マテリアルのノードを有効化する 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) # プリンスプルBSDFか確認する if isBSDF == True: # プリンシプルBSDFならベースカラーにリンクが貼られているかチェックする isCheckedLink = check_link_bsdf_basecolor(get_node) # リンクが貼られていたか確認する if isCheckedLink == False: # リンクが貼られていないならベースカラー値を取得する getBaseColor = get_value_bsdf_basecolor(get_node) return getBaseColor # アクティブな出力ノードに接続されたノードを取得する 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 # 指定ノードのプリンシプルBSDFのベースカラーにリンクが設定されているかチェックする def check_link_bsdf_basecolor(arg_node:bpy.types.Node) -> bool: """指定ノードのプリンシプルBSDFのベースカラーにリンクが設定されているかチェックする Args: arg_node (bpy.types.Node): 指定ノード Returns: bool: リンクの有無 """ # チェック結果 isLinked = False # ベースカラーのリンクが接続されているか確認する if arg_node.inputs["Base Color"].is_linked == True: # リンクが設定されていればTrueを返す isLinked = True return isLinked # 指定ノードのプリンシプルBSDFのベースカラー値を取得する def get_value_bsdf_basecolor(arg_node:bpy.types.Node) -> bpy.types.NodeSocketColor: """指定ノードのプリンシプルBSDFのベースカラー値を取得する Args: arg_node (bpy.types.Node): 指定ノード Returns: bpy.types.NodeSocketColor: ベースカラー値 """ # ベースカラーのデフォルトカラーを取得する # ノードソケットカラー操作のマニュアル # (https://docs.blender.org/api/current/bpy.types.NodeSocketColor.html) basecolor_value = arg_node.inputs["Base Color"].default_value return basecolor_value # 関数の実行例 target_mat = bpy.data.materials.get("Red") mat_color = get_basecolor_bsdf(target_mat) if mat_color != None: print("Red:" + str(mat_color[0]) + ",Green:" + str(mat_color[1]) + ",Blue:" + str(mat_color[2]) + ",Alpha:" + str(mat_color[3])) else: print("None")
・ベースカラー有効時
・デフォルト値が無効な場合
・プリンシプルBSDF以外の場合