« 実際にユーザスクリプトをチョロッと | トップページ | 選択された複数のオブジェクトを処理 »

スクリプトマネージャの「メニューの状態」

今回の実験は、スクリプトマネージャのメニューの状態

「メニュー状態のテスト」で新規作成する。
ユーザスクリプトを新規で作成すると必ずデフォルトで

ENABLE=TRUE;

と入力済みになっています。なんだか定数に定数を代入しているみたいだけど、メニューアイテムのプロパティENABLEにTRUE/FALSEの値を設定するんだろう。
一々プラグインメニューのユーザスクリプトを選択してメニューがどんな状態かを見るのは面倒なのでアイコンを空いてるパレットにドラッグ&ドロップします。アイコンはわざわざ作成しません。この状態でアイコンは可視化されています。TRUEをFALSEに変更します。

ENABLE=FALSE;

これで実行をすると、先ほどドロップしたアイコンが不可視化になりました。もちろんメニュー上でも不可視化になっています。
ここで、シーンに適当に数種類のオブジェクトを追加します。

Objectmanager

こんな具合に追加しました。ではポリゴンオブジェクトが1個だけ選択された時にアイコンが可視化されるようにしてみよう。「メニューの状態」に次のように打ち込みます。

ENABLE = instanceof(op , PolygonObject);

instanceof()関数はclass系関数で第1引数で渡された変数のクラス型と第2引数で指定したクラス型を比較して同じでるか否かでTRUE/FALSEを返す関数。
これで実行してみよう。何も選択されていなければ不可視の状態。ではポリゴンオブジェクトを選択してください、可視化されます。他のオブジェクトを選択すると不可視化されます。これで指定したクラス限定で使うツールを作れます。ただしこれはあくまでも1個のみの選択です。
今いきなりinstanceof()関数に変数opを使いましたが、実は詳しいことはわかりません。使えるかどうか試したら使えたので問題ないでしょう。いい加減でごめんなさいね。おっ、今気づいたけどメニューの状態にopのみ渡されると思っていたけど、docも引き渡されています。これでGetActiveDocument()関数を使わなくてもアクティブドキュメントが得られるわけですね。しかも実行ボタンを押さなくても「メニューの状態」は常時(イベントが起きた時)実行されるようです。
ではポリゴンオブジェクト以外の球体の場合なら

ENABLE = instanceof(op , SphereObject);

クラスなので継承と派生の関係があります。スプラインとポリゴンはPointObjectクラスの派生なのでPointObjectを指定すると、スプラインとポリゴンオブジェクトが有効になります。球体、立方体、円柱等は、PrimitiveObjectクラスの派生なのでプリミティブ全般で指定できます。多分よく使うのがPointObject/PolygonObject/SplineObjectかなぁ。
主なオブジェクトクラス

ポイントオブジェクト PointObject
ポリゴンオブジェクト PolygonObject
スプラインオブジェクト SplineObject

プリミティブオブジェクト  PrimitiveObject

立方体 CubeObject
球体 SphereObject
円錐 ConeObject
円柱 CylinderObject
ポリゴン SinglePolyObject
平面 PlaneObject
ディスク DiscObject
ピラミッド PyramidObject
カプセル CapsuleObject
オイルタンク OiltankObject
正多面体 PlatonicObject
トーラス TorusObject
チューブ TubeObject
地形 FractalObject
フィギュア FigureObject
レリーフ ReliefObject

スプラインプリミティブオブジェクト  SplinePrimitiveObject

円形 SplineCircleObject
四辺形 Spline4SideObject
歯車 SplineCogwheelObject
らせん SplineHelixObject
数式 SplineFormulaObject
SplineArcObject
多角形 SplineNSideObject
花形 SplineFlowerObject
断面形 SplineProfileObject
疾走線 SplineCissoidObject
長方形 SplineRectangleObject
星型 SplineStarObject
テキスト SplineTextObject
サイクロイド SplineCycloidObject
ベクター化 SplineContourObject

屈曲オブジェクト BendObject
ボーンオブジェクト SinglePolyObject
膨張オブジェクト BulgeObject
爆発オブジェクト ExplosionObject
数式オブジェクト FormulaObject
FFDオブジェクト FFDObject
メルトオブジェクト MeltObject
粉砕オブジェクト ShatterObject
せん断オブジェクト ShearObject
テーパーオブジェクト TaperObject
ツイストオブジェクト TwistObject
風オブジェクト WindDeformObject
ラップオブジェクト WrapObject

ベジェNURBSオブジェクト BezierObject
押し出しNURBSオブジェクト ExtrudeObject
HyperNURBSオブジェクト HyperNURBSObject
回転NURBSオブジェクト LatheObject
ロフトNURBSオブジェクト LoftObject
スイープNURBSオブジェクト SweepObject

背景オブジェクト BackgroundObject
カメラオブジェクト CameraObject
作業平面 ConPlaneObject
環境オブジェクト EnvironmentObject
床オブジェクト FloorObject
前景オブジェクト ForegroundObject
ライトオブジェクト LightObject
空オブジェクト SkyObject
ステージオブジェクト StageObject

配列オブジェクト ArrayObject
ブールオブジェクト BooleObject
インスタンスオブジェクト InstanceObject
メタボールオブジェクト MetaballObject
ヌルオブジェクト NullObject
対称オブジェクト SymmetryObject

引力オブジェクト AttractorObject
反射オブジェクト DeflectorObject
消滅オブジェクト DestructorObject
減速オブジェクト FrictionObject
重力オブジェクト GravitationObject
エミッタオブジェクト ParticleObject
回転オブジェクト RotationObject
タービュランスオブジェクト TurbulenceObject
風オブジェクト WindObject

ステレオマイクオブジェクト HeadphoneObject
ラウンドスピーカーオブジェクト LoudspeakerObject
マイクオブジェクト MicrophoneObject

一応チェックはしましたが、タイプミスがあるかもしれません。
そこで、オブジェクトのクラスを取得する関数があります。これもクラス系の関数でgetclass()です。「クラスの表示」で新規作成し次のコードを入力しました。

/*
オブジェクトクラスの表示

Copyright(c)2008/5/25 村人とC4D
*/

println(op->GetName() , "   " , getclass(op));//オブジェクトの名前とクラスの表示

println()はコンソールに表示する関数です。GetName()はBaseObjectクラスのメンバ関数で、オブジェクトマネージャでのオブジェクトの名前を返します。これでオブジェクトを選択し実行したらコンソールにオブジェクトの名前とクラスを表示します。ただし何も選択しないで実行するとgetclass()関数がエラーを起こします。エラーを起こさせないためにmain()関数内で「何も選択されていなければ処理をしない」とするか、メニューの状態で「何も選択されていなければメニューを不可視化」にする。main()内であれば

if(!op)return;//選択されていなければスクリプトを終了
println(op->GetName() , "   " , getclass(op));

それとも一行で

if(op)println(op->GetName() , "   " , getclass(op));//選択されていれば表示

メニューの状態だと

ENABLE = (op != NULL);

main()関数内でif(op)で選択されたオブジェクトがあるか否かを判定できるのですが、メニューの状態では、

ENABLE = op;

では残念ながら機能しません。確実にTRUE/FALSE(1か0か)でなければならないようです。
で、main()かメニューの状態で処理するかは、メニューの状態で処理したほうが、ツールを使う側には「何も選択されていないとツールが使えない」とわかりやすいですかね。ま、使うために作るので使う側を考慮したほうが良いですかね。ただ、問題なのが「メニューの状態」がC4Dにイベントが発生するたび実行されるので、複雑な「メニューの状態」のコードを書くとレスポンスが悪くなる可能性が出てくるかも知れません。COFFEEの実行スピードは遅いし。まあ、main()と「メニューの状態」と両方で対処するのもありかな?ん?「メニューの状態」はあくまでもメニューの状態だから処理をすか否かはmain()関数かな?グダグダになってきた…
で、このスクリプトは「GetClass.ZIP」です。 さて次は何だろう。

|

« 実際にユーザスクリプトをチョロッと | トップページ | 選択された複数のオブジェクトを処理 »

コメント

この記事へのコメントは終了しました。