チュートリアル 6: サービスとオブジェクトを使用して V2 インタフェースを操作する方法

この「チュートリアル 6: サービスとオブジェクトを使用して V2 インタフェースを操作する方法」ビデオでは、VR 内のカメラ、ビューポイント、シーンプレートを使用するサンプルについて説明します。

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

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

チュートリアルの PDF をダウンロードする

ビデオ キャプション: VRED Pro の新しい Python チュートリアルへようこそ。Christopher といいます。今日は、新しい API バージョン 2 の以前のバージョンとの相違点、および使用方法についてお話します。

API バージョン 2 のリリースにより、オートデスクは VRED で Python インタフェースをより簡単に操作するための新しいオブジェクト モデルを導入しました。このバージョンには、サービス クラスと呼ばれる重要な機能が導入され、より多くのオブジェクト指向データタイプが使用できるようになりました。これがなぜ優れているのかを理解するには、最初に以前の API の欠点について説明する必要があります。

次のサンプルを見てみましょう。バージョン 1 の API では、パラメータとして別々の値を使用することがよくあります。これは、たとえば、単一のベクトルの x、y、z 値を操作する場合などに適しています。しかし、関数が複数のベクトルまたはベクトル コンポーネントを要求する場合、これは非常に分かりにくいことがあります。より良いアプローチとは、ベクトルのように、意図を明確に説明するオブジェクト内にこれらのパラメータをカプセル化することです。戻り値についても同じです。

API バージョン 1 では、戻り値がベクトルのコンポーネントである場合、単一の値または値のリストを返す関数が示されます。開発者は、この戻り値のリストの意味を理解するために、関数の戻り値のタイプを知っておく必要があります。ベクトルのような単一のオブジェクトを返す場合、これは次のように即座に認識できます。

API バージョン 1 の別の欠点は、Python 2.7 に基づいていることです。Python 2.7 が不良なリリースであるというわけではありませんが、Python 3 では、完全に静的に型付けされた API を非常に簡単に提供できるようになりました。動的型付けにも良い点はありますが、静的な型を使用すれば一貫性のある API をより簡単に構築できます。

個人的には、API バージョン 2 では多くの改善が行われたと思います。まず、VRED との対話の主要なゲートウェイとして動作するいくつかの特殊なサービス クラスが導入されました。vrNodeServicevrSessionService などのサービスは、その特定のトピックのすべての機能を組み合わせたものです。たとえば、セッション サービスには、コラボレーション セッションを管理する関数が含まれています。カメラ サービスを使用すると、カメラとビューポイントを管理できます。これにより、正しい機能が見つけやすくなります。これは、たとえば、カメラに関連するすべての機能が vrCameraService に配置され、新しいカメラ タイプは vrdCameraNodevrdCameraBaseNode で識別できるようになったためです。

新しい API では、データの一部の機能をカプセル化する一連のデータ タイプが導入されました。これらの新しいタイプには、すべて「vrd」というプレフィックスが付きます。先ほど説明したとおり、たとえば vrdCameraNode には、シーン内のカメラに関するすべての情報が含まれています。同様に、vrdSessionUser タイプのオブジェクトは、コラボレーション セッションでの特定のユーザに関するすべての情報を保持します。

新しいタイプにはそれぞれ、オブジェクトのデータを追加または変更する関数が含まれています。そのため、焦点距離など、カメラの設定を変更する場合は、最初に vrdCameraNode から vrCameraService タイプのオブジェクトを取得し、次に setFocalLength 関数を使用して設定を変更します。VRED には、あらゆる種類のデータに対応する新しいタイプが多数用意されていますが、ここでは詳細な説明はしません。たとえば、シーン内のポイント光源を操作するために必要な機能を正確に提供する vrdPointLightNode などがあります。

もう 1 つの利点は、新しい API バージョン 2 に付属する他のサポート データ タイプの範囲です。ベクトル データ タイプについては既に説明しました。これらは、ベクトルとして明確にラベル付けされている個別の数値を組み合わせます。これにより、コードがより読みやすく、また理解しやすくなります。開発者は、この関数がベクトルを入力として要求し、別の関数がベクトルを返すことを即座に理解します。もう 1 つの優れた点は、これらの新しいデータ タイプには数値演算が含まれていて、直感的に作業できることです。では、いくつかのサンプルを見てみましょう。

まず、新しいサービスの基本的な使用法を示します。実際に、これらを使用する際に難しいことはありません。このサンプルでは、vrCameraService を使用してカメラを操作する方法を確認します。最初に、シーン内に新しいカメラを作成します。createCamera の関数 vrCameraService を使用して名前を付けます。この関数の戻り値は、変数に割り当てる vrdCameraNode です。

これで、このカメラ ノード オブジェクトを使用して新しいカメラ トラックを作成できるようになります。これは、vrCameraService および関数 createCameraTrack でも行われます。今回は、戻り値は変数にも格納される vrdCameraTrack オブジェクトです。

これをさらに発展させて、このカメラ トラックに新しいビューポイントを作成することができます。必要なのは、「camera service」の createViewpoint 関数を使用し、カメラ トラック オブジェクトを入力パラメータとして使用することだけです。カメラ エディタを見ると、作成したすべてのオブジェクトを確認できます。

次のサンプルでは、シーン内に光源をいくつか作成します。ここでも、vrLightService およびその関数 createLight を使用できます。今回は、入力パラメータとして名前とライトのタイプを指定する必要があります。

API バージョン 2 には、いくつかのタイプを含むクラスも含まれています。この場合は、vrLightType のポイントライトが必要です。これらのタイプと、このビデオで先ほど説明したデータ タイプを混同しないでください。新しい API 内の「type」で終わるすべてのクラスは、一連の異なる要素(すなわちタイプ)を定義します。たとえば、ライトのタイプは、ポイントライト、スポットライト、指向性ライトなどです。このタイプでは、作成するライトのタイプをライト サービスに伝えることができます。

カメラのサンプルでは、既に新しい「vred オブジェクト」のいくつかについて確認しました。このサンプルに戻ると、カメラ サービスを使用して新しいオブジェクトを作成できるだけでなく、カメラ、カメラ トラック、および作成したビューポイントも変更できます。

最初に、カメラの位置を変更します。カメラの位置、カメラの視点、シーン内で「上」になる位置を示す方向を定義することで、これを行うことができます。これらの値は、定義したベクトルを提供する fromAtUp データ タイプを使用して設定します。これにより、カメラの照準がシーンの中心に合わせられます。その後、カメラをアクティブにすると、結果をただちに表示できます。

もちろん、他のオブジェクトも同様の方法で変更できます。たとえば、関数 createPreview() を使用してビューポイントのプレビューを更新できます。これにより、現在のシーンからビューポイントの新しいプレビューが作成されます。

最後のサンプルでは、新しいデータ タイプによって、いかに簡単に作業を行えるようになるかを説明します。今後のビデオでさらに詳細なチュートリアルを用意しているので、ここでは詳しく説明しません。新しいベクトル タイプを使用してベクトル コンポーネントをカプセル化し、スクリプト全体を読みやすく、また短くする方法に注目してください。

右側では、いくつかのジオメトリを作成し、3D 空間でその位置を設定します。左側には、API バージョン 1 の関数を使用してスクリプト化された同じサンプルがあります。少なくとも私には、より読みやすく、理解しやすいものになっています。また、ベクトル タイプの数値演算を使用して、スクリプトをさらに短くすることもできます。

ドキュメントに関する最後の注意事項です。ドキュメントでは、バージョン 2 で置き換えられたバージョン 1 のすべての関数を確認できます。これらの関数は「廃止予定」となっています。つまり、これらは現在も使用可能ですが、将来削除されるか、置き換えられる可能性があります。

たとえば、バージョン 2 では、vrCamera に含まれるほぼすべての関数が、vrCameraServicevrdCameraNode、または vrdCameraBaseNode に含まれる関数に置き換えられました。新しいスクリプトを作成する場合は、廃止予定の関数を使用しないでください。これらはまだ機能しますが、新しい API を使用する方が安全です。ページの上部を見ると、この機能を含むバージョン 2 のクラスを指すリンクもあります。

API バージョン 2 において、オートデスクは VRED の Python インタフェースに新しい画期的な変更を導入しました。スクリプトの記述に慣れている場合は、新しいクラスとデータ タイプを使用しても問題はありません。これからスタートする場合にどこを開始点としたらよいかについてご覧いただきました。今日の説明はこれで終わりです。この動画を楽しんでいただけたことを祈ります。また次回、お会いしましょう。


Python サンプル コード

これは、「チュートリアル 6: サービスとオブジェクトを使用して V2 インタフェースを操作する方法」ビデオに付属する Python サンプル スクリプトです。

ヒント:

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

camera.py

import math

# Example 1.0
# Get active camera with vrCameraService
camera = vrCameraService.getActiveCamera()

# Set Focal Length
camera.setFocalLength(35)


# Example 2.0
# Creating a camera using API v1 and settings its fov to 35
vrCamera.selectCamera("Perspective")
camera_v1 = vrCamera.getActiveCameraNode()

# read field of view mode (0 := vertical, 1 := horizontal)
fov_mode = camera_v1.fields().getUInt32("fovMode")
sensor_size = camera_v1.fields().getVec("sensorSize", 2)

# calculate fov based on sensor size
fov = vrOSGWidget.getFov()
focal_length = 35

if fov_mode is 0:
    fov = 2 * math.degrees(math.atan((sensor_size[1] / 2) / focal_length))
else:
    fov = 2 * math.degrees(math.atan((sensor_size[0] / 2) / focal_length))

vrOSGWidget.setFov(fov)


# Example 3.0
# Creating a camera using API v2 and calculating the fov manually
camera_v2_1 = vrCameraService.createCamera("Camera v2_1")

# read field of view mode (vertical or horizontal)
fov_mode = camera_v2_1.getFovMode()

# read sensor size as QtVector2D
sensor_size = camera_v2_1.getSensorSize()

# calculate fov based on sensor size
fov = camera_v2_1.getFov()
focal_length = 50

if fov_mode is vrCameraTypes.FovMode.Vertical:
    fov = 2 * math.degrees(math.atan((sensor_size.y() / 2) / focal_length))
else:
    fov = 2 * math.degrees(math.atan((sensor_size.x() / 2) / focal_length))

camera_v2_1.setFov(fov)

light.py

# Example 1

# Get vrdPointLightNode with the vrLightService
myPointLight = vrLightService.findLight("MyPointLight")

# Set the ground shadow intensity
myPointLight.setGroundShadowIntensity(0.5)

service.py

#Example 1

# Get the active camera from the camera service
camera = vrCameraService.createCamera("My New Camera")

# Create a new camera track on the camera object
cameraTrack = vrCameraService.createCameraTrack("My New Camera Track", camera)

# Create a new viewpoint on the camera track
viewpoint = vrCameraService.createViewpoint("My New Viewpoint", cameraTrack)


#Example 2

# Create a new pointlight with the vrLightService
newPointLight = vrLightService.createLight(
                    "My New PointLight",
                    vrLightTypes.LightType.Point
                )

# Set the translation of this pointlight                               
newPointLight.setTranslation(QVector3D(0,0,1000))


#Example 3

# Create a new camera with the vrCameraService
camera = vrCameraService.createCamera("New Camera")

# Create vectors that define the location and look-at point of the camera
cameraFrom = QVector3D(5000, 8000, 3000)
cameraAt = QVector3D(0, 0, 0)
cameraUp = QVector3D(0, 0, 1)

# Set the camera parameters
fromAtUp = vrCameraFromAtUp(cameraFrom, cameraAt, cameraUp)
camera.setFromAtUp(fromAtUp)

# Activate the camera
camera.activate()


# Create a new camera track on the camera object
cameraTrack = vrCameraService.createCameraTrack("My New Camera Track", camera)

# Create a new viewpoint on the camera track
viewpoint = vrCameraService.createViewpoint("My New Viewpoint", cameraTrack)

viewpoint.createPreview(True)