PythonからのSpringhead API使用法

PythonからSpringhead APIを呼び出す際の詳細な方法といくつかの注意点について解説します.

Sprモジュールについて

Springheadの全クラスはSprモジュールにパッケージされています.

import Spr

を行うことで使用可能となります(Springheadアプリケーションに組み込む場合はEPLoopInitの中でインポートを実行します).

Springheadに関連するクラスは全てSprモジュールの直下に定義されます.Springheadのインタフェースクラスはクラス名からIfを取ったもの(*****If*****),ベクトルやクォータニオン等はそのままのクラス名で定義されています.

現時点では,すべてのSpringheadクラスがPythonからの利用に対応しているわけではありません.Pythonから利用できるSpringheadクラスは,dir関数で確認できます.

>>> import Spr
>>> dir(Spr)

オブジェクトの生成

C++でSpringheadを利用する場合と同様,まずはSdkを作成する必要があります.Sdkを作成するには,PHSdkクラスのインスタンスからCreateSdkを呼び出す必要があります.

phSdk = Spr.PHSdk().CreateSdk()
grSdk = Spr.GRSdk().CreateSdk()
# ... etc.

シーンのCreateはSpringhead同様sdkのインスタンスから行います.

phScene = phSdk.CreateScene(Spr.PHSceneDesc())
grScene = grSdk.CreateScene(Spr.GRSceneDesc())
# ... etc.

IfInfo,自動ダウンキャスト

オブジェクトをCreateするAPIの中には,引き渡すディスクリプタの型によって生成するオブジェクトの種類を判別するものがあります.例えばPHScene::CreateJointは,PHHingeJointDescを渡すとヒンジジョイントを生成し,PHBallJointDescを渡すとボールジョイントを生成します.

これらのCreate関数をPythonから利用する場合,ディスクリプタの型を判別する機能は現時点では用意されていないため,生成したいオブジェクトの型に対応するIfInfoオブジェクトを同時に引数に渡します.

# Hinge
phScene.CreateJoint(so1,so2, Spr.PHHingeJoint.GetIfInfoStatic(), desc)

# Ball
phScene.CreateJoint(so1,so2, Spr.PHBallJoint.GetIfInfoStatic(),  desc)

IfInfoオブジェクトはクラス名.GetIfInfoStatic()で取得することができます.

より正確には,ディスクリプタ型によって返すオブジェクトを変えるようなCreate関数は,以下のようにAPIヘッダファイルにおいてテンプレートを用いて記述されています.Python APIでは,非テンプレート版のCreate関数のみがポートされているため,IfInfo* ii に相当する引数が必要になります.

// in SprPHScene.h
PHJointIf* CreateJoint(PHSolidIf* lhs, PHSolidIf* rhs,
  const IfInfo* ii, const PHJointDesc& desc);

template <class T> PHJointIf* CreateJoint
(PHSolidIf* lhs, PHSolidIf* rhs, const T& desc){
  return CreateJoint(lhs, rhs, T::GetIfInfo(), desc);
}

なお,複数種類のクラスのオブジェクトを返しうるAPI関数の場合,C++では共通するスーパークラス(関節ならPHJointIfなど)が返るため自分でDCAST等を用いてダウンキャストする必要がありますが,Pythonにおいてははじめから個々のクラス(PHHingeJoint, PHBallJointなど)の型情報を持つように自動的にダウンキャストされたものが返されます.よって,ユーザが意識してダウンキャストする必要はありません.

enumの扱い

PHSceneIf::SetContactModeのように,enum型を引数にとる関数があります. 残念ながら,現時点ではenumの定義はPythonへポートされていません.これらの関数を呼び出す場合は,対応する整数値を渡してください.

# C++での phScene->SetContactMode(so1, so2, PHSceneDesc::MODE_NONE) と同じ
phScene.SetContactMode(so1, so2, 0)

ベクトル,ポーズ

Vec3dQuaterniondPosed等はSpringheadと同じクラス名で使用できます. 各要素は .x .y 等のプロパティによりアクセスでき,値の変更も可能です.

>>> v = Spr.Vec3d(1,2,3)
>>> v
(1.000,2.000,3.000)
>>> v.x
1.0
>>> v.x = 4.0
>>> v
(4.000,2.000,3.000)

Posed, Posefについては,w, x, y, zプロパティがクォータニオン成分,px, py, pzプロパティがベクトル成分へのアクセスとなります. また,Posed::Pos(), Posed::Ori()に対応する関数として

が用意されています.