2016年07月29日

modo10のスクリプトについて調べてみた その5

前回に引き続き「コマンドプラグインキット」で生成した「コマンドプラグイン」のテンプレートについて調べてみたい。

「cmd_Flags()」についてはマニュアルにこうある。

This is a very important part of a command if you are using the Python API (or TD SDK) to edit the scene in the command execution.The command flags tell MODO what the command is expected to do when it executes and how to handle it.

コマンドが何をしてどう扱えばいいかをMODOに伝えるのがこのメソッドの役割らしい。デフォルトの状態で下のようになっていて、

def cmd_Flags(self):
	return lx.symbol.fCMD_UNDO | lx.symbol.fCMD_MODEL

MODOから呼び出された時に値を一つ返す。フラグの値は2進数で、どの桁が1になっているかでどのフラグがONなのかが識別できる。今回は「lx.symbol.fCMD_UNDO」と「lx.symbol.fCMD_MODEL」の2つの値の論理和を「|」演算子でとっていて、生成された値は2つのフラグに対応した2進数の桁が1になる。さらにいろんなフラグを付け加えたいならこれに「|」演算子をつけて追加して行けばいい仕組みだ。

ちなみに「lx.symbol.fCMD_UNDO」の値は100663296で2進数に直すと110000000000000000000000000で、「lx.symbol.fCMD_MODEL」の値は33554432で2進法に直すと10000000000000000000000000だ。だから実は2つの論理和をとっても値は変らない。

110000000000000000000000000
010000000000000000000000000
---------------------------
110000000000000000000000000

「lx.symbol.fCMD_MODEL」はこのコマンドがシーンに影響を及ぼすことを示していて、「lx.symbol.fCMD_UNDO」はこのコマンドがUNDO出来るべきであることを示している。マニュアルによるとこれらのフラグは特別な事が無いかぎりこのままにして置いた方がいいらしい。

「basic_Enable()」はコマンドの有効無効をMODOに伝えるメソッド。これが「True」を返せばコマンドは有効で「False」なら無効。

「cmd_Interact()」はコマンドを起動した時に最初に呼ばれるメソッドで、コマンドがユーザーにファイル名を要求する時にここでファイルダイアログを出したりする処理を書く場所になっている。「コマンドプラグイン」のテンプレートでは何もしないので「pass」が書かれている。

「basic_Execute」はコマンドの実行本体。

「cmd_Query()」は引数の値の問い合わせで呼び出されるメソッド。これを使うためには引数に「fCMDARG_QUERY」フラグを設定する必要がある。「__init__()」をこのように直して、

def __init__(self):
	lxu.command.BasicCommand.__init__(self)
	self.dyna_Add("newName", lx.symbol.sTYPE_STRING)
	self.basic_SetFlags (0, lx.symbol.fCMDARG_QUERY|lx.symbol.fCMDARG_OPTIONAL)

クエリされる引数の番号が「index」に、MODOとのやりとりは「vaQuery」でするようで、「vaQuery」を「ValueArray」オブジェクトにして、そこに値をセットして戻すとコマンドが値を出力する。下の例では引数「newName」に対するクエリの結果として「no name」を返すようにしている。

def cmd_Query(self, index, vaQuery):
	va = lx.object.ValueArray()
	va.set(vaQuery)
	if index == 0:
		va.AddString("no name")
	return lx.result.OK

このように「newName」に対してクエリすると、

fig01

「no name」が出力されているのがわかる。

fig02

引数のタイプにあわせて「AddString()」の部分は変える必要がある。複数引数がある場合は「index」の値で何番目の引数か見極めてそれに対応した型用のメソッドを使って値をセットする。

fig03

それではまた次回。

modo10ブログ目次



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)modo | CG

2016年07月28日

3ds Max 2017の新機能を調べてみた その17 3dsmax 2017

「参照座標系」ドロップダウンメニューに「ローカル位置合わせ」オプションが追加された。

fig01

従来の「ローカル」オプションでは頂点、エッジ、ポリゴンと言ったサブオブジェクトを操作する場合、法線方向をZ軸とするところまでは確定していたが、X軸、Y軸の方向については考慮されていなかった。そのため、X軸とY軸の方向がどの方向を向くかは使ってみないとわからなかった。

下のGIFアニメは「ローカル」でポリゴンを選択してみたところ。選択するポリゴンによって「選択を移動」の軸方向がいきなり反転したりしている。

fig03

「ローカル位置合わせ」は従来の「ローカル」同様、サブオブジェクトの法線方句にZ軸をあわせ、その軸とオブジェクトのローカル座標系のZ軸方向のベクトルとで張る面に含まれるようにY軸を取り、2つの軸に直交する方向にX軸をとるようにする事で3軸を決めるように働く。法線とローカルZ軸が揃った時はローカルX軸にX軸をあわせる。

fig02

下のGIFアニメは「ローカル位置合わせ」を使ってみたもの。X−Y軸の方向が「ローカル」の時のようにいきなり反転したりする事が無く安定して予想しやすい方向を向くようになっている。

fig04

それではまた次回。

maxまとめページ



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)3ds Max | CG

2016年07月27日

modo10のスクリプトについて調べてみた その4

前回に引き続き「コマンドプラグインキット」で生成した「コマンドプラグイン」のテンプレートについて調べてみたい。

前回は「__init__()」に

self.dyna_Add(name, type)

name:コマンド引数の内部名称
type:引数のタイプ

を書き込むことでコマンドに引数を追加出来るというところまで調べた。

この「dyna_Add()」をコマンドに必要なら引数の数だけ「__init__()」に追加するだけでコマンドに引数が追加される。

そして追加された引数は「BasicCommand」クラス内では0から始まる追加順の通し番号で管理される。

例えば下のようになっていた場合、「myBoolean」は0番、「myDistance」は1番といった具合だ。

def __init__(self):
lxu.command.BasicCommand.__init__(self) self.dyna_Add ("myBoolean", lx.symbol.sTYPE_BOOLEAN) self.dyna_Add ("myDistance", lx.symbol.sTYPE_DISTANCE) self.dyna_Add ("myAngle", lx.symbol.sTYPE_ANGLE)

入力された引数から値を読み込むにはその番号を使って、

myBoolean = self.dyna_Bool (0, False)
myDistance = self.dyna_Float (1, 0.0)
myAngle = self.dyna_Float(2, 0.0)

のようにすればいい。値の取得には下の4つのメソッドが使える。indexが登録時の通し番号で、valueはデフォルト値だ。

fig01

引数のタイプはいろいろあったけど、実際記録されるのはInt(整数)、Float(実数)、String(文字列)になる。読み込む時は型にあわせたメソッドを選択する必要がある(ブーリアンは整数として記録されるけど、専用メソッドがあるので、IntとしてもBoolとしても読み込める)。

例えば以前にやった「cmd_cloneItem.py」の2つのメソッドを以下のように書き換えて、

def __init__(self):
   lxu.command.BasicCommand.__init__(self)
	self.dyna_Add("newName", lx.symbol.sTYPE_STRING)

def basic_Execute(self, msg, flags):
   reload(myPythonModule)
	newname=self.dyna_String(0,"")
   myPythonModule.cloneSelectedItems(newname)

「__init__.py」を以下のように書き換えれば、

import modo

def cloneSelectedItems(newname):
	scene = modo.Scene()
	for item in scene.selected:
		duplicate = scene.duplicateItem(item)
	if newname=="":
		duplicate.name = '%s_copy' % item.name
	else:
		duplicate.name = newname

コピーしたアイテムにつける名前を引数に設定出来るようになる。

このように引数をつけてコマンドを呼び出せば、

fig02

コピーされたアイテムの名前を直接指定できる。

fig03

引数を何もつけないで起動すると引数の値を聞くダイアログボックスが出る。

fig04

何も入力しないで「OK」を押すと従来通りアイテムに「_copy」が付いた名前のコピーが出来る。

fig05

このように引数がありながらコマンド起動時に与えない場合、自動的にダイアログボックスが出ちゃうんだけど、下のように引数0番に対して「fCMDARG_OPTIONAL」を設定してやれば、ダイアログを抑制して何も指定が無ければデフォルトの値を使うようにする事も出来る。

def __init__(self):
	lxu.command.BasicCommand.__init__(self)
	self.dyna_Add("newName", lx.symbol.sTYPE_STRING)
	self.basic_SetFlags (0, lx.symbol.fCMDARG_OPTIONAL)

このように何も引数をつけないで起動すると、

fig06

従来通り「_copy」を付けたアイテムが生成される。

fig07

続きはまた次回。

modo10ブログ目次



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)modo | CG

2016年07月26日

3ds Max 2017の新機能を調べてみた その16 3dsmax 2017

前回に引き続き「ブール演算合成オブジェクト」について調べてみたい。

合成オブジェクトのマテリアルは合成先のマテリアルと揃えるかオリジナルのまま使うかを合成する時に選ぶ事が出来る。合成後は変更出来ない。

どちらの方式を採用するかは「オペランドを追加」でベースオブジェクトに新しいオブジェクトを追加する時に「オペランドマテリアルを適用」を選ぶか「元のマテリアルを保持」を選ぶかで選択する。

fig01

「オペランドマテリアルを適用」を選ぶと、追加される「オペランド」オブジェクトに適用されているマテリアルが使われて、「元のマテリアルを保持」を選ぶと「ベース」オブジェクトのマテリアルが「オペランド」オブジェクトに適用される。

例えば下のようにそれぞれ別々のマテリアルが適用されたBOXと球体があって、

fig02

「Box001」を「ベース」オブジェクトとして、そこに「Sphere001」を「オペランド」オブジェクトとして追加する時に

fig03

「オペランドマテリアルを適用」を選んでいると、このように「ベース」オブジェクトに合成された「オペランド」オブジェクトの部分に追加前のマテリアルが適用される。

fig04

「元のマテリアルを保持」を選んで「Sphere001」を追加した場合は「ベース」オブジェクトのマテリアルが割り当てられる。

fig05

マテリアルが変更されるのは追加の時だけなのでこれ以降は割り当て方を変える事はできない。

「オペランドマテリアルを適用」を選んで「オペランド」を追加した場合、1つの「合成」オブジェクトに2つのマテリアルが割り当てられる事になるので、「マルチ/サブオブジェクト」マテリアルに変換されて割り当てられる。

fig06

UVマップがどうなるかもチェックしてみると、合成前の「Box001」のUVマップは下のようになっていて、

fig07

「Sphere001」がこうなっているとすると、

fig08

「差」をとった場合したのような形状になって、

fig12

「ポリゴンを編集」を追加してから「UVWアンラップ」を追加してUVマップを表示させてみると、

fig11

当然の結果と言うか、2枚のUVマップが1つのマップになって、合成によって削除された部分はUVマップからも取り除かれている。

fig13

「表示」オプションは「オペランド」の表示をコントロールする。

fig14

デフォルトの状態でこのオプションは「結果」になっていて、合成後のオブジェクトがビューポートに表示される。

「オペランド」を選択すると、合成結果と共に合成前の「オペランド」がワイヤーフレームで表示される。

fig15

「シェーディング」をONにするとワイヤーフレームで表示されていた「オペランド」がシェーディングされて表示されるようになる。

fig16

「選択されたオペランド」を選ぶと、合成結果と共に選択された「オペランド」がワイヤーフレームで表示される。これも「シェーディング」をONにする事で個別にワイヤーフレーム表示とシェーディング表示を切り替えられる。

fig17

表示されたオペランドはクリックして選択出来るので、合成で見えなくなったオペランドの位置を変更したりする時に便利だ。

さらに合成操作について表で一括操作するための「ブール演算エクスプローラ」がある。これを起動するには「ブール演算エクスプローラを開く」ボタンを押す。

fig18

見てわかる通り今まで調べてきたマテリアル以外の操作が表の項目になっているのがわかる。

fig19

そして「仕様不能にする」のチェックをONにすると、

fig20

「オペランド」リストで該当するオブジェクトの目のアイコンがOFFになって、

fig21

そのオブジェクトの影響が結果から除外される。ここで目のアイコンOFFに出来るのか・・・。なんでリストで出来ないのかなぁ。

fig22

それではまた次回。

maxまとめページ



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)3ds Max | CG

2016年07月25日

modo10のスクリプトについて調べてみた その3

前回「コマンドプラグインキット」で生成した「コマンドプラグイン」のテンプレートについて今回は調べてみたい。

新たにコマンドプラグインを生成すると下のような「コマンドプラグイン」の骨組みとなるコードが生成される。

fig03

最初の「import」文はこのテンプレートで使用するモジュールをインポートするためのものだ。

次のクラス定義がこの「コマンドプラグイン」を定義するもので、まず最初にこのクラス名を変更してこのプラグイン特有の名前にする必要がある。前回の例では「CmdCloneItem」にしていた。

そして定義したクラスは一番下の行の「lx.bless」によってmodoから実際使うコマンド名を付けて登録される。だからこの行の「CmdMyCustomCommand」の部分を上で変更したクラス名に、「replace.me」の部分を追加したいコマンド名に変更する。

前回の例では

lx.bless(CmdCloneItem, "item.clone")

としてコマンド名は「item.clone」になった。

定義するクラスは「lxu.command.BasicCommand」クラスを継承している。このクラスが「コマンドプラグイン」を作る時のテンプレートになっていて、継承したクラスでこれに肉付けをすることで「コマンドプラグイン」を作る仕組みになっている。

それが「__init__()」「cmd_Flags()」「basic_Enable()」「cmd_Interact()」「basic_Execute」「cmd_Query()」のメソッド定義だ。これらはコマンド実行時の特定の状況の時に呼び出されるメソッドだ。これらの中にプログラムを書き込んでおけばコマンドが実行される時に自動的に呼び出される仕組みだ。

「__init__()」はプラグインを初期化する時に呼び出される。

def __init__(self):
  lxu.command.BasicCommand.__init__(self)

この初期化ではまず最初にこのクラスの継承元の「lxu.command.BasicCommand」の初期化をする必要があるので、

lxu.command.BasicCommand.__init__(self)

が追加されている。初期化のプログラムを追加する場合はこの後に続けて書くことになる。

例えばこのコマンドで使う引数があればここで追加する事になる。

引数を追加するメソッドは「dyna_Add()」だ。

self.dyna_Add(name, type)

name:コマンド引数の内部名称
type:引数のタイプ

例えば

self.dyna_Add (
 "mydistance", lx.symbol.sTYPE_DISTANCE)

とすれば「mydistance」という名前で距離タイプの引数が追加される。

「lx.symbol」クラスはシンボルの定義リストが収められていて、「sTYPE_〜」がつくものは引数タイプとして使えるものらしい。「Pythonエディタ」で調べてみると、下のように値は「'distance'」などの文字列になっているようだ。

fig04

だから「lx.symbol.sTYPE_DISTANCE」の部分を「'distance'」と置き換えても同じ動作をする。ただしこの名前を覚えなきゃならないけどね。クラスでまとめてあれば、「Pythonエディタ」から「Tab」キーで一覧が呼び出せる。

fig05

前回の「cmd_cloneItem.py」の「__init__()」メソッドの定義を編集して、

def __init__(self):
	lxu.command.BasicCommand.__init__ (self)
	self.dyna_Add ("myDistance", lx.symbol.sTYPE_DISTANCE)

とすると、コマンドを実行した時に引数を与えなければ下のようにダイアログボックスを表示してパラメータを尋ねてくるようになる。

fig06

続きはまた次回。
土曜日明け方からお店に並んでPSVRをようやくゲット。
疲れた・・・orz
まだPS4も持って無いんだけどねw10月が楽しみだ。

modo10ブログ目次



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)modo | CG
Archives