夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

MixedRealityModelingTools その⑧ Blender上でテクスチャの取得とバイナリの送信

本日は先日最初期のβ版リリースをしたMixedRealtiyModelingToolsの機能開発枠です。

〇MixedRealityModelingToolsとは?

MixedRealityModelingTools(MRMT)は筆者が開発しているMixedReality空間内での3DCGのデータの取り扱いに関するパッケージです。

BlenderをコアとしてMixedRealityアプリケーションに組み込める形でパッケージを開発しています。

現時点でBlender-Unityの相互通信に力を入れています。

github.com

今回はBlender上でのテクスチャの取得及び送信を紹介し間s。

Blender上でテクスチャの取得とバイナリの送信

次にUnity側でVSCodeをデフォルトのエディタとして使用するように設定します。

今回は次のようなコードでマテリアルのテクスチャを取得しています。

def get_texture(material):
    if material.use_nodes:  # check used node
        nodes = material.node_tree.nodes# get node tree
        for node in nodes:#ノードの数実行
            if node.type == 'BSDF_PRINCIPLED':  # プリンシパルBSDFシェーダーノードを検索
                base_color_socket = node.inputs["Base Color"]
                if base_color_socket.is_linked:  # BaseColorにリンクがあるかチェック
                    texture_node = base_color_socket.links[0].from_node
                    if texture_node.type == 'TEX_IMAGE':  # テクスチャノードを検索
                        texture = texture_node.image
                        texture_path = bpy.path.abspath(texture_node.image.filepath)
                        send_texture_data(texture_path,texture.name)

基本的な処理は前回紹介した記事に倣っていますが、一点だけ異なる点があります。

redhologerbera.hatenablog.com

今回はテクスチャをバイナリ情報として扱いたいため、一度PC内でのテクスチャ本体のファイルパスを取得しています。

                        texture = texture_node.image
                        texture_path = bpy.path.abspath(texture_node.image.filepath)#テクスチャのパスを取得
                        send_texture_data(texture_path,texture.name)

今回はsend_texture_data(パス、名前)として別の関数を用意して送信しています。

テクスチャの送信は次のようなコードで行っています。

def send_texture_data(texture_path,texture_name):
    IMAGE_HEADER = "IMGE"


    with open(texture_path, 'rb') as f:
        image_data = f.read()

    image_data_base64 = base64.b64encode(image_data).decode('utf-8')

    data_dict = {
        'header': IMAGE_HEADER,
        'imagename': texture_name,  
        'imagedata': image_data_base64
    }

    serialized_image_data = msgpack.packb(data_dict)

    for client in server_thread.clients:
        try:
            print(serialized_image_data)
            client.sendall(serialized_image_data)
        except Exception as e:
            print(f"Error while sending image data to client: {e}")

メッシュやマテリアル同様にMessagePackを使用してシリアライズしてバイナリを送信しています。

フォーマットは次のようになります。

    data_dict = {
        'header': IMAGE_HEADER, #string
        'imagename': texture_name,  #string
        'imagedata': image_data_base64#string
    }

これまではデータの型はStringやintかlistでしたが、今回画像データはそのまま元がバイナリのためバイナリとして送信しています。

送信する際にUTF-8Base64型としてで画像をでコードしています。

以上がBlenderからテクスチャデータを送信する処理になります。