my funeral week

少しでも日々の生活に変化を。

SoftimageとXSIと

Softimageというソフトを覚えているでしょうか?
昔からの利用者はXSIという名称の方がなじみ深いかもしれませんね。

f:id:garysfirearms108:20181211232748p:plain:w400

かつてカナダで生まれ、XSI という名で優秀な3DCG制作ツールとして一世を風靡しました。
ある日、Autodesk社に取り込まれ、その名をXSIの開発会社と同名の Softimage に改名させられた後、2015年にその短い生を終えました。
今でも使われている例は存在するようですが、現在はどれだけのお金を積まれても、新規でのライセンス購入は出来なくなりました 。完全に消えてしまう日も遠くはないでしょう。


私が初めて触った本格的な制作ツールが、XSI7.5でした。
当時17歳。参考書を読み漁り、ただひたすらにモデリングを勉強していたのを覚えています。
就職してからもしばらくの間はSoftimageを利用していましたが、いつの間にかMayaばかりを使い・・・いつしかSoftimageのことも忘れかかっていました。

最近ふと昔のことを思い出したので、今日は彼らの冥福を祈っていくつかの基本的なスクリプトコマンドを紹介します。

※残念ながら全てPythonを利用しています。


Commands


xsi = Application # XSIのメインクラス(で名称は合っているのか?)

Softimageの多くのコマンドはこのオブジェクトからCallされます。
Pymelでいうところの

import pymel.core as pm

のようなものです。


プリミティブ

null = xsi.GetPrim("Null") # Nullを作成
sphere = xsi.GetPrim("Sphere") # インプリシットジオメトリの球を作成
cube = xsi.GetPrim("Cube") # インプリシットジオメトリの四角形を作成

xsi.DeleteObj(null) # ノードを削除

プリミティブの作成。
Mayaで言うところのLocatorも、SoftimageではNullと呼んでいました。

インプリシットジオメトリという、NullでもなくNurbsCurveでもないプリミティブもありましたね。
私はこのノードの正しい利用方法を理解していません。一体どれくらいの方が利用していたのでしょうか?


ノード選択

selection = xsi.Selection() # 選択中のノード

xsi.SelectObj(xsiObjects) # 任意のノードを選択
xsi.AddToSelection(xsiObjects) # Selectionに任意のノードを追加

ノード の選択関連のコマンド類です。字面を見れば詳細は説明不要でしょう。

一点注意、xsi.Selection はノードの配列が返ってくるわけではなく、Selectionというオブジェクト が返ってきます。Softimageのスクリプティングには、このような独自の?コレクションオブジェクトを返すものが多々ありました。

selection = xsi.Selection() # Selection

selection.Add(xsiObject) # 任意のノードを選択に追加
selection.Remove(xsiObject) # 任意のノードを選択から除去
selection.Item(xsiObject) # 選択から任意のノードを検索
selection.Count # 選択しているノード数
selection.Clear() # 選択をクリア

※Softimageにおいてシーン内に存在するものは オブジェクト と呼称しますが、スクリプト側のオブジェクトとややこしいので、ここでは ノード と呼びます。
ちなみに3Dノードは、X3DObjectというオブジェクトを継承しています。


名前

xsiObject.Name # ノードの名前
xsiObject.FullName # ノードのフルネーム

xsiObject.Name = "NewName" # リネーム

名前関連。どちらもプロパティで、取得と設定が可能です。

FullNameでは親の名前込みで返すはずなのですが、なんか思った内容が返って来ないことが多々あります。きっとなんか使い方があるのでしょうけど、よく分かりません・・・。
Softimageでは、例え階層が異なっていたとしても シーン内に同名のノードが存在することが許されませんでした。 Nameの取得でもユニークなものが返って来るはずなので問題ないと思います。


グループ

group = xsi.CreateGroup("groupName", xsiObjects) # グループを作成。Groupオブジェクトを返す
group.AddMember(xsiObjects) # メンバー追加
group.RemoveMember(xsiObjects) # メンバー除名処分

xsi.SelectMembers(xsiGroup) # グループメンバーの選択。
member = xsi.SelectMembers(xsiGroup, False) # 選択を行わず、メンバーのリストだけを返す。

グループの作成関連のコマンドです。MayaでいうSetみたいなものですかね。
SelectMembersの第二引数は、AffectSelectionList といいます。


親子

xsi.ParentObj(parent, children) # 任意の親子関係を作成
xsi.CutObj(children) # 子供をシーンルートの子供にする(親子付け解除の意)

xsiObject.FindChild("SweetChild") # 任意の子供を捜す
xsiObject.FindChildren("OhMine") # 任意の子供をすべて捜す

親子付けを制御します。
基本的にはどんなノードもSceneRootというノードの子供になります。
Find系のメソッドにて目的の物が見つからなかった場合は None を返しますが、引数に何も与えないと、自分の子供を返します。 Childなら一番最初の子供を、Childrenなら全ての子供を返します。


キネマティクス

kinematics = xsiObject.Kinematics # キネマティクスにアクセス
localParameters = kinematics.Local.Parameters # ローカルパラメータにアクセス

positionX = parameter("posx").Value # translate X の値を取得
parameter("posx").Value = 5.0 # translate X に値をセット

トランスフォーム関連の操作を行うなら、必ず通るであろうキネマティクス
2行目の Local はローカル座標のことです。Global ならばワールド座標になります。

文字列からキネマティクスにアクセスを行う場合は以下のようになります。

positionX = xsi.GetValue("xsiObject.kine.local.posx") # 値取得
xsi.SetValue("xsiObject.kine.local.posx", 10.0) # 値の設定


コンストレイン

xsi.ApplyCns("Position", destination, source) # 位置コンストレイントを追加
xsi.ApplyCns("Orientation", destination, source) # 回転コンストレイントを追加

kinematics = xsiObjectA.Kinematics
kinematics.AddConstraint("Position", xsiObjectB) # これも位置コンストレイント追加

constraint = xsiObject.Kinematics.Constraints # コンストレイントにアクセス
posConstraint = "xsiObject.kine.poscns" # 位置コンストレイントにアクセス

xsi.SelectConstrainingObjects(xsiObjects) # 被コンストレイントノードからソースノードを選択

Mayaのように手軽にアトリビュートの接続が出来なかったSoftimageでは、このようなコンストレイントが多用されていました。Mayaでもその名残かコンストレイントを愛用する方々がおられますが、いたずらに処理が重くなるので出来るだけアトリビュートの接続で済ませられればいいですね。


アニメーション

parameters = ["xsiObject.kine.local.posx","xsiObject.kine.local.posy","xsiObject.kine.local.posz"]

xsi.SaveKey(parameters, 10, 50.0) # 10Fに50.0の値のキーを打つ
xsi.RemoveAnimation(parameters) # アニメーションを削除

minFrame = xsi.GetValue("Playcontrol.In")
maxFrame = xsi.GetValue("Playcontrol.Out")

xsi.PlotAndApplyAction(xsiObject, parameters, minFrame, maxFrame) # アニメーションをベイク

Softimageは一度キーフレームを打ってしまうと、キーを全て除去した状態でも アニメーションの除去 という操作を行わない限り、アニメーション有という扱いなるのが独特な仕様でしたね。

強力なアニメーションミキサー機能があったのも懐かしいです。Mayaにも似たようなものがありますが、Softimageのようなかゆいところに手が届くという機能がないのが残念です。



最後にSDKリファレンスのリンクを載せます。このリンク先は2012年度版のものですが、最新の2015年度版でも内容にほとんど差がないので問題はないかと思われます。 精力的に開発が行われていなかったのでしょうか? 思えばこの頃から彼は消える運命だったのでしょう。

Autodesk Softimage 2012 SDK ドキュメント

2018年現在、まだAutodeskさんのHPにてこれらのSDKガイドがダウンロードできるようになっています。
今後もSoftimageを使い続けたいという方は、ダウンロードをお忘れなく。

アーメン。