#include <UT/UT_DSOVersion.h>
#include "VOP_CustomContext.h"
#include <VOP/VOP_Operator.h>
#include <OP/OP_OperatorTable.h>
#include <OP/OP_Input.h>
#include <PRM/PRM_Include.h>
#include <PRM/PRM_SpareData.h>
#include <CH/CH_Manager.h>
#include <UT/UT_Assert.h>
#include <UT/UT_WorkBuffer.h>
#include <SYS/SYS_Types.h>
#include <stdlib.h>
#include <string.h>
using namespace HDK_Sample;
void
newSopOperator(OP_OperatorTable *table)
{
OP_Operator * op;
op = new OP_Operator(
"hdk_customvop",
"Custom VOP",
SOP_CustomVop::myConstructor,
SOP_CustomVop::myTemplateList,
0,
0
);
table->addOperator(op);
}
OP_Node *
SOP_CustomVop::myConstructor(
OP_Network *net, const char *name, OP_Operator *entry)
{
return new SOP_CustomVop(net, name, entry);
}
PRM_Template
SOP_CustomVop::myTemplateList[] =
{
PRM_Template()
};
SOP_CustomVop::SOP_CustomVop(
OP_Network *net, const char *name, OP_Operator *entry)
: SOP_Node(net, name, entry)
{
setOperatorTable(createAndGetOperatorTable());
}
SOP_CustomVop::~SOP_CustomVop()
{
}
const char *
SOP_CustomVop::getChildType() const
{
return VOP_OPTYPE_NAME;
}
OP_OpTypeId
SOP_CustomVop::getChildTypeID() const
{
return VOP_OPTYPE_ID;
}
class sop_CustomVopOperator : public VOP_Operator
{
public:
sop_CustomVopOperator(const char *name, const char *label)
: VOP_Operator(
name,
label,
VOP_CustomVop::myConstructor,
VOP_CustomVop::myTemplateList,
0,
VOP_VARIABLE_INOUT_MAX,
"invalid",
NULL,
OP_FLAG_UNORDERED,
VOP_VARIABLE_INOUT_MAX)
{
}
};
OP_OperatorTable *
SOP_CustomVop::createAndGetOperatorTable()
{
OP_OperatorTable &table = *OP_Network::getOperatorTable(VOP_TABLE_NAME);
table.addOperator(new sop_CustomVopOperator("hdk_inout11_", "In-Out 1-1"));
table.addOperator(new sop_CustomVopOperator("hdk_inout21_", "In-Out 2-1"));
table.addOperator(new sop_CustomVopOperator("hdk_inout12_", "In-Out 1-2"));
table.addOperator(new sop_CustomVopOperator("hdk_inout22_", "In-Out 2-2"));
table.notifyUpdateTableSinksOfUpdate();
return &table;
}
OP_ERROR
SOP_CustomVop::cookMySop(OP_Context &context)
{
return error();
}
OP_Node *
VOP_CustomVop::myConstructor(
OP_Network *net, const char *name, OP_Operator *entry)
{
return new VOP_CustomVop(net, name, entry);
}
static PRM_Name vopPlugInputs("inputs", "Inputs");
static PRM_Name vopPlugInpName("inpplug#", "Input Name #");
static PRM_Default vopPlugInpDefault(0, "input1");
static PRM_Name vopPlugOutputs("outputs", "Outputs");
static PRM_Name vopPlugOutName("outplug#", "Output Name #");
static PRM_Default vopPlugOutDefault(0, "output1");
static PRM_Template
vopPlugInpTemplate[] =
{
PRM_Template(PRM_ALPHASTRING, 1, &vopPlugInpName, &vopPlugInpDefault),
PRM_Template()
};
static PRM_Template
vopPlugOutTemplate[] =
{
PRM_Template(PRM_ALPHASTRING, 1, &vopPlugOutName, &vopPlugOutDefault),
PRM_Template()
};
PRM_Template
VOP_CustomVop::myTemplateList[] =
{
PRM_Template(PRM_MULTITYPE_LIST, vopPlugInpTemplate, 0, &vopPlugInputs,
PRMzeroDefaults, 0, &PRM_SpareData::multiStartOffsetZero),
PRM_Template(PRM_MULTITYPE_LIST, vopPlugOutTemplate, 0, &vopPlugOutputs,
PRMzeroDefaults, 0, &PRM_SpareData::multiStartOffsetZero),
PRM_Template()
};
VOP_CustomVop::VOP_CustomVop(
OP_Network *parent, const char *name, OP_Operator *entry)
: VOP_Node(parent, name, entry)
{
addOpInterest(this, &VOP_CustomVop::nodeEventHandler);
}
VOP_CustomVop::~VOP_CustomVop()
{
removeOpInterest(this, &VOP_CustomVop::nodeEventHandler);
}
bool
VOP_CustomVop::runCreateScript()
{
if (!VOP_Node::runCreateScript())
return false;
const UT_String & type_name = getOperator()->getName();
fpreal t = CHgetEvalTime();
UT_WorkBuffer plugname;
int n;
n = type_name(type_name.length() - 3) - '0';
setInt(vopPlugInputs.getToken(), 0, t, n);
for (int i = 0; i < n; i++)
{
plugname.sprintf("input%d", i + 1);
setStringInst(plugname.buffer(), CH_STRING_LITERAL,
vopPlugInpName.getToken(), &i, 0, t);
}
n = type_name(type_name.length() - 2) - '0';
setInt(vopPlugOutputs.getToken(), 0, t, n);
for (int i = 0; i < n; i++)
{
plugname.sprintf("output%d", i + 1);
setStringInst(plugname.buffer(), CH_STRING_LITERAL,
vopPlugOutName.getToken(), &i, 0, t);
}
return true;
}
const char *
VOP_CustomVop::inputLabel(unsigned idx) const
{
static UT_WorkBuffer theLabel;
fpreal t = CHgetEvalTime();
int i = idx;
UT_String label;
evalStringInst(vopPlugInpName.getToken(), &i, label, 0, t);
if (label.isstring())
theLabel.strcpy(label);
else
theLabel.strcpy("<unnamed>");
return theLabel.buffer();
}
const char *
VOP_CustomVop::outputLabel(unsigned idx) const
{
static UT_WorkBuffer theLabel;
fpreal t = CHgetEvalTime();
int i = idx;
UT_String label;
evalStringInst(vopPlugOutName.getToken(), &i, label, 0, t);
if (label.isstring())
theLabel.strcpy(label);
else
theLabel.strcpy("<unnamed>");
return theLabel.buffer();
}
unsigned
VOP_CustomVop::getNumVisibleInputs() const
{
return evalInt("inputs", 0, CHgetEvalTime());
}
unsigned
VOP_CustomVop::getNumVisibleOutputs() const
{
return evalInt("outputs", 0, CHgetEvalTime());
}
void
VOP_CustomVop::getInputNameSubclass(UT_String &name, int idx) const
{
name.harden(inputLabel(idx));
}
int
VOP_CustomVop::getInputFromNameSubclass(const UT_String &name) const
{
for (int i = 0; i < getNumVisibleInputs(); i++)
{
if (name == inputLabel(i))
return i;
}
return -1;
}
VOP_Type
VOP_CustomVop::getInputTypeSubclass(int idx)
{
return VOP_TYPE_FLOAT;
}
void
VOP_CustomVop::getAllowedInputTypesSubclass(
unsigned idx, VOP_VopTypeArray &voptypes)
{
voptypes.append(VOP_TYPE_FLOAT);
}
void
VOP_CustomVop::getOutputNameSubclass(UT_String &name, int idx) const
{
name.harden(outputLabel(idx));
}
VOP_Type
VOP_CustomVop::getOutputTypeSubclass(int idx)
{
return VOP_TYPE_FLOAT;
}
void
VOP_CustomVop::nodeEventHandler(
OP_Node *caller, void *callee, OP_EventType type, void *data)
{
switch (type)
{
case OP_PARM_CHANGED:
static_cast<VOP_CustomVop*>(callee)->handleParmChanged(long(data));
break;
default:
break;
}
}
void
VOP_CustomVop::handleParmChanged(int parm_index)
{
triggerUIChanged();
}
bool
SOP_CustomVopOperatorFilter::allowOperatorAsChild(OP_Operator *op)
{
return (dynamic_cast<sop_CustomVopOperator *>(op) != NULL);
}