チュートリアル 4: 一般的なユースケースを使用して VRED Core をカスタマイズする方法

一般的なユースケースを使用して VRED Core をカスタマイズする方法について説明します。

サンプル スクリプトをダウンロードする

サンプル スクリプトに移動する

ビデオ キャプション: VRED Core のチュートリアルへようこそ。Christopher といいます。本日は、引き続き前回のビデオで開始したユースケースおよび VRED Core を使用したタスクの自動化のチュートリアルを進めていきます。ここでは、複数のファイルを一度に処理する単純な自動化スクリプトを使用して、シーンのレンダリング、別のファイル形式へのファイルの変換、シーングラフの最適化を行うパイプラインの作成方法を紹介します。

VRED Core の自動化スクリプトを作成する方法はいくつかあり、オペレーティング システム、ユースケース、その他多くの要因によっても異なります。そのため、スクリプトを記述するための正しい方法というものはなく、いくつかは適切で、いくつかはあまり適切ではありません。

このチュートリアルでは、Python スクリプトを使用して VRED Core パイプラインを自動化しますが、Windows のバッチ スクリプトや Linux の共有スクリプト、またはまったく異なる方法でも同じ結果を得ることができます。ここでは、実行可能な方法についてのアイデアを提供します。

システムにインストールされた Python ランタイムを自由に使用することができる Visual Studio Code 環境を使用しています。ボタンを押すだけで、スクリプトを実行して、結果を即座にターミナルで確認することができます。

最初のサンプルから始めましょう。ディレクトリ内のすべてのファイルを別のファイル形式に変換します。前回のチュートリアルでは、-pre および -post コマンド ライン オプションについて学習しました。このオプションは、コマンド ラインから VRED を起動するときにコードを実行するのに役立ちます。このパラメータを使用すると、ファイルをロードし、ファイル拡張子を変更して別の形式で保存するように VRED に指示することができます。

この例では、さらにステップアップします。ディレクトリ内のすべてのファイルを自動的に別のファイル形式に変換します。新しい Python ファイルから開始し、スクリプトを設定する変数を定義します。VRED Core 実行実行可能ファイルのパスを定義し、ソース ファイルのファイル拡張子と、ソース ファイルを検索するディレクトリを定義します。また、ターゲット ファイルのファイル拡張子と、ターゲット ファイルを保存するディレクトリも定義します。

ここで Windows の開始パスを使用し、r キーワードを使用して、ここで定義されたものと完全に一致する文字列を読み込むように Python に指示します。そうしない場合、バックスプラッシュを回避する必要があります。ターゲット ディレクトリがまだ存在しない場合は、作成する必要があります。

その後、ソース ディレクトリ内のすべてのファイルに対して処理を反復することができます。正しい拡張子のファイルのみを処理するために、拡張子を付けずにファイル名を抽出し、変換されたファイルを保存するファイル パスを作成します。次に、ソース ファイルとターゲット ファイルのファイル パスを作成します。変数ファイル名にはパス全体ではなくファイル名のみが含まれるため、これを行う必要があります。

VRED は Linux スタイルのファイル パスのみを内部で使用するため、ここではファイル パスに注意する必要があります。ただし、Python 関数 join は Windows スタイルのファイル パスを返します。このため、ファイル パスを使用する前にすべてのバックスラッシュをスラッシュに置換する必要があります。

最後に、サブプロセス関数 call を使用して VRED Core を開始し、-pre Python パラメータを追加してファイルを変換します。スクリプトを実行すると、ソース ディレクトリのすべてのファイルが VRED にロードされ、別のファイル形式でターゲット ディレクトリに保存されます。

これは VRED Core を使用してタスクを自動化する最も効率的な方法ではないという疑いを既にお持ちかもしれません。これは、スクリプトが各ファイルごとに VRED を起動し、そのために時間がかかり、ファイルを処理すると再び VRED を閉じるからです。

このスクリプトは少数のファイルに適していますが、短時間で多くのファイルを処理する場合は、オーバーヘッドが大きすぎます。ただし心配はいりません。次のサンプルではこの問題を修正します。

バッチ レンダリング、より正確には VRED Pro で自動レンダリングをカスタマイズする方法を見てみましょう。ビューポイントとバリアントの組み合わせが異なる多数のフレームをレンダリングする必要があるという問題に直面する場合があります。これは VRED Pro では非常に簡単な操作です。レンダリング設定を使用して、シーケンス内のバリアント セットとビューポイントのすべての組み合わせをレンダリングするように VRED に指示できるためです。

もちろん、Python スクリプトを使用した VRED Core でも同じ結果を得ることができます。ここでも、新しい Python ファイルを使用し、ビューポイントとバリアント セットのすべての組み合わせをレンダリングするコードを追加します。最初に、VRED ファイルが配置された場所、使用するバリアント、およびレンダリングするビューポイントをスクリプトに伝える変数をいくつか定義します。また、新しいファイル名を生成するために使用されるパス テンプレートを定義し、レンダリングされたイメージを並べ替えることもできます。

次に、load 関数を使用して VRED ファイルをロードし、すべてのビューポイントとバリアント セットに対して処理を反復します。これにより、シーン内でこの特定の状態が順次選択され、createSnapshot を使用してイメージがレンダリングされます。

ここでは、先ほど定義したパス テンプレートに従ってビューポイントとバリアントの名前を設定し、レンダリング解像度も設定します。この Python スクリプトはすべてのイメージをレンダリングしますが、何らかの方法で VRED にスクリプトを読み込む必要があります。

前の例では、-pre Python パラメータを使用し、スクリプト全体を通常の Python ファイルと同様にロードしました。テキストまたはファイルを base64 としてエンコーディングできるオンライン サービスがあり、その結果を VRED のパラメータとして取得することができます。

この文字列の文字と数字はエンコーディングしたコードと同じであるため、VRED ではこのコードを実際の Python コードとして認識して読み込むことができます。-pre Python パラメータの base64 文字列をコピーして貼り付けるだけで、通常の Python ファイルと同様にスクリプト全体がロードされます。テキストまたはファイルを base64 としてエンコーディングできるオンライン サービスがあり、その結果を VRED のパラメータとして取得することができます。

この文字列の文字と数字はエンコーディングしたコードと同じであるため、VRED ではこのコードを実際の Python コードとして認識して読み込むことができます。単純に -pre Python パラメータの base64 文字列をコピーして貼り付けることもできますが、このサンプルでは、VRED スクリプトを直接 Python スクリプトにエンコーディングする方法を示します。

そのためには、Python コード ブロックを三重引用符で囲み、テキストを変数に格納する必要があります。三重引用符を使用すると、コード ブロックがここで示すように 1 行ずつ記述されたものとして正確に解釈されます。スクリプトは有効な Python スクリプトである必要があります。つまり、空白を含めて、すべてが正しく記述されている必要があります。そうでないと、VRED で実行しようとしたときにエラーが発生します。

次に変数を使用して、コンテンツをこのコード行を含む base64 にエンコーディングすることができます。最後の行では、パラメータ -pre Python を使用して VRED Core を開始し、エンコーディングされた Python スクリプトを入力として使用します。不足している読み込みを追加すると、準備が整います。スクリプトの実行には時間がかかりますが、最終的には 9 つの異なるシーン イメージがレンダリングされます。

これで、base64 エンコーディングを使用して Python スクリプト全体を VRED Core に読み込むことができます。これは非常に便利ですが、このサンプルにはまだいくつかの欠点があります。まず、VRED Python スクリプトが自動化 Python スクリプトと同じファイル内にあるということです。

次に、ご覧のように、VRED スクリプトを引用符で囲むと、IE では通常の Python 構文が強調表示されません。この方法ではスクリプトを読んで維持することが難しいので、次のサンプルではこれをさらに最適化して、シーン ジオメトリの最適化を自動化する方法を示します。

ここでは、2 つの Python ファイルが必要になります。1 つは VRED Python スクリプトを含むファイルで、もう 1 つはこのスクリプトを入力として使用して VRED Core を起動するファイルです。VRED スクリプトで、データ変換のサンプルと同じ方法で開始し、最適化前のファイルを含むディレクトリと最適化後のファイルを含むディレクトリの変数を定義します。

もちろん、ディレクトリがまだ存在していない場合は、作成する必要があります。最適化前のファイルに対して処理を反復し、ソース ファイルとターゲット ファイルのパスを作成し、最適化前のファイルをロードして、最適化を適用します。これらの最適化は、VRED の Python API 1 の vrOptimize モジュールで定義します。このドキュメントはオンラインで見つけることができます。

適用できる最適化は多数ありますが、ジオメトリとユースケースに応じてこれらの最適化は異なります。これらの 2 つのオプションを選択したサンプルを示します。最後に、ターゲットファイル パスにファイルを保存すれば完了です。すべてのファイルが処理されたら、VRED を終了します。このスクリプトは、前のサンプルと同じ base64 エンコーディングの方法を使用して VRED に直接読み込まれます。ただし今回は、別の Python スクリプトから VRED を起動して、それらのスクリプトを分離します。

2 番目の Python ファイルでは、VRED Core へのパスを定義し、2 つのファイルが保存されるディレクトリのパスも定義します。これは、実行時にこのスクリプトへの完全なパスを含むこの Python スクリプトのファイル属性を使用して行うことができます。次に、先ほど作成し、同じディレクトリにある VRED スクリプト ファイルを開いてそのコンテンツを読みます。次に、ファイルのコンテンツを base64 としてエンコーディングし、前のサンプルと同様に VRED を起動します。

VRED スクリプトと自動化スクリプトを分離することには、他のパイプラインで VRED スクリプトを再利用できるという利点があり、構文のハイライト表示など、Visual Studio のような IDE で開発する場合の利点を最大限に活用できます。

このサンプルでは、VRED を 1 回だけ起動し、実行中の VRED インスタンス内のすべてのファイルを処理していることもわかります。これは、最適化するすべてのファイルに対して VRED を起動するよりもはるかに効率的です。

このように、VRED では、レンダリング パイプラインやデータ準備パイプラインのスクリプトを自動化する方法が多数あります。これは Python で実行できますが、バッチ、シェルなどの他のスクリプト言語でも実行できます。これは、使用するタスク、ユースケース、および開発環境に完全に依存します。ただし、基本原則は常に似ています。-pre および -post Python コマンド ライン パラメータを使用して、処理を行う Python スクリプトを VRED に挿入します。また、これらの Python スクリプトは、VRED の Python API で定義されているすべての関数を使用できます。

最初の自動化 VRED パイプラインのスクリプトを作成するためのいくつかの開始点についてご覧いただきました。今日の説明はこれで終わりです。このスクリプトのチュートリアルを楽しんでいただけたことを祈ります。また次回、お会いしましょう。


Python サンプル コード

これは、「チュートリアル 4: 一般的なユースケースを使用して VRED Core をカスタマイズする方法」ビデオに付属する Python サンプル スクリプトです。

ヒント:

以下のファイルが含まれた ZIP ファイルをダウンロードするには、ここをクリックしてください。

batch-data-conversion.py

import base64
import subprocess
import os

print("=[VRED Core Tutorial] Batch Data Conversion")

vredCorePath = r'D:\Programme\Autodesk\VREDCore-13.3\bin\WIN64\VREDCore.exe'

sourceExtension = 'vpb'
sourceDirectory = r'C:\VRED_Examples\vpb'

targetExtension = 'fbx'
targetDirectory = r'C:\VRED_Examples\fbx'

# Create target directory if it does not exist
if not os.path.exists(targetDirectory):
    os.makedirs(targetDirectory)

# Iterate over files in source directory and process each filename
for filename in os.listdir(sourceDirectory):
    # ... but only if the file extension matches
    if filename.endswith(sourceExtension): 
        # Extract the file name without the extension
        namePart = filename.split('.')[0]

        print("=[VRED Core Tutorial] Data Conversion: {} from {} to {}".format(namePart, sourceExtension, targetExtension))

        # Create paths for the source and the target file
        # Replace windows backslashes with linux style forward slashes
        sourcePath = os.path.join(sourceDirectory, filename).replace('\\','/')
        targetPath = os.path.join(targetDirectory, '{}.{}'.format(namePart, targetExtension)).replace('\\','/')

        # Start vred and process files
        subprocess.call([vredCorePath, '-prepython=load("{}"); save("{}"); terminateVred()'.format(sourcePath, targetPath)])

print("=[VRED Core Tutorial] Finished Batch Data Conversion...")

batch-data-optimization-runner.py

import os
import base64
import subprocess

vredCorePath = r'D:\Programme\Autodesk\VREDCore-13.3\bin\WIN64\VREDCore.exe'

directory = os.path.dirname(__file__)

with open(os.path.join(directory, 'batch-data-optimization.py'), 'r') as file:
    # Read file content
    scriptContent = file.read()

    # Convert python script to base64, in order to import it into VRED
    base64EncodedScript = base64.b64encode(scriptContent.encode('UTF-8')).decode('UTF-8')

    # Start VRED with prepython and the base64 encoded script as input
    subprocess.call([vredCorePath, '-prepython={}'.format(base64EncodedScript)])

batch-data-optimization.py

import os

print("=[VRED Core Tutorial] Batch Data Optimization")

sourceDirectory = 'C:/VRED_Examples/unoptimized'
targetDirectory = 'C:/VRED_Examples/optimzied'

# Create target directory if it does not exist
if not os.path.exists(targetDirectory):
    os.makedirs(targetDirectory)

# Iterate over files in source directory and process each filename
for filename in os.listdir(sourceDirectory):
    print("=[VRED Core Tutorial] Optimize file: {}".format(filename))

    # Create paths for the source and the target file
    # Replace windows backslashes with linux style forward slashes
    sourcePath = os.path.join(sourceDirectory, filename).replace('\\\\','/')
    targetPath = os.path.join(targetDirectory, filename).replace('\\\\','/')

    # Load file in VRED
    load(sourcePath)

    # Optimize Geometry
    removeTransformNodesWithNoChildren(findNode("Root"))
    optimizeIndices(findNode("Root"))

    # Save optimized file
    save(targetPath)

# Close VRED instance
terminateVred()

batch-rendering.py

import sys
import base64
import subprocess

vredCorePath = r'D:\Programme\Autodesk\VREDCore-17.2\bin\WIN64\VREDCore.exe'

batchRenderingScript = '''
vredSceneFile = r"C:/ProgramData/Autodesk/VREDPro-<internalVersion>/examples/Automotive_Genesis.vpb"
variants = ("Black Metallic", "Blue Fire Metallic", "Silver Dark Metallic")
viewpoints = ("Home", "Left-Back", "Viewpoint")
pathTemplate = r"C:/VRED_Examples/batch_rendering/variant_{viewpoint}_{variant}.png"

print("=[VRED Core Tutorial] Load Source file...")
load(vredSceneFile)

print("=[VRED Core Tutorial] Iterate viewpoints and variants...")
for viewpointName in viewpoints:
    vp = vrCameraService.getViewpoint(viewpointName)
    if not vp.isNull():
        vp.activate()
        for variantName in variants:
            print("=[VRED Core Tutorial] Rendering {}, {}".format(viewpointName, variantName))
            vrVariants.selectVariantSet(variantName)
            createSnapshot(pathTemplate.format(viewpoint=viewpointName, variant=variantName), 1920, 1080)

print("End")
'''

# Convert python script to base64, in order to import it into VRED
base64EncodedScript = base64.b64encode(batchRenderingScript.encode('UTF-8')).decode('UTF-8')

# Start VRED with prepython and the base64 encoded script as input
subprocess.call([vredCorePath, '-prepython={}'.format(base64EncodedScript)])