
次のセクションでは、カスタム エバリュエータを定義する新しい API クラスおよびメソッドについて説明します。カスタム エバリュエータを使用すると、Maya シーンの計算方法をコントロールできます。
カスタム エバリュエータを作成する場合は、MPxCustomEvaluator クラスを拡張するプラグインを定義する必要があります。次に、オーバーライドする必要がある主要クラスのメソッドを示します。
新しいエバリュエータを使用するには、事前に登録しておく必要があります。
MStatus registerEvaluator(
// name of the evaluator
const char * evaluatorName,
// evaluator priority. Higher priority evaluators get 'first-dibs'
unsigned int uniquePriority,
// function pointer to method returning a new evaluator instance
MCreatorFunction creatorFunction
)次に、登録解除方法を示します。
MStatus deregisterEvaluator(
// name of the evaluator
const char* evaluatorName
)MFnPlugin メソッドを使用します。これらの関数は、プラグインインの初期化中に使用する必要があります。
MStatus initializePlugin( MObject obj )
{
MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");
MStatus status = plugin.registerEvaluator(
"SimpleValuator",
40 /* unused priority */,
simpleEvaluator::creator);
if (!status)
status.perror("registerEvaluator");
return status;
}初期化解除については、次のとおりです。
MStatus uninitializePlugin( MObject obj)
{
MFnPlugin plugin( obj );
MStatus status = plugin.deregisterEvaluator( "SimpleValuator" );
if (!status)
status.perror("deRegisterEvaluator");
return status;
}(上図を参照)
プラグインがロードされると、Python コマンドまたは MEL コマンドを使用して有効にすることができます。
import maya.cmds as cmds
cmds.evaluator(enable=True, name='SimpleEvaluator')
# Result: False #無効にする方法は、次のとおりです。
cmds.evaluator(enable=False, name='SimpleEvaluator')
# Result: True # エバリュエータに関する情報を照会する方法は、次のとおりです。
print cmds.evaluator(query=True)
[u'dynamics', ... u'SimpleEvaluator']注: エバリュエータ コマンドは、エバリュエータの前の状態を返します。エバリュエータを有効にできない場合、このコマンドは失敗します。このコマンドの詳細については、Maya ヘルプの「テクニカル ドキュメント」セクションを参照してください。**
ロードされたすべてのエバリュエータの優先順位を表示するには、evaluator コマンドで priority フラグを使用します。
for evaluatorName in cmds.evaluator():
print "%-25s : %d" % (
evaluatorName,
cmds.evaluator(name=evaluatorName, query=True, priority=True))
dynamics : 103000
ikSystem : 102000
timeEditorCurveEvaluator : 101000
disabling : 100000
GPUOverride : 5000
transformFlattening : 3000
reference : 1000
SimpleValuator : 40このセクションでは、さまざまな MPxCustomEvaluator API メソッドの詳細について説明します。
EG の分割時、各エバリュエータは次のメソッドを使用してエバリュエータ ノードを要求できます。
bool MPxCustomEvaluator::markIfSupported(const MEvaluationNode* node) この呼び出し内で評価を行っても問題ありませんが、分割が増大し、評価時間が長くなります。評価が必要かどうか(.outputValue/.outputArrayValue を呼び出すかどうか)、または以前に評価されたデータブロックの値を再利用できるかどうか(.inputValue/.inputArrayValue を呼び出すかどうか)の決定は、開発者が行います。複数のエバリュエータが特定のノードをマークしている場合、優先順位により、ノードに割り当てるエバリュエータが実行時に決定されます。たとえば、A と B という 2 つのエバリュエータがあり、ノード C が対象ノードとしてマークされている場合、エバリュエータ A に優先順位 100、エバリュエータ B に優先順位 10 を設定すると、エバリュエータ A にノード C を含むクラスタが割り当てられます。
エバリュエータでクラスタを並列に評価できるかどうかを判断するには、以下を使用します。
MCustomEvaluatorClusterNode::SchedulingType schedulingType(
// a disjoint set of nodes on a custom evaluator layer
const MCustomEvaluatorClusterNode * cluster
)ここで、
| スケジュール タイプ | 詳細 |
|---|---|
| kParallel | 同じタイプの任意の個数のノードを並列に実行できる |
| kSerial | このタイプのすべてのノードを順番に連結し、実行する必要がある |
| kGloballySerial | このタイプのノードは一度に 1 つのみ実行できる |
| kUntrusted | 何が起きるか予測できないため、このノードでは他に何も実行できない |
EG のスケジュール中:
bool MPxCustomEvaluator::clusterInitialize(
const MCustomEvaluatorClusterNode* cluster // evaluation cluster node
)必要なクラスタ準備を行うのに使用できます。クラスタのポインタは、シーン トポロジが変更されるなど、グラフが無効になるまで有効であり続けます。
クラスタを削除する前に、次を呼び出すと、
void MPxCustomEvaluator::clusterTerminate(
const MCustomEvaluatorClusterNode* cluster // the cluster to terminate
)エバリュエータ固有のリソースをリリースするなど、必要なクリーンアップを実行できます。内部表現をクリアする必要があるかどうかは、カスタム エバリュエータが決定します。
実行時に使用されるメイン メソッドは 3 つあります。
グラフを実行する前、EM は以下を呼び出します。
void MPxCustomEvaluator::preEvaluate(
const MEvaluationGraph* graph // the graph about to be evaluated
)実行中、EM は以下を呼び出します。
void MPxCustomEvaluator::clusterEvaluate(
const MCustomEvaluatorClusterNode* cluster // the cluster to be evaluated
)このエバリュエータに属しているクラスタを受け取るだけです。この呼び出しは、常に clusterInitialize の後に発生します。clusterTerminate の後には発生しません。最後に、
void MPxCustomEvaluator::postEvaluate(
const MEvaluationGraph* graph // the graph that was evaluated
)が、グラフ評価終了直後に呼び出されます。
以前の結果をキャッシュして評価を制限する例については、Developer Kit の simpleEvaluator プラグインを参照してください。
このシンプルなスクリプトは、指定のエバリュエータにどのノードが関連付けられているか確認します。
def printClusters(evaluatorName):
"""
Print out any clusters of nodes captured by the specified evaluator.
"""
evaluators = cmds.evaluator( query=True )
if evaluatorName in evaluators:
try:
print cmds.evaluator(
query=True,
name=evaluatorName,
clusters=True )[1:]
except KeyError:
print 'No clusters in the specified evaluator'
else:
print 'The specified evaluator is not active. Use the "evaluator" command to activate it'