OP_ERROR SOP_Cleave::cookMySop(OP_Context &context) { const GA_PrimitiveGroup *polyGroup; GEO_Primitive *prim; GQ_Detail *gqd; int i,j,k; UT_Vector4 np,p; // Before we do anything, we must lock our inputs. Before returning, // we have to make sure that the inputs get unlocked. if (lockInputs(context) >= UT_ERROR_ABORT) return error(); float now = context.getTime(); duplicateSource(0, context, 0, 1); // Here we determine which groups we have to work on. We only // handle poly groups. UT_String groups; getGroups(groups); if (groups.isstring()) polyGroup = parsePrimitiveGroups(groups); else polyGroup = 0; if (error() >= UT_ERROR_ABORT) { unlockInputs(); return error(); } UT_Interrupt* boss = UTgetInterrupt(); // Start the interrupt server boss->opStart("Cleaving Polys"); // separate out all polys to be cleaved GA_PrimitiveGroup* cleave_group = gdp->newPrimitiveGroup("cleave",1); GA_PrimitiveGroup* not_cleave_group = gdp->newPrimitiveGroup("not_cleave",1); if (polyGroup) { GA_FOR_ALL_PRIMITIVES(gdp,prim) { if ( (prim->getTypeId()==GEO_PRIMPOLY) && (polyGroup->contains(prim)!=0)) cleave_group->add(prim); else not_cleave_group->add(prim); } } else {
OP_ERROR SOP_PrimGroupCentroid::cookMySop(OP_Context &context) { fpreal now; int method, mode; now = context.getTime(); if (lockInputs(context) >= UT_ERROR_ABORT) return error(); // The partitioning mode. mode = MODE(now); // Find out which calculation method we are attempting. method = METHOD(now); // Binding geometry. if (nConnectedInputs() == 2) { // Duplicate the source. duplicateSource(0, context); // Bind to the centroids. If the function returns 1, unlock // the inputs and return. if (bindToCentroids(now, mode, method)) { unlockInputs(); return error(); } } // Creating centroids. else { // Clear out any previous data. gdp->clearAndDestroy(); // Build the centroids. If the function returns 1, unlock // the inputs and return. if (buildCentroids(now, mode, method)) { unlockInputs(); return error(); } } unlockInputs(); return error(); }
OP_ERROR SOP_UniPdist::cookMySop(OP_Context &context) { // Before we do anything, we must lock our inputs. Before returning, // we have to make sure that the inputs get unlocked. if (lockInputs(context) >= UT_ERROR_ABORT) return error(); // Duplicate input geometry duplicateSource(0, context); float time = context.getTime(); float dist = evalFloat(distanceName.getToken(), 0, time); GA_PointGroup *removeGroup = gdp->newPointGroup(REMOVE_GROUP_NAME); GA_PointGroup *keepGroup = gdp->newPointGroup(KEEP_GROUP_NAME); // Flag the SOP as being time dependent (i.e. cook on time changes) flags().timeDep = 1; //Create a removeAttrib GA_RWHandleI removeAttrib(gdp->addIntTuple(GA_ATTRIB_POINT, "__remove__", 1)); //Creating PointTree GEO_PointTreeGAOffset pttree; //Build PointTree with all the points pttree.build(gdp,NULL); //Create the Array wich holds the distance for the current point in the for loop UT_FloatArray ptdist; // Index offset const GA_IndexMap points = gdp->getPointMap(); GA_Size ptoffsetindex; ptoffsetindex = points.offsetSize()-points.indexSize(); //set all for (GA_Iterator ptoff(gdp->getPointRange()); !ptoff.atEnd(); ++ptoff) { removeAttrib.set(*ptoff,0); } // loop over all points, find second closest point for (GA_Iterator ptoff(gdp->getPointRange()); !ptoff.atEnd(); ++ptoff) { int removeMe; removeMe = int(removeAttrib.get(*ptoff)); if(removeMe) { removeGroup->addIndex(*ptoff-ptoffsetindex); continue; } // Create the Array which holds a list sorted on distance to current point in the for loop GEO_PointTree::IdxArrayType plist; //plist UT_Vector3 pos = gdp->getPos3(*ptoff); // create pos pttree.findAllCloseIdx(pos,dist,plist); // find all points within the search radius unsigned int tempListP = plist.entries(); //create a int for entries in the array for(int i=0;i < tempListP; ++i) { removeAttrib.set(plist[i],1); //set the tempList points to be removed } removeAttrib.set(*ptoff,0); keepGroup->addIndex(*ptoff-ptoffsetindex); } pttree.clear(); //clear the pointtree unlockInputs(); return error(); }
OP_ERROR SOP_IdBlast::cookMySop(OP_Context &context) { fpreal now; exint id; GA_Offset start, end; GA_PointGroup *group; GA_ROAttributeRef id_gah; GA_ROPageHandleI id_ph; UT_String pattern; UT_WorkArgs tokens; IdOffsetMap id_map, srcid_map; GroupIdMapPair pair; now = context.getTime(); if (lockInputs(context) >= UT_ERROR_ABORT) return error(); // Duplicate the incoming geometry. duplicateSource(0, context); // Get the id pattern. IDS(pattern, now); // If it's emptry, don't do anything. if (pattern.length() == 0) { unlockInputs(); return error(); } // Tokenize the range so we can handle multiple blocks. pattern.tokenize(tokens, " "); // Try to find the 'id' point attribute on the 1st input geometry. id_gah = gdp->findPointAttribute(GA_SCOPE_PUBLIC, "id"); // If it doesn't exist, display a node error message and exit. if (id_gah.isInvalid()) { addError(SOP_MESSAGE, "Input geometry has no 'id' attribute."); unlockInputs(); return error(); } // Bind the page handles to the attributes. id_ph.bind(id_gah.getAttribute()); // Iterate over all the points we selected. for (GA_Iterator it(gdp->getPointRange()); it.blockAdvance(start, end); ) { // Set the page handle to the start of this block. id_ph.setPage(start); // Iterate over all the points in the block. for (GA_Offset pt = start; pt < end; ++pt) { // Get the 'id' value for the point. id = id_ph.get(pt); id_map[id] = pt; } } // Create the group. group = createAdhocPointGroup(*gdp); // Add the group and the id map to the pair. pair.first = group; pair.second = &id_map; // Iterate over each block in the tokens and add any ids to the group. for (int i=0; i < tokens.getArgc(); ++i) { UT_String id_range(tokens[i]); id_range.traversePattern(-1, &pair, addOffsetToGroup); } // Destroy the points. gdp->destroyPointOffsets(GA_Range(*group)); unlockInputs(); return error(); }
OP_ERROR aaOceanSOP::cookMySop(OP_Context &context) { if (lockInputs(context) >= UT_ERROR_ABORT) return error(); duplicateSource(0, context); setVariableOrder(3, 2, 0, 1); setCurGdh(0, myGdpHandle); setupLocalVars(); // variable declarations float now = context.getTime(); // Flag the SOP as being time dependent (i.e. cook on time changes) flags().timeDep = 1; // start pulling in SOP inputs and send to aaOcean enableEigens = (ENABLEEIGENS() != 0); if(pOcean->isChoppy() && enableEigens) enableEigens = TRUE; now = now + TIMEOFFSET(now); pOcean->input( RESOLUTION(), SEED(), OCEANSCALE(now), OCEANDEPTH(now), SURFACETENSION(now), VELOCITY(now), CUTOFF(now), WINDDIR(now), WINDALIGN(), DAMP(now), WAVESPEED(now), WAVEHEIGHT(now), CHOP(now), now, LOOPTIME(now), enableEigens, FALSE); // get the user-specified attribute that holds uv-data getUVAttributeName(UvAttribute); if(UvAttribute.length() == 0) UvAttribute = "uv"; const char* UVAttribName = (const char *)UvAttribute; uvRef = gdp->findFloatTuple(GA_ATTRIB_POINT, UVAttribName, 3); if(uvRef.isValid() == TRUE) { uvAttribute = uvRef.getAttribute(); uvTuple = uvRef.getAIFTuple(); } else { // uv attribute not found char msg[256]; sprintf(msg, "[aaOcean] Specified UV attribute \'%s\' not found on geometry.\ \nUV's are required for aaOcean to cook", UVAttribName); std::cout<<msg; std::cout.flush(); addError(SOP_MESSAGE, msg); unlockInputs(); return error(); } // setup local variables to output Eigens if(enableEigens) { eVecPlusRef = gdp->addFloatTuple(GA_ATTRIB_POINT, eVecPlusName, 3); eVecMinusRef = gdp->addFloatTuple(GA_ATTRIB_POINT, eVecMinusName, 3); eValuesRef = gdp->addFloatTuple(GA_ATTRIB_POINT, eValuesName, 1); eVecPlusHandle = GA_RWHandleV3(eVecPlusRef.getAttribute()); eVecMinusHandle = GA_RWHandleV3(eVecMinusRef.getAttribute()); eValuesHandle = GA_RWHandleF(eValuesRef.getAttribute()); } // inputs validated. Begin writing ocean data to output handles int npts = gdp->getNumPoints(); #pragma omp parallel for for (int pt_offset = 0; pt_offset < npts; ++pt_offset) { UT_Vector3F pos = gdp->getPos3(pt_offset); UT_Vector3F UV; uvTuple->get(uvAttribute, pt_offset, UV.data(), 3); // Houdini V coord runs in opposite direction compared to Softimage/Maya // Conforming with other apps to make ocean shape consistent across apps float u = UV.x(); float v = 1.0f - (fmod(UV.y(), 1.0f)); pos.y() += pOcean->getOceanData(u, v, aaOcean::eHEIGHTFIELD); if(pOcean->isChoppy()) { pos.x() += pOcean->getOceanData(u, v, aaOcean::eCHOPX); pos.z() += pOcean->getOceanData(u, v, aaOcean::eCHOPZ); } gdp->setPos3(pt_offset, pos); if(enableEigens) { UT_Vector3F eigenVectorPlusValue; UT_Vector3F eigenVectorMinusValue; float eigenValue; eigenVectorPlusValue.x() = pOcean->getOceanData(u, v, aaOcean::eEIGENPLUSX); eigenVectorPlusValue.y() = 0.0f; eigenVectorPlusValue.z() = pOcean->getOceanData(u, v, aaOcean::eEIGENPLUSZ); eigenVectorMinusValue.x() = pOcean->getOceanData(u, v, aaOcean::eEIGENMINUSX); eigenVectorMinusValue.y() = 0.0f; eigenVectorMinusValue.z() = pOcean->getOceanData(u, v, aaOcean::eEIGENMINUSZ); eigenValue = pOcean->getOceanData(u, v, aaOcean::eFOAM); eVecPlusHandle.set(pt_offset,eigenVectorPlusValue); eVecMinusHandle.set(pt_offset,eigenVectorMinusValue); eValuesHandle.set(pt_offset,eigenValue); } } unlockInputs(); return error(); }