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も自動でアクティブにすることができます。
このような感じで便利コマンドを追加していき、かつ、再利用できるようになります。