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 <UT/UT_DSOVersion.h>
00030 #include <UT/UT_Math.h>
00031 #include <UT/UT_Matrix3.h>
00032 #include <UT/UT_Matrix4.h>
00033 #include <GU/GU_Detail.h>
00034 #include <GU/GU_PrimPoly.h>
00035 #include <PRM/PRM_Include.h>
00036 #include <OP/OP_Operator.h>
00037 #include <OP/OP_OperatorTable.h>
00038 #include <SOP/SOP_Guide.h>
00039 #include "SOP_Flatten.h"
00040
00041 using namespace HDK_Sample;
00042
00043 void
00044 newSopOperator(OP_OperatorTable *table)
00045 {
00046 table->addOperator(new OP_Operator("hdk_flatten",
00047 "Flatten",
00048 SOP_Flatten::myConstructor,
00049 SOP_Flatten::myTemplateList,
00050 1,
00051 1,
00052 0));
00053 }
00054
00055 static PRM_Name names[] = {
00056 PRM_Name("usedir", "Use Direction Vector"),
00057 PRM_Name("dist", "Distance"),
00058 };
00059
00060 PRM_Template
00061 SOP_Flatten::myTemplateList[] = {
00062 PRM_Template(PRM_STRING, 1, &PRMgroupName, 0, &SOP_Node::pointGroupMenu),
00063 PRM_Template(PRM_FLT_J, 1, &names[1], PRMzeroDefaults, 0,
00064 &PRMscaleRange),
00065 PRM_Template(PRM_TOGGLE, 1, &names[0]),
00066 PRM_Template(PRM_ORD, 1, &PRMorientName, 0, &PRMplaneMenu),
00067 PRM_Template(PRM_DIRECTION, 3, &PRMdirectionName, PRMzaxisDefaults),
00068 PRM_Template(),
00069 };
00070
00071
00072 OP_Node *
00073 SOP_Flatten::myConstructor(OP_Network *net, const char *name, OP_Operator *op)
00074 {
00075 return new SOP_Flatten(net, name, op);
00076 }
00077
00078 SOP_Flatten::SOP_Flatten(OP_Network *net, const char *name, OP_Operator *op)
00079 : SOP_Node(net, name, op), myGroup(0)
00080 {
00081
00082 mySopFlags.setNeedGuide1(1);
00083 }
00084
00085 SOP_Flatten::~SOP_Flatten() {}
00086
00087 unsigned
00088 SOP_Flatten::disableParms()
00089 {
00090 unsigned changed = 0;
00091
00092 changed = enableParm(3, !DIRPOP());
00093 changed += enableParm(4, DIRPOP());
00094
00095 return changed;
00096 }
00097
00098
00099 OP_ERROR
00100 SOP_Flatten::cookInputGroups(OP_Context &context, int alone)
00101 {
00102
00103
00104
00105 if (alone) if (lockInputs(context) >= UT_ERROR_ABORT) return error();
00106
00107 UT_String grp_name;
00108
00109
00110
00111
00112 GU_Detail *pgdp = alone ? (GU_Detail *)inputGeo(0, context) : gdp;
00113
00114 myGroup = 0;
00115
00116 getGroups(grp_name);
00117
00118
00119 if (grp_name.isstring())
00120 {
00121 myGroup = parsePointGroups((const char *)grp_name, pgdp);
00122
00123
00124
00125 if (!myGroup)
00126 {
00127 addError(SOP_ERR_BADGROUP, grp_name);
00128 }
00129 else if (!alone)
00130 {
00131
00132
00133
00134 select(*(GB_BaseGroup *)myGroup, 1);
00135 }
00136 }
00137 else if (!alone)
00138 {
00139
00140
00141 select(GU_SPoint);
00142 }
00143
00144
00145 checkInputChanged(0, -1, myDetailGroupPair, pgdp, myGroup);
00146
00147
00148 if (alone)
00149 {
00150 destroyAdhocGroups();
00151 unlockInputs();
00152 }
00153
00154 return error();
00155 }
00156
00157
00158 OP_ERROR
00159 SOP_Flatten::cookMySop(OP_Context &context)
00160 {
00161 GEO_Point *ppt;
00162 float now;
00163 int plane;
00164 float dist;
00165 UT_Vector3 normal, p;
00166
00167
00168
00169
00170 if (lockInputs(context) >= UT_ERROR_ABORT)
00171 return error();
00172
00173 now = context.myTime;
00174 plane = 2;
00175 duplicateSource(0, context);
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 setVariableOrder(3, 2, 0, 1);
00189
00190
00191
00192
00193
00194
00195 setCurGdh(0, myGdpHandle);
00196
00197
00198 setupLocalVars();
00199
00200
00201
00202 if (error() < UT_ERROR_ABORT && cookInputGroups(context) < UT_ERROR_ABORT)
00203 {
00204 FOR_ALL_OPT_GROUP_POINTS(gdp, myGroup, ppt)
00205 {
00206
00207
00208
00209
00210 myCurPt[0] = ppt;
00211 dist = DIST(now);
00212 if (!DIRPOP())
00213 {
00214 switch (ORIENT())
00215 {
00216 case 0 :
00217 normal.assign(0, 0, 1);
00218 break;
00219 case 1 :
00220 normal.assign(1, 0, 0);
00221 break;
00222 case 2 :
00223 normal.assign(0, 1, 0);
00224 break;
00225 }
00226 }
00227 else
00228 {
00229 normal.assign(NX(now), NY(now), NZ(now));
00230 normal.normalize();
00231 }
00232
00233 p.assign(ppt->getPos()(0), ppt->getPos()(1),
00234 ppt->getPos()(2));
00235 p -= normal * (dot(normal, p) - dist);
00236 ppt->getPos()(0) = p.x();
00237 ppt->getPos()(1) = p.y();
00238 ppt->getPos()(2) = p.z();
00239 }
00240 }
00241 unlockInputs();
00242
00243
00244
00245
00246
00247 resetLocalVarRefs();
00248
00249 return error();
00250 }
00251
00252 OP_ERROR
00253 SOP_Flatten::cookMyGuide1(OP_Context &context)
00254 {
00255 float now;
00256 UT_BoundingBox bbox;
00257 UT_Matrix3 mat3;
00258 UT_Matrix4 xform;
00259 float dist, nx = 0, ny = 0, nz = 1;
00260 float cx, cy, cz;
00261 float sx, sy, sz;
00262 float size;
00263 const int divs = 5;
00264 UT_Vector3 zaxis(0, 0, 1);
00265
00266 if (lockInputs(context) >= UT_ERROR_ABORT) return error();
00267
00268 now = context.myTime;
00269
00270 myGuide1->clearAndDestroy();
00271
00272 dist = DIST(now);
00273 if (!DIRPOP())
00274 {
00275 switch (ORIENT())
00276 {
00277 case 0 :
00278 nx = 0; ny = 0; nz = 1;
00279 break;
00280 case 1 :
00281 nx = 1; ny = 0; nz = 0;
00282 break;
00283 case 2 :
00284 nx = 0; ny = 1; nz = 0;
00285 break;
00286 }
00287 }
00288 else
00289 {
00290 nx = NX(now); ny = NY(now); nz = NZ(now);
00291 }
00292
00293 if (error() < UT_ERROR_ABORT)
00294 {
00295 UT_Vector3 normal(nx, ny, nz);
00296 normal.normalize();
00297
00298 inputGeo(0, context)->getBBox(&bbox);
00299
00300 sx = bbox.sizeX();
00301 sy = bbox.sizeY();
00302 sz = bbox.sizeZ();
00303 size = sqrtf(sx*sx + sy*sy + sz*sz);
00304
00305 cx = normal.x() * dist;
00306 cy = normal.y() * dist;
00307 cz = normal.z() * dist;
00308
00309 myGuide1->meshGrid(divs, divs, size, size);
00310
00311 mat3.dihedral(zaxis, normal);
00312 xform = mat3;
00313 xform.translate(cx, cy, cz);
00314
00315 myGuide1->transform(xform);
00316 }
00317
00318 unlockInputs();
00319 return error();
00320 }
00321
00322 const char *
00323 SOP_Flatten::inputLabel(unsigned) const
00324 {
00325 return "Geometry to Flatten";
00326 }