本日はモデリング枠です。
BlenderなどのDCCツールにはデシメートと呼ばれる機能が存在します。
今回はこのデシメートについて学んでいきます。
〇デシメートとは?
デシメート(decimate)
は「大幅に減少させる」や「破壊する」という意味で、メッシュの頂点や面の数を減らすための手法を指します。
Blenderの場合はモディファイアとして提供されています。
デシメートにはいくつかのアルゴリズムがありますが、最もシンプルな束ねる
の場合は次のように変化します。
〇デシメートの原理
デシメートのアルゴリズムについて学ぶ上で参考欄に記載したブログ記事がとても勉強になりました。
この記事によるとデシメートを行うために頂点を減らす方法として、頂点(三角形をつなぐ点)を1つずつ取り除く、エッジを折りたたむ、三角形全体を折りたたむといくつかの方法があるようです。
この際の考え方として「頂点はメッシュのテッセレーションを徐々に解除することで構成されます。」
テッセレーション
とはグラフィックの処理で、ポリゴンを分割し、詳細で滑らかな表現を行う技術です。
つまりこの逆を行っているということです。
しかしこの処理は複雑です。
3Dメッシュのポリゴンを減らすアルゴリズムの中で一般的なものがエッジコラプス法(Edge Collapse)
と呼ばれる手法です。
https://gudhi.inria.fr/doc/latest/groupedgecollapse.html#:~:text=Edge%20collapse%20definition%20An%20edge%20e%20in%20a,dominates%20e%20and%20e%20is%20dominated%20by%20v%E2%80%B2.
エッジコラスプ法では①簡略化するエッジの選択、②エッジの縮退および頂点の統合、③ジオメトリを評価し縮退させるエッジを選択
という順で頂点を減らします。
つまりエッジコラスプ法では、また別にジオメトリ全体を評価、その中から縮退させるエッジを選択するアルゴリズムが必要となります。
エッジコラスプ法で縮退させるエッジを選択するには以下のような評価基準が使用されます。
・形状の変化が最小限である
・短いエッジを優先的にする
・法線の変化が少ないエッジ
この中で、「短いエッジを優先的にする」というのはエッジの長さをすべて取得し、短いものから行うことができるという意味では最も簡単な評価基準と考えることができます。
今回はBlenderで最も短い辺を選択するコードを書きました。
import bpy import bmesh # オブジェクトが編集モードであることを確認 if bpy.context.object.mode == 'EDIT': # BMeshを取得 bm = bmesh.from_edit_mesh(bpy.context.object.data) # 最も短いエッジを見つける shortest_edge = None shortest_length = float('inf') for edge in bm.edges: length = edge.calc_length() if length < shortest_length: shortest_length = length shortest_edge = edge # すべてのエッジの選択を解除 for edge in bm.edges: edge.select = False # 最も短いエッジを選択 if shortest_edge: shortest_edge.select = True # BMeshを更新 bmesh.update_edit_mesh(bpy.context.object.data) else: print("オブジェクトが編集モードではありません。")
これを実行し最も短い辺を構成する頂点をマージすることを、繰り返すことで手動でエッジコラスプ法を再現できます。
本日は以上です。
〇参考
https://odgy.medium.com/mesh-decimation-done-right-95245c4b5f52
https://gudhi.inria.fr/doc/latest/groupedgecollapse.html#:~:text=Edge%20collapse%20definition%20An%20edge%20e%20in%20a,dominates%20e%20and%20e%20is%20dominated%20by%20v%E2%80%B2.