[Omniverse] 「Set Origin」の紹介/Extensionでコマンドを追加

  • by

OmniverseのExtensionとして「Set Origin」という機能を追加してみました。

https://github.com/ft-lab/Omniverse_extension_SetOrigin

MeshまたはXform(参照含む)のマニピュレータの中心を調整します。
Omniverse Create 2022.1.1で確認しました。

Set OriginのExtensionのインストールは、上記GitHubのreadmeをご参照くださいませ。

Set Originの使い方

DCCツール側でモデリングした際に、マニピュレータ位置を考慮していない場合も多々あるかと思います。
例えば、以下はタイプライタ―をモデリングしてOmniverseにインポートしました。

マニピュレータを表示すると中心位置がずれています(実は説明のために故意にずらしました)。
Stageウィンドウでは、インポート時の参照(Reference)のXformを選択しています。

この中心を、以下の動画のようにジオメトリの中央下に移動させます。

Stageウィンドウで選択したMeshまたはXformに対して機能します。
内部的には、Transformの移動(Translate)とピボット(Pivot)を更新してマニピュレータの中心位置を変更しています。

メインメニューに「Tools」という項目が追加されます。
その中に「Set Origin」、サブメニューで「Center of Geometry」「Lower center of Geometry」が選択できます。

Center of Geometry

選択Mesh、もしくは選択Xform内の形状のバウンディングボックスの中心にマニピュレータを移動させます。

Lower center of Geometry

選択Mesh、もしくは選択Xform内の形状のバウンディングボックスの中央下にマニピュレータを移動させます。

この「Set Origin」は、UNDO/REDOに対応しています。
以降はOmniverseでのPythonプログラムの話になります。

開発 : Extension(Python)でのUNDO/REDO対応

参考 : https://docs.omniverse.nvidia.com/py/kit/source/extensions/omni.kit.commands/docs/index.html

OmniverseのExtensionまたはPythonスクリプトでのUNDO/REDOの対応例を以下にアップしています。
https://github.com/ft-lab/omniverse_sample_scripts/blob/main/Operation/UNDO/CreateSphereUndo.py

以下は球を作成する処理をUNDO/REDO対応する例です。

from pxr import Usd, UsdGeom, UsdPhysics, UsdShade, Sdf, Gf, Tf
import omni.kit.commands
import omni.kit.undo

# Get stage.
stage = omni.usd.get_context().get_stage()

# Process to create a sphere.
class MyCreateSphere (omni.kit.commands.Command):
    _path = ""

    def __init__ (self, path : str):
        self._path = path

    def do (self):
        sphereGeom = UsdGeom.Sphere.Define(stage, self._path)

        # Set radius.
        sphereGeom.CreateRadiusAttr(5.0)

        # Set color.
        sphereGeom.CreateDisplayColorAttr([(1.0, 0.0, 0.0)])

        # Set position.
        UsdGeom.XformCommonAPI(sphereGeom).SetTranslate((0.0, 5.0, 0.0))

    def undo (self):
        stage.RemovePrim(self._path)

# Create sphere.
pathName = '/World/sphere'

# Register a Class and run it.
omni.kit.commands.register(MyCreateSphere)
omni.kit.commands.execute("MyCreateSphere", path=pathName)

「omni.kit.commands.Command」を引数に持つclassを作成し、
「do」に実行する処理、「undo」にdoで実行した処理をUNDOする処理を記述します。
class内に1つの処理をカプセル化します。
「MyCreateSphere」というクラス名としました。
これを「omni.kit.commands.register(MyCreateSphere)」として登録すると、「omni.kit.commands」のコマンドとして追加されます。

「omni.kit.commands.execute("MyCreateSphere", path=pathName)」のように第一引数にコマンド名、第二引数以降に渡すパラメータを指定すると、
そのコマンドを実行します。
UNDO/REDO対応する場合は「omni.kit.commands」に登録することになります。

この「omni.kit.commands」はOmniverseのあらゆる部分で使用されています。

例えば、"MovePrim"を使うと指定のPrim名を変更できます。
以下は"/World/sphere"から"/World/sphereA"に名前変更するコマンドを呼んでいます。

path = "/World/sphere"
newPathName = "/World/sphereA"
omni.kit.commands.execute("MovePrim", path_from=path, path_to=newPathName)

その他、omni.kit.commandsの使用例は以下にいくつかアップしてます。
https://github.com/ft-lab/omniverse_sample_scripts/tree/main/Operation/CommandsExecute

"MovePrim"はOmniverseのコアとして用意されているコマンドですが、前述の"MyCreateSphere"のように自身のExtensionからコマンドを追加することができます。

開発 : Omniverseの基本操作でどのようなコマンドが呼ばれているか知りたい

Omniverse Code(2022.1.0で確認)を使うことで、操作を行った場合のコマンドが
Commandsウィンドウに履歴として表示されます。
[Omniverse] Omniverse Codeでomni.kit.commandsの作法を調べる」もご参照くださいませ。

開発 : "Set Origin"ExtensionでのUNDO/REDO対応

"Set Origin"もUNDO/REDO対応しているため、このExtensionを有効にした場合はコマンドとして実行可能です。

from pxr import Usd, UsdGeom, UsdPhysics, UsdShade, Sdf, Gf, Tf
import omni.kit.commands
import omni.usd

# Get stage.
stage = omni.usd.get_context().get_stage()

path = "/World/sphere"
pos = Gf.Vec3f(0.0, 0.0, 0.0)

# Get prim at path.
target_prim = stage.GetPrimAtPath(path)

omni.kit.commands.execute("ToolSetOrigin",
  prim = target_prim,
  center_position=pos)

「omni.kit.commands.execute」の第一引数に"ToolSetOrigin"を指定します。
primに対象のUsd.Prim、center_positionにワールド座標上の中心にしたい位置を指定します。
ここでのprimは「Mesh」または「Xform」が対象です。
これを実行すると、特定のPrimの中心を指定のワールド座標位置に変更します。
UNDO/REDOにも対応しています。

これにより、汎用機能として"ToolSetOrigin"というコマンドを用意できたことになります。
好きな位置を中心に変更できます。
もちろん、この拡張した機能は他のExtensionやOmniverseのScript Editorでも使用できるようになります。

開発 : Extensionで他のExtensionを有効にするには ?

もし、独自Extensionでこの"ToolSetOrigin"コマンドを呼びたい場合、あらかじめSet OriginのExtensionが起動してほしいです(依存関係を持つ状態)。

その場合は、自身のExtensionのconfig/extension.tomlで

[dependencies]
"ft_lab.Tools.SetOrigin" = {}

のように、SetOriginのパッケージ名を記述するとSetOriginも自動でアクティブにすることができます。

このような感じで便利コマンドを追加していき、かつ、再利用できるようになります。