Sunday, November 2, 2008

So how do I use Shake Command Window?

I use it for plug-in development. You don't have to restart Shake every time you modify a code. You can see the internal state of nodes interactively, you can test your plug-in after modifying the node state, and you can see how things work, monitor plug changes to see if node evaluation chain is working as you expected. There are two programs I was mainly using. I made these two programs bit by bit interactively with the Command Window.

[dispTree] Displays a node tree.
name: the root tree
recurseNode: set true if you want to show child node
showPlug: set true if you also want to show plugs and their values
recursePlug: set true if you want to show child plugs and their values

























[dispPlugInfo] displays informations about a plug
nodename: node name which has the plug to display
plugname: plug name to display



























You may need to add include directives to the header include (settings - header include).
#include <string>, etc.

[dispTree]


const char* name = "NRiScript1";
bool recurseNode = true;
bool showPlug = false;
bool recursePlug = false;

#define print(x) NRiSys::error((NRiName() + x).getString());

const NRiName operator +(const NRiName lhs, const std::string rhs)
{
return lhs + rhs.c_str();
}

void printSpace(int nestcount)
{
for (int n = 0; n < nestcount; ++n)
{
print(" ");
}
}


void dispPlug(NRiPlug* p)
{
NRiName val;
switch(p->getType())
{
case kString:
val = p->asString();
break;
case kInt:
val = p->asInt();
break;
case kFloat:
val = p->asFloat();
break;
case kDouble:
val = p->asDouble();
break;
case kPtr:
val.sprintf("0x%x", p->asPtr());
break;
default:
break;
}
print(".." + p->getName() + "=" + val + "\n");
}

void dispPlugTree(NRiPlug* plug, int nestcount, bool recursePlug)
{
printSpace(nestcount);
dispPlug(plug);
if (recursePlug)
{
int ncp = plug->getNbChildren();
for (int i = 0; i < ncp; ++i)
{
dispPlugTree(plug->getNthChild(i), nestcount + 1, recursePlug);
}
}
}

void dispNodeTree(NRiNode* node, int nestcount, bool showPlug, bool recurseNode = false, bool recursePlug = false)
{
printSpace(nestcount);
print(node->getName() + ":" + node->getClassName() + "\n");
if (showPlug)
{
int np = node->getNbPlugs();
for (int ip = 0; ip < np; ++ip)
{
dispPlugTree(node->getNthPlug(ip), nestcount + 1, recursePlug);
}
}

if (recurseNode)
{
int numkids = node->getNbChildren();
for (int i = 0; i < numkids; ++i)
{
dispNodeTree(node->getNthChild(i), nestcount + 1, showPlug, recurseNode, recursePlug);
}
}
}

void shakeCommandWinEntryFunc()
{
NRiNode* node = NRiNode::findNode(name);
dispNodeTree(node, 0, showPlug, recurseNode, recursePlug);
}

[dispPlugInfo]

const char* nodename = "NRiScript1.Gamma1";
const char* plugname = "In";


#define print(x) NRiSys::error((NRiName() + x).getString());


NRiName value(NRiPlug* p)
{
NRiName val;
switch(p->getType())
{
case kString:
val = p->asString();
break;
case kInt:
val = p->asInt();
break;
case kFloat:
val = p->asFloat();
break;
case kDouble:
val = p->asDouble();
break;
case kPtr:
val.sprintf("0x%x", p->asPtr());
break;
default:
break;
}
return val;
}

NRiName ioString(NRiPlug* p)
{
const char* types[] = {"ng", "in", "out", "inout"};
return types[p->getIO()];
}

NRiName typeString(NRiPlug* p)
{
switch(p->getType())
{
case kInt:
return "int";
case kFloat:
return "float";
case kPtr:
return "ptr";
case kString:
return "string";
default:
return "ng";
}
}

NRiName flagString(NRiPlug* p)
{
NRiPlug::Flags flags[] = {NRiPlug::kInternal, NRiPlug::kNotify, NRiPlug::kNotifyConnect,
NRiPlug::kInherit, NRiPlug::kDisconnectOnSet, NRiPlug::kPersistent,
NRiPlug::kRecompile, NRiPlug::kLoadable, NRiPlug::kPreUpdate,
NRiPlug::kOwnerScope, NRiPlug::kIgnoreConnect, NRiPlug::kAutoPlug,
NRiPlug::kLocal, NRiPlug::kIgnoreDependencies, NRiPlug::kDeleting,
NRiPlug::kXReadWrite, NRiPlug::kIgnoreType, NRiPlug::kAlwaysCallOwner,
NRiPlug::kMonitor, NRiPlug::kNoExpr, NRiPlug::kInterrupt, NRiPlug::kFiltered,
NRiPlug::kSerializeChildren, NRiPlug::kLookupSrc, NRiPlug::kExpressionSrc,
NRiPlug::kUserDefined, NRiPlug::kPassThrough, NRiPlug::kCurveDefined,
NRiPlug::kLocked};

const char* flagStrings[] = {
"Internal", "Notify", "NotifyConnect", "Inherit", "DisconnectOnSet",
"Persistent", "Recompile", "Loadable", "PreUpdate", "OwnerScope",
"IgnoreConnect", "AutoPlug", "Local", "IgnoreDependencies", "Deleting",
"XReadWrite", "IgnoreType", "AlwaysCallOwner", "Monitor", "NoExpr",
"Interrupt", "Filtered", "SerializeChildren", "LookupSrc", "ExpressionSrc",
"UserDefined", "PassThrough", "CurveDefined", "Locked"};
NRiName result;
for (int i = 0; i < 29; ++i)
{
if (p->getFlag(flags[i]))
{
result += flagStrings[i];
result += " ";
}
}
return result;
}

NRiName hasErrorString(NRiPlug* p)
{
if (p->hasError())
{
return "Yes";
}
else
{
return "No";
}
}

void printPlug(NRiPlug* p)
{
if (p)
{
print(p->getOwner()->getFullName() + ".." + p->getFullName());
}
print("\n");
}

void printPA(const NRiPArray < NRiPlug >& pa)
{
for(unsigned i = 0; i < pa.getLength(); ++i)
{
print(" ");
printPlug(pa[i]);
}
}

void shakeCommandWinEntryFunc()
{
NRiNode* node = NRiNode::findNode(nodename);
if ( ! node)
{
print("Node not found.\n");
return;
}
NRiPlug* plug = node->getPlug(plugname);
if ( ! plug)
{
print("Plug not found.\n");
return;
}

print("<<<");
print(node->getFullName() + ".." + plug->getFullName() + ">>>\n");
print(NRiName() + "[Value] " + value(plug) + "\n");
print(NRiName() + "[Expr] " + plug->asExpr() + "\n");
print(NRiName() + "[IO] " + ioString(plug) + "\n");
print(NRiName() + "[Type] " + typeString(plug) + "\n");
print(NRiName() + "[Flags] " + flagString(plug) + "\n");
print(NRiName() + "[HasError] " + hasErrorString(plug) + "\n");
print("[Input] ");
printPlug(plug->getInput());
print("[LogicalInput] ");
printPlug(plug->getLogicalInput());
//print("[Ouput] ");
//printPlug(plug->getOutput());
print("[Outputs]...\n");
NRiPArray < NRiPlug > pa;
plug->getOutputs(pa);
printPA(pa);
pa.clear();
print("[getLogicalOutputs]...\n");
plug->getLogicalOutputs(pa);
printPA(pa);
pa.clear();
print("[getDependencies]...\n");
const NRiPArray < NRiPlug > * pap;
pap = plug->getDependencies();
printPA(*pap);
print("[getDependents]...\n");
pap = plug->getDependents();
printPA(*pap);
}

No comments: