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
00027
00028
00029 #include <limits.h>
00030 #include <UT/UT_DSOVersion.h>
00031 #include <UT/UT_Math.h>
00032 #include <UT/UT_Interrupt.h>
00033 #include <GU/GU_Detail.h>
00034 #include <GU/GU_PrimPoly.h>
00035 #include <CH/CH_LocalVariable.h>
00036 #include <PRM/PRM_Include.h>
00037 #include <OP/OP_Operator.h>
00038 #include <OP/OP_OperatorTable.h>
00039 #include "SOP_Star.h"
00040
00041 using namespace HDK_Sample;
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 void
00057 newSopOperator(OP_OperatorTable *table)
00058 {
00059 table->addOperator(
00060 new OP_Operator("hdk_star",
00061 "Star",
00062 SOP_Star::myConstructor,
00063 SOP_Star::myTemplateList,
00064 0,
00065 0,
00066 SOP_Star::myVariables,
00067 OP_FLAG_GENERATOR)
00068 );
00069 }
00070
00071 static PRM_Name negativeName("nradius", "Negative Radius");
00072
00073
00074
00075 static PRM_Default fiveDefault(5);
00076 static PRM_Default radiiDefaults[] = {
00077 PRM_Default(1),
00078 PRM_Default(0.3)
00079 };
00080
00081 PRM_Template
00082 SOP_Star::myTemplateList[] = {
00083 PRM_Template(PRM_INT_J, 1, &PRMdivName, &fiveDefault, 0,
00084 &PRMdivision2Range),
00085 PRM_Template(PRM_XYZ_J, 2, &PRMradiusName, radiiDefaults),
00086 PRM_Template(PRM_TOGGLE, 1, &negativeName),
00087 PRM_Template(PRM_XYZ_J, 3, &PRMcenterName),
00088 PRM_Template(PRM_ORD, 1, &PRMorientName, 0, &PRMplaneMenu),
00089 PRM_Template()
00090 };
00091
00092
00093
00094 enum {
00095 VAR_PT,
00096 VAR_NPT
00097 };
00098
00099 CH_LocalVariable
00100 SOP_Star::myVariables[] = {
00101 { "PT", VAR_PT, 0 },
00102 { "NPT", VAR_NPT, 0 },
00103 { 0, 0, 0 },
00104 };
00105
00106 float
00107 SOP_Star::getVariableValue(int index, int thread)
00108 {
00109
00110
00111 if (myCurrPoint < 0) return 0;
00112 switch (index)
00113 {
00114 case VAR_PT: return myCurrPoint;
00115 case VAR_NPT: return myTotalPoints;
00116 }
00117
00118 return SOP_Node::getVariableValue(index, thread);
00119 }
00120
00121 OP_Node *
00122 SOP_Star::myConstructor(OP_Network *net, const char *name, OP_Operator *op)
00123 {
00124 return new SOP_Star(net, name, op);
00125 }
00126
00127 SOP_Star::SOP_Star(OP_Network *net, const char *name, OP_Operator *op)
00128 : SOP_Node(net, name, op)
00129 {
00130 myCurrPoint = -1;
00131 }
00132
00133 SOP_Star::~SOP_Star() {}
00134
00135 unsigned
00136 SOP_Star::disableParms()
00137 {
00138 return 0;
00139 }
00140
00141 OP_ERROR
00142 SOP_Star::cookMySop(OP_Context &context)
00143 {
00144 float now;
00145 float rad, tx, ty, tz;
00146 int divisions, plane, negradius;
00147 int xcoord, ycoord, zcoord;
00148 float tmp, tinc;
00149 GEO_Point *ppt;
00150 GU_PrimPoly *poly;
00151 int i;
00152 UT_Interrupt *boss;
00153
00154 now = context.myTime;
00155
00156
00157
00158 divisions = DIVISIONS(now)*2;
00159 myTotalPoints = divisions;
00160 myCurrPoint = 0;
00161
00162 plane = ORIENT();
00163 negradius = NEGRADIUS();
00164 tx = CENTERX(now);
00165 ty = CENTERY(now);
00166 tz = CENTERZ(now);
00167
00168 switch (plane)
00169 {
00170 case 0:
00171 xcoord = 0;
00172 ycoord = 1;
00173 zcoord = 2;
00174 break;
00175 case 1:
00176 xcoord = 1;
00177 ycoord = 2;
00178 zcoord = 0;
00179 break;
00180 case 2:
00181 xcoord = 0;
00182 ycoord = 2;
00183 zcoord = 1;
00184 break;
00185 }
00186
00187
00188 if (error() < UT_ERROR_ABORT)
00189 {
00190 boss = UTgetInterrupt();
00191 if (divisions < 4)
00192 {
00193
00194
00195
00196 addWarning(SOP_MESSAGE, "Invalid divisions");
00197 divisions = 4;
00198 }
00199 gdp->clearAndDestroy();
00200
00201
00202 boss->opStart("Building Star");
00203
00204
00205 poly = GU_PrimPoly::build(gdp, divisions, GU_POLY_CLOSED);
00206 tinc = M_PI*2 / (float)divisions;
00207
00208
00209 for (i = 0; i < divisions; i++)
00210 {
00211
00212 if (boss->opInterrupt())
00213 break;
00214
00215 myCurrPoint = i;
00216
00217
00218
00219
00220
00221 tmp = (float)i * tinc;
00222 rad = (i & 1) ? XRADIUS(now) : YRADIUS(now);
00223 if (!negradius && rad < 0)
00224 rad = 0;
00225
00226 ppt = poly->getVertex(i).getPt();
00227 ppt->getPos()(xcoord) = cos(tmp) * rad + tx;
00228 ppt->getPos()(ycoord) = sin(tmp) * rad + ty;
00229 ppt->getPos()(zcoord) = 0 + tz;
00230 }
00231
00232
00233
00234
00235 select(GU_SPrimitive);
00236
00237
00238 boss->opEnd();
00239 }
00240
00241 myCurrPoint = -1;
00242 return error();
00243 }