Khronos標準OpenGLが使われている3Dモデリングツール「Blender」を使ってみた

# 背景
私は自動車向け組み込みソフト開発に従事しているフィットネス系ソフトウェアエンジニアで、普段は筋トレしかしていませんが、気になったので調べてみました。

自動車業界としてSDV（Software Defined Vehicle）実現が課題となる中で、
「Khronos」というコンソーシアムがあることを知った。

「Khronos」とは、主にコンピュータグラフィックスや並列コンピューティング、ビジョン処理、そして音声処理などの分野で標準の仕様を策定するコンソーシアムである。

https://qiita.com/issykatsu/items/a2d4ba2497d210b4ebe2

※経済産業省作成の「モビリティDX戦略」に記載されている。

https://www.meti.go.jp/policy/mono_info_service/mono/automobile/jido_soko/index.html

![スクリーンショット 2024-07-15 15.21.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/d207ccb1-a57a-4421-27d0-6619263d6d2b.png)

余談：僕はフィットネスウェアブランドの「CRONOS」しか知らなかった。

https://cronos-fit.com/?srsltid=AfmBOop0v69Tp28Bl4FHCQQSNtjFHKpbUESqrQo4hDghI3hCf4G3hBrm

# Khronosの目的

https://www.khronos.org/about/

オープンな標準を策定することで、以下を達成すること。

・エンジニアリングコストの削減（特定のプラットフォームに依存せずアプリケーションを開発可能）
・市場投入までの時間を短縮
・市場の成長（市場参入障壁を低くし、市場拡大）
・企業の革新と差別化

非競争領域のコスト削減という目的は、車載業界のAUTOSARと同じだと思う。

例えば2D/3Dグラフィックスが、Khronosで標準化したAPIを使って車載ECUにも搭載されるのであれば、
狙い（市場の成長）どおり、市場を拡大して（自動車業界にも範囲を広げて）いると思う。

# メンバーシップ

https://www.khronos.org/members/list

Khronosは、車載標準団体のAUTOSARと同じように、メンバーシップがある。

1. Promoter Member:
完全なワーキンググループの参加と議決権に加えて、Khronos理事会に取締役を任命する権利を持つ。

2. Contributor Member:
参加を希望するすべてのエンティティが利用できます。完全なワーキンググループの参加と投票権を持つ。

3. Associate Members:
従業員が100人未満の企業で利用できる。ワーキンググループに完全に参加しているが、ワーキンググループの投票権はない。

4. Academic Members
認定された学術機関が利用できる。ワーキンググループに完全に参加しているが、ワーキンググループの投票権はない

# 主な活動
Khronos Groupは、例えば以下のようなAPIを策定している。

https://registry.khronos.org

OpenGL:
3DグラフィックスのためのクロスプラットフォームAPI。

Vulkan:
高効率かつ高パフォーマンスな3Dグラフィックスと計算のための次世代API。

OpenCL:
異種並列計算のためのフレームワーク。

WebGL:
ウェブブラウザ上での3DグラフィックスのためのAPI。

OpenVX:
ビジョン処理のためのAPI。

SYCL:
シングルソースのC++プログラミングをサポートする異種並列計算のためのAPI。

Khronos Groupは、これらのAPIを通じて、開発者が高性能なアプリケーションを効率的に開発できるよう支援しています。これにより、業界全体の発展と技術革新が促進され、多くの分野での応用が広がっています。

# OpenGLの使用例

https://www.blender.org

「Blender」という3DモデリングおよびアニメーションソフトウェアでOpenGLが使われていて、ユーザがOpenGLを使って拡張することもできるらしい。

https://colorful-pico.net/introduction-to-addon-development-in-blender/2.7/html/chapter_01/04_Understand_Install_Uninstall_Update_Add-on.html?toc-chapter=1.%20Blenderアドオン開発の世界へようこそ&toc-section=@04:1-4.%20アドオンのインストール・アンインストール・アップデート方法を理解する

https://qiita.com/nutti/items/835b745257a79ed215e8

※Blenderで、OpenGLすべてのAPIが使えるわけではなく、あくまでWrapperが用意されていて、使えるAPIは以下のようにまとめられている。

https://docs.blender.org/api/blender_python_api_master/bgl.html

例えば以下のようなAPIが用意されている。

bgl.glVertexxf()
 用途: 頂点を指定（2D用と3D用のバージョンがある）
```
bgl.glVertex3f(1.0, 1.0, 0.0)  # 3Dの頂点
```

bgl.glColor4f()
用途: 色と透明度を指定。
```
bgl.glColor4f(1.0, 0.0, 0.0, 1.0)  # 赤色、不透明
```

bgl.glLineWidth()
用途: 線の太さを設定。
```
bgl.glLineWidth(2.0)  # 線の太さを2ピクセルに設定
```

## OpenGLが使われている3Dモデリングツール「Blender」を使ってみた
以下の動画を見れば、簡単にテキトーなものは作ることができた。

「【初心者向け】世界一やさしいBlender入門！使い方＆導入〜画像作成までを徹底解説【3.6対応】」

https://youtu.be/S6aAvxUx2ko?si=yLS5k2z0N0ildlG9

作品名：「整体に来た全裸人間」

![筋肉.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/50577043-1926-9888-9382-7e4b063f533e.png)

カメラの角度とか光量とかも簡単に変えることができる。

![筋肉2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/f7b71630-6afe-f8e2-f36f-cb84823c7185.png)

ユーザが機能を拡張していけるので、意味はないけど床が波打つようなアニメーションになるようなアドオンをpythonで作ってスクリプトを実行するとこんな感じになる。

![実行GIF4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/fd1db4e8-55cd-5525-43c7-53a607a248ba.gif)


```py:メッシュ(平面)を変形させるサンプルコード(chatgptで作ってもらった)

import bpy
import math

class MeshDeformOperator(bpy.types.Operator):
    """選択したメッシュオブジェクトを変形するオペレーター"""
    bl_idname = "object.mesh_deform_operator"
    bl_label = "Mesh Deform Operator"
    bl_options = {'REGISTER', 'UNDO'}

    # アニメーションの時間パラメータ
    time: bpy.props.FloatProperty(name="Time", default=0.0, min=0.0, max=10.0)

    def execute(self, context):
        # アクティブなメッシュオブジェクトを取得
        obj = context.object
        if obj and obj.type == 'MESH':
            mesh = obj.data

            # 頂点を変形させる
            for vertex in mesh.vertices:
                x, y, z = vertex.co.x, vertex.co.y, vertex.co.z
                vertex.co.z = math.sin(x * 2.0 + self.time) * 0.2

            # メッシュを更新
            mesh.update()
            return {'FINISHED'}
        else:
            self.report({'ERROR'}, "選択されたオブジェクトはメッシュではありません")
            return {'CANCELLED'}

    def invoke(self, context, event):
        # タイマーを設定してリアルタイムで変形を実行
        self._timer = context.window_manager.event_timer_add(0.05, window=context.window)
        context.window_manager.modal_handler_add(self)
        return {'RUNNING_MODAL'}

    def modal(self, context, event):
        if event.type == 'TIMER':
            # タイムを更新
            self.time += 0.1
            self.execute(context)
            context.area.tag_redraw()

        elif event.type in {'ESC', 'RIGHTMOUSE'}:
            # タイマーを削除して終了
            context.window_manager.event_timer_remove(self._timer)
            return {'CANCELLED'}
        
        return {'RUNNING_MODAL'}

class SimpleMeshDeformPanel(bpy.types.Panel):
    """ツールシェルフに表示されるパネル"""
    bl_label = "Mesh Deform Panel"
    bl_idname = "VIEW3D_PT_mesh_deform"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Tools'

    def draw(self, context):
        layout = self.layout
        layout.operator("object.mesh_deform_operator", text="Start Mesh Deformation")

def register():
    bpy.utils.register_class(MeshDeformOperator)
    bpy.utils.register_class(SimpleMeshDeformPanel)

def unregister():
    bpy.utils.unregister_class(MeshDeformOperator)
    bpy.utils.unregister_class(SimpleMeshDeformPanel)

if __name__ == "__main__":
    register()
```
※以下のサイトを参考に、OpenGL（bgl）を使ったスクリプトではなぜかうまく動きませんでした。（三角形の図形が表示されることを狙ってアドオン機能を作ってみたんですが、開始を押しても三角形が表示されなかった）
記載されているコードのバージョンが古かったので、バージョンが合うように修正したつもりですが、なぜか図形が表示されませんでした。
OpenGLを使った機能は今後試していきます。
今回は簡単に機能を追加していけることが確認できたのでよしとします。

https://colorful-pico.net/introduction-to-addon-development-in-blender/2.7/html/chapter_03/04_Use_API_for_OpenGL.html

# まとめ
SDV実現に向けて、政府が発表しているように標準化団体の動向をウォッチして、なるべく1から作ることなく、ものづくりをしていくことが大事だと理解した。

筋トレでも、一からトレーニングメニュー等を自分で考えるのではなく、一流の選手がトレーニングメニューや食事、考え方を発信されているので、上手く取り込んでMDB（Muscle Defined Being：筋肉によって定義される人間社会）実現に向けて日々の筋トレに励んでいきたい。