今回はマテリアルのサブ要素(マテリアル、テクスチャ)の取得について。
マテリアルは要素の下に別の要素が入れ子式に接続される、いわゆるツリー構造を持っています。こういった構造では、再起処理を使って子要素を巡回する事で、簡単に全ての要素を処理する事が出来ます。
以下は指定マテリアル下の全てのサブ要素を取得する関数です。
fn getAllSubItemsFromMtl mtl _subs:#() =
(
if mtl != undefined and (appendIfUnique _subs mtl) do
(
if (superclassof mtl) == material do
(
for i = 1 to (getNumSubMtls mtl) do
getAllSubItemsFromMtl (getSubMtl mtl i) _subs:_subs
)
for i = 1 to (getNumSubTexmaps mtl) do
getAllSubItemsFromMtl (getSubTexmap mtl i) _subs:_subs
)
_subs
)
引数
名前 | |
---|---|
mtl | サブ要素を取得したいマテリアル。 |
_subs | 内部使用専用。基本的に使用不可。 |
使用サンプル
-- 選択オブジェクトのマテリアルを引数に指定
getAllSubItemsFromMtl $.material
これで該当マテリアルの全てのサブ要素を、配列として取得する事ができます。
ただし、取得されるサブ要素は、マテリアルとテクスチャが混ざった状態で取得されてしまいます。
関数内でどちらかのみ取得する事も出来ますが、今回は両方同時に取得しています。理由として、テクスチャのみを取得しようとした時に、「マテリアルの子マテリアルのテクスチャ」の様なケースで処理が複雑になってしまう為です。説明の為に極力シンプルにしています。
以下は取得後にマテリアルとテクスチャを分離しています。
-- マテリアルのサブ要素を取得
subs = getAllSubItemsFromMtl $.material
-- マテリアルを抽出
mtls = for s in subs where (superClassOf s) == material collect s
-- テクスチャを抽出
maps = for s in subs where (superClassOf s) != material collect s
2018/09/03: マテリアルとテクスチャの抽出をcollectに変更。
for文の中で個別にappendするよりも、1つの処理を1つのループに纏める方が今風らしいです。