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: