#include <UT/UT_DSOVersion.h>
#include <OP/OP_OperatorTable.h>
#include <CH/CH_LocalVariable.h>
#include <PRM/PRM_Include.h>
#include <CHOP/PRM_ChopShared.h>
#include <CHOP/CHOP_Handle.h>
#include <OP/OP_Channels.h>
#include "CHOP_Stair.h"
using namespace HDK_Sample;
CHOP_SWITCHER2(4, "Stair", 8, "Channel");
static PRM_Name names[] =
{
PRM_Name("number", "Number of Stairs"),
PRM_Name("height", "Stair Height"),
PRM_Name("offset", "Offset"),
PRM_Name("direction", "Direction"),
PRM_Name("channelname", "Channel Name"),
};
static PRM_Name CHOPstairMenu[] = {
PRM_Name("up", "Up"),
PRM_Name("down", "Down"),
PRM_Name(0),
};
static PRM_ChoiceList stairMenu((PRM_ChoiceListType)(PRM_CHOICELIST_EXCLUSIVE
| PRM_CHOICELIST_REPLACE),CHOPstairMenu);
static PRM_Default nameDefault(0,"chan1");
static PRM_Range stairRange(PRM_RANGE_RESTRICTED, 0, PRM_RANGE_UI, 10);
PRM_Template
CHOP_Stair::myTemplateList[] =
{
PRM_Template(PRM_SWITCHER, 3, &PRMswitcherName, switcher),
PRM_Template(PRM_INT_J, 1, &names[0], PRMoneDefaults, 0, &stairRange),
PRM_Template(PRM_FLT_J, 1, &names[1], PRMoneDefaults, 0,
&CHOP_DefaultValueRange),
PRM_Template(PRM_FLT_J, 1, &names[2], PRMzeroDefaults, 0,
&CHOP_DefaultValueRange),
PRM_Template(PRM_ORD, 1, &names[3], PRMzeroDefaults, &stairMenu),
PRM_Template(PRM_STRING, 1, &names[4], &nameDefault,0),
PRM_Template(PRM_ORD, 1, &CHOP_RangeName, PRMtwoDefaults,
&CHOP_RangeMenu),
PRM_Template(PRM_FLT, 1, &CHOP_StartName, &CHOP_StartDefault,0,
&CHOP_FrameRange),
PRM_Template(PRM_FLT, 1, &CHOP_EndName, &CHOP_EndDefault, 0,
&CHOP_FrameRange),
PRM_Template(PRM_FLT, 1, &CHOP_SampleRateName,
&CHOP_SampleRateDefault,0,&CHOP_SampleRateRange),
PRM_Template(PRM_ORD, 1, &CHOP_ExtendLeftName,0, &CHOP_ExtendMenu),
PRM_Template(PRM_ORD, 1, &CHOP_ExtendRightName,0,&CHOP_ExtendMenu),
PRM_Template(PRM_FLT, 1, &CHOP_DefaultValueName, PRMzeroDefaults,0,
&CHOP_DefaultValueRange),
PRM_Template(),
};
OP_TemplatePair CHOP_Stair::myTemplatePair(
CHOP_Stair::myTemplateList, &CHOP_Node::myTemplatePair);
enum
{
VAR_C = 200,
VAR_NC = 201
};
CH_LocalVariable
CHOP_Stair::myVariableList[] = {
{ "C", VAR_C, 0 },
{ "NC", VAR_NC, 0 },
{ 0, 0, 0 }
};
OP_VariablePair CHOP_Stair::myVariablePair(
CHOP_Stair::myVariableList, &CHOP_Node::myVariablePair);
bool
CHOP_Stair::evalVariableValue(fpreal &v, int index, int thread)
{
switch( index )
{
case VAR_C:
v = (fpreal) my_C;
return true;
case VAR_NC:
v = (fpreal) my_NC;
return true;
}
return CHOP_Node::evalVariableValue(v, index, thread);
}
OP_Node *
CHOP_Stair::myConstructor(OP_Network *net,
const char *name,
OP_Operator *op)
{
return new CHOP_Stair(net, name, op);
}
CHOP_Stair::CHOP_Stair( OP_Network *net,
const char *name,
OP_Operator *op)
: CHOP_Node(net, name, op),
myExpandArray()
{
myParmBase = getParmList()->getParmIndex( names[0].getToken() );
my_C = 0;
my_NC = 0;
}
CHOP_Stair::~CHOP_Stair()
{
}
unsigned
CHOP_Stair::disableParms()
{
unsigned changes = CHOP_Node::disableParms();
bool use_startend = (RANGE(0.0) == RANGE_USER_ENTERED);
changes += enableParm("start", use_startend);
changes += enableParm("end", use_startend);
if(LEXTEND() == CL_TRACK_DEFAULT || REXTEND() == CL_TRACK_DEFAULT)
changes += enableParm(CHOP_DefaultValueName.getToken(),1);
else
changes += enableParm(CHOP_DefaultValueName.getToken(),0);
return changes;
}
#define START_HANDLE 1
#define END_HANDLE 2
#define OFFSET_HANDLE 3
void
CHOP_Stair::cookMyHandles(OP_Context &context)
{
CHOP_Handle *handle;
CHOP_HandleLook hlook;
fpreal start, end;
fpreal xoffset, yoffset;
destroyHandles();
getParmIntervalInSamples(context.getTime(), start, end);
xoffset = (end - start) * 0.75 + start;
yoffset = OFFSET(context.getTime());
if (RANGE(context.getTime()) == RANGE_USER_ENTERED)
{
hlook = myChannels->getChannel("start") ? HANDLE_GUIDE : HANDLE_BOX;
handle = new CHOP_Handle(this, "start", START_HANDLE, start, 0.0,
hlook, HANDLE_HORIZONTAL, (HANDLE_BAR |
HANDLE_LABEL_RIGHT | HANDLE_LABEL_BOTTOM));
myHandles.append(handle);
hlook = myChannels->getChannel("end") ? HANDLE_GUIDE : HANDLE_BOX;
handle = new CHOP_Handle(this, "end", END_HANDLE, end, 0.0,
hlook, HANDLE_HORIZONTAL, (HANDLE_BAR |
HANDLE_LABEL_RIGHT | HANDLE_LABEL_BOTTOM |
HANDLE_WIDTH_END));
myHandles.append(handle);
}
hlook = myChannels->getChannel("offset") ? HANDLE_GUIDE : HANDLE_BOX;
handle = new CHOP_Handle(this, "offset", OFFSET_HANDLE, xoffset, yoffset,
hlook, HANDLE_VERTICAL,
(HANDLE_LABEL_RIGHT | HANDLE_LABEL_BOTTOM));
myHandles.append(handle);
}
fpreal
CHOP_Stair::handleChanged(CHOP_Handle *handle, CHOP_HandleData *hdata)
{
fpreal result = 0.0;
OP_Network *net = 0;
fpreal offset;
if (hdata->shift)
{
setCurrent(1);
if (net = getParent())
net->pickRequest(this, 0);
}
switch(handle->getId())
{
case START_HANDLE:
offset = CL_RINT(hdata->xoffset);
if (!hdata->shift)
SET_START(myHandleCookTime, offset);
result = toUnit(offset, hdata->unit);
break;
case END_HANDLE:
offset = CL_RINT(hdata->xoffset);
if (!hdata->shift)
SET_END(myHandleCookTime, offset);
result = toUnit(offset, hdata->unit, 1);
break;
case OFFSET_HANDLE:
if (!hdata->shift)
SET_OFFSET(myHandleCookTime, hdata->yoffset);
result = hdata->yoffset;
break;
}
return result;
}
fpreal
CHOP_Stair::shiftStart(fpreal new_offset, fpreal t)
{
SET_START(t, new_offset);
return new_offset;
}
OP_ERROR
CHOP_Stair::cookMyChop(OP_Context &context)
{
CL_Track *track;
fpreal samplerate;
fpreal start, end;
int left, right;
fpreal *data;
UT_String name;
fpreal value;
fpreal defvalue;
int nchan;
fpreal stepheight;
fpreal index, idxstep;
int i;
destroyClip();
samplerate = RATE(context.getTime());
if(UTequalZero(samplerate))
{
addError(CHOP_ERROR_ZERO_SAMPLE_RATE);
return error();
}
myClip->setSampleRate(samplerate);
CHAN_NAME(name, context.getTime());
nchan = myExpandArray.setPattern(name);
my_NC = nchan;
getParmIntervalInSamples(context.getTime(), start, end);
left = LEXTEND();
right = REXTEND();
myClip->setTrackLength((int)(end-start+1));
myClip->setStart(start);
for (my_C=0; my_C < nchan; my_C++)
{
defvalue = DEFAULT(context.getTime());
value = OFFSET(context.getTime());
idxstep = (end-start+1) / (NUMBER(context.getTime()) + 1);
stepheight = HEIGHT(context.getTime());
if (DIRECTION() == 1)
stepheight *= -1;
track = myClip->addTrack(myExpandArray(my_C));
track->setLeft((CL_TrackOutside)left);
track->setRight((CL_TrackOutside)right);
if(left == CL_TRACK_DEFAULT || right == CL_TRACK_DEFAULT)
track->setDefault(defvalue);
data = track->getData();
track->constant(0);
index = idxstep;
for(i=0; i < (end-start+1); i++)
{
if (i && i > index)
{
value += stepheight;
index += idxstep;
}
data[i] = value;
}
}
my_C = 0;
return error();
}
void
newChopOperator(OP_OperatorTable *table)
{
table->addOperator(
new OP_Operator("hdk_stair",
"HDK Stair",
CHOP_Stair::myConstructor,
&CHOP_Stair::myTemplatePair,
0,
0,
&CHOP_Stair::myVariablePair,
OP_FLAG_GENERATOR)
);
}