00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdlib.h>
00027 #include <UT/UT_DSOVersion.h>
00028 #include <UT/UT_NTStreamUtil.h>
00029 #include <PRM/PRM_Include.h>
00030 #include <OP/OP_OperatorTable.h>
00031 #include <OP/OP_Input.h>
00032 #include <VOP/VOP_Operator.h>
00033 #include "VOP_Switch.h"
00034
00035 using namespace HDK_Sample;
00036
00037 void
00038 newVopOperator(OP_OperatorTable *table)
00039 {
00040 OP_Operator *op;
00041
00042
00043
00044
00045
00046
00047 op = new VOP_Operator("hdkswitch",
00048 "HDK Switch",
00049 VOP_Switch::myConstructor,
00050 VOP_Switch::myTemplateList,
00051 0,
00052 VOP_VARIABLE_INOUT_MAX,
00053 "*",
00054 0,
00055 OP_FLAG_UNORDERED,
00056 1);
00057
00058 table->addOperator(op);
00059 }
00060
00061 static const char *theInputRoot = "input";
00062 static const char *theOutputName = "result";
00063 static PRM_Name theSwitcherName("switcher", "Switcher Index");
00064 static PRM_Name theOutOfBoundsName("outofbounds",
00065 "Out Of Bounds Behavior");
00066 static PRM_Name theOutOfBoundsChoices[] =
00067 {
00068 PRM_Name("last", "Output Last Input Value"),
00069 PRM_Name("zero", "Output Zero"),
00070 PRM_Name()
00071 };
00072 enum
00073 {
00074 VOP_SWITCH_OOB_LAST,
00075 VOP_SWITCH_OOB_ZERO
00076 };
00077 static PRM_ChoiceList theOutOfBoundsMenu(PRM_CHOICELIST_SINGLE,
00078 theOutOfBoundsChoices);
00079
00080 OP_Node *
00081 VOP_Switch::myConstructor(OP_Network *net, const char *name, OP_Operator *entry)
00082 {
00083 return new VOP_Switch(net, name, entry);
00084 }
00085
00086 PRM_Template VOP_Switch::myTemplateList[] =
00087 {
00088 PRM_Template(PRM_INT, 1, &theSwitcherName, PRMzeroDefaults),
00089 PRM_Template(PRM_ORD, 1, &theOutOfBoundsName, PRMzeroDefaults,
00090 &theOutOfBoundsMenu),
00091
00092 PRM_Template()
00093 };
00094
00095 VOP_Switch::VOP_Switch(OP_Network *parent, const char *name, OP_Operator *entry)
00096 : VOP_Node(parent, name, entry)
00097 {
00098 }
00099
00100 VOP_Switch::~VOP_Switch()
00101 {
00102 }
00103
00104 unsigned
00105 VOP_Switch::disableParms()
00106 {
00107 int changed = 0;
00108
00109
00110
00111 changed += enableParm(theSwitcherName.getToken(), getInput(0) == 0);
00112
00113 return changed;
00114 }
00115
00116 void
00117 VOP_Switch::getCode(UT_String &codestr)
00118 {
00119
00120
00121 if (getNumVisibleInputs() > 2)
00122 {
00123 UT_OStrStream os;
00124 UT_String inputName, outputName;
00125 int outofbounds = OUTOFBOUNDS();
00126 int i, j, next, first = 1;
00127
00128
00129
00130
00131
00132
00133 getOutputName(outputName, 0);
00134 for( i = getConnectedInputIndex(0), j = 0; i >= 0; i = next, j++ )
00135 {
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 next = getConnectedInputIndex(i);
00152 getInputName(inputName, i);
00153 if( next >= 0 || outofbounds == VOP_SWITCH_OOB_ZERO )
00154 {
00155 if( !first )
00156 os << "else ";
00157 os << "if( $" << theSwitcherName.getToken();
00158 os << " == " << j << " )" << endl;
00159 os << " ";
00160 }
00161 else if( !first )
00162 {
00163 os << "else" << endl << " ";
00164 }
00165 os << "$" << outputName << " = $" << inputName << ";" << endl;
00166 first = 0;
00167 }
00168
00169
00170
00171 if( outofbounds == VOP_SWITCH_OOB_ZERO )
00172 {
00173 VOP_Type outputType = getOutputType(0);
00174
00175 if( !first )
00176 os << "else" << endl << " ";
00177 os << "$" << outputName << " = ";
00178 os << myLanguage->getEmptyConstantString(outputType) << ";" << endl;
00179 }
00180 os << ends;
00181 codestr.harden(os.str());
00182 os.rdbuf()->freeze(0);
00183 }
00184 }
00185
00186 const char *
00187 VOP_Switch::inputLabel(unsigned idx) const
00188 {
00189 if (idx >= orderedInputs())
00190 {
00191 static UT_String theLabel;
00192 char numstr[UT_NUMBUF];
00193
00194
00195 theLabel = "Input Number ";
00196 UT_String::itoa(numstr, idx + 1 - orderedInputs());
00197 theLabel += numstr;
00198
00199 return theLabel;
00200 }
00201 else
00202 return theSwitcherName.getLabel();
00203 }
00204
00205 const char *
00206 VOP_Switch::outputLabel(unsigned idx) const
00207 {
00208 UT_ASSERT(idx == 0);
00209
00210 return "Chosen Value";
00211 }
00212
00213 void
00214 VOP_Switch::getInputNameSubclass(UT_String &in, int idx) const
00215 {
00216 if (idx >= orderedInputs())
00217 {
00218 char numstr[UT_NUMBUF];
00219
00220
00221 in = theInputRoot;
00222 UT_String::itoa(numstr, idx + 1 - orderedInputs());
00223 in += numstr;
00224 }
00225 else
00226 in = theSwitcherName.getToken();
00227 }
00228
00229 int
00230 VOP_Switch::getInputFromNameSubclass(const UT_String &in) const
00231 {
00232 int inputnum = -1;
00233
00234
00235 if( in == theSwitcherName.getToken() )
00236 return 0;
00237
00238
00239 if( !strncmp(in, theInputRoot, strlen(theInputRoot)) )
00240 inputnum = ::atoi((const char *)in + strlen(theInputRoot));
00241
00242 return inputnum - 1 + orderedInputs();
00243 }
00244
00245 VOP_Type
00246 VOP_Switch::getInputTypeSubclass(int idx)
00247 {
00248 VOP_Node *vop;
00249 OP_Input *input;
00250 VOP_Type vextype = VOP_TYPE_UNDEF;
00251
00252 if( idx >= orderedInputs() )
00253 {
00254
00255
00256 if( input = getInputReference(orderedInputs(), 0) )
00257 {
00258 vop = CAST_VOPNODE(input->getNode());
00259 if( vop )
00260 vextype = vop->getOutputType(input->getNodeOutputIndex());
00261 }
00262 }
00263 else
00264 vextype = myLanguage->conditionType(VOP_TYPE_INTEGER);
00265
00266 return vextype;
00267 }
00268
00269 void
00270 VOP_Switch::getAllowedInputTypesSubclass(unsigned idx, VOP_VopTypeArray &voptypes)
00271 {
00272 VOP_Node *vop;
00273 OP_Input *input;
00274
00275 if( idx >= orderedInputs() )
00276 {
00277
00278
00279 if( input = getInputReference(orderedInputs(), 0) )
00280 {
00281 vop = CAST_VOPNODE(input->getNode());
00282 if( vop )
00283 voptypes.append(vop->getOutputType(input->getNodeOutputIndex()));
00284 }
00285 }
00286 else
00287 voptypes.append(myLanguage->conditionType(VOP_TYPE_INTEGER));
00288 }
00289
00290 void
00291 VOP_Switch::getOutputNameSubclass(UT_String &name, int idx) const
00292 {
00293 UT_ASSERT(idx == 0);
00294
00295 name = theOutputName;
00296 }
00297
00298 VOP_Type
00299 VOP_Switch::getOutputTypeSubclass(int idx)
00300 {
00301 UT_ASSERT(idx == 0);
00302
00303
00304
00305 return getInputType(orderedInputs());
00306 }
00307
00308 unsigned
00309 VOP_Switch::getNumVisibleInputs() const
00310 {
00311 int max = nInputs();
00312
00313
00314
00315 if( max < orderedInputs() )
00316 max = orderedInputs();
00317
00318 return max + 1;
00319 }
00320
00321 unsigned
00322 VOP_Switch::orderedInputs() const
00323 {
00324
00325
00326 return 1;
00327 }
00328
00329 int
00330 VOP_Switch::OUTOFBOUNDS()
00331 {
00332 return evalInt(theOutOfBoundsName.getToken(), 0, 0.0f);
00333 }
00334