int SOP_PrimGroupCentroid::buildCentroids(fpreal t, int mode, int method) { bool store; exint int_value; const GA_AIFStringTuple *ident_t; GA_Attribute *ident_attrib; GA_Offset ptOff; GA_RWAttributeRef ident_gah; GA_RWHandleI class_h; const GU_Detail *input_geo; UT_BoundingBox bbox; UT_String attr_name, pattern, str_value; UT_Vector3 pos; UT_Array<GA_Range> range_array; UT_Array<GA_Range>::const_iterator array_it; UT_StringArray string_values; UT_IntArray int_values; // Get the input geometry as read only. GU_DetailHandleAutoReadLock gdl(inputGeoHandle(0)); input_geo = gdl.getGdp(); // Check to see if we should store the source group/attribute name as an // attribute the generated points. store = STORE(t); // If we want to we need to create the attributes. if (store) { // A 'class' operation, so create a new integer attribute. if (mode == 2) { // Add the int tuple. ident_gah = gdp->addIntTuple(GA_ATTRIB_POINT, "class", 1); // Bind the handle. class_h.bind(ident_gah.getAttribute()); } // Using the 'name' attribute or groups, so create a new string // attribute. else { attr_name = (mode == 0) ? "group" : "name"; // Create a new string attribute. ident_gah = gdp->addStringTuple(GA_ATTRIB_POINT, attr_name, 1); ident_attrib = ident_gah.getAttribute(); // Get the string tuple so we can set values. ident_t = ident_gah.getAIFStringTuple(); } } // Create a new attribute reference map. GA_AttributeRefMap hmap(*gdp, input_geo); // Get the attribute selection string. ATTRIBUTES(pattern, t); // If we have a pattern, try to build the ref map. if (pattern.length() > 0) buildRefMap(hmap, pattern, gdp, input_geo, mode, GA_ATTRIB_PRIMITIVE); // The list of GA_Primitives in the input geometry. const GA_PrimitiveList &prim_list = input_geo->getPrimitiveList(); // Creating by groups. if (mode == 0) { // Get the group pattern. GROUP(pattern, t); // If the group string is empty, get out of here. if (pattern.length() == 0) return 1; buildGroupData(pattern, input_geo, range_array, string_values); } // 'name' or 'class'. else { // Build the data. If something failed, return that we had an issue. if (buildAttribData(mode, input_geo, range_array, string_values, int_values)) return 1; } // Iterate over each of the primitive ranges we found. for (array_it=range_array.begin(); !array_it.atEnd(); ++array_it) { // Create a new point. ptOff = gdp->appendPointOffset(); // Bounding Box if (method == 1) { // Calculate the bouding box center for this range. boundingBox(input_geo, *array_it, prim_list, pos); // Set the point's position to the center of the box. gdp->setPos3(ptOff, pos); } // Center of Mass else if (method == 2) { // Calculate the center of mass for this range. centerOfMass(*array_it, prim_list, pos); // Set the point's position to the center of mass. gdp->setPos3(ptOff, pos); } // Barycenter else { // Calculate the barycenter for this range. baryCenter(input_geo, *array_it, prim_list, pos); // Set the point's position to the barycenter. gdp->setPos3(ptOff, pos); } // Store the source value if required. if (store) { // 'class', so get the integer value at this iterator index. if (mode == 2) { int_value = int_values(array_it.index()); class_h.set(ptOff, int_value); } // 'name' or by group, so get the string value at this iterator // index. else { str_value = string_values(array_it.index()); ident_t->setString(ident_attrib, ptOff, str_value, 0); } } // If there are no entries in the map then we don't need to copy // anything. if (hmap.entries() > 0) { GA_WeightedSum sum; // Start a weighted sum for the range. hmap.startSum(sum, GA_ATTRIB_POINT, ptOff); // Add the values for each primitive to the sum. for (GA_Iterator it(*array_it); !it.atEnd(); ++it) { hmap.addSumValue(sum, GA_ATTRIB_POINT, ptOff, GA_ATTRIB_PRIMITIVE, *it, 1); } // Finish the sum, normalizing the values. hmap.finishSum(sum, GA_ATTRIB_POINT, ptOff, 1.0/(*array_it).getEntries()); } } return 0; }
OP_ERROR SOP_PrimCentroid::cookMySop(OP_Context &context) { fpreal now; int method; const GA_Attribute *source_attr; const GA_AttributeDict *dict; GA_AttributeDict::iterator a_it; GA_Offset ptOff; GA_RWAttributeRef n_gah; GA_RWHandleV3 n_h; const GEO_Primitive *prim; const GU_Detail *input_geo; UT_BoundingBox bbox; UT_String pattern, attr_name; UT_WorkArgs tokens; now = context.getTime(); if (lockInputs(context) >= UT_ERROR_ABORT) return error(); // Clear out any previous data. gdp->clearAndDestroy(); // Get the input geometry as read only. GU_DetailHandleAutoReadLock gdl(inputGeoHandle(0)); input_geo = gdl.getGdp(); // Find out which calculation method we are attempting. method = METHOD(now); // Create the standard point normal (N) attribute. n_gah = gdp->addNormalAttribute(GA_ATTRIB_POINT); // Bind a read/write attribute handle to the normal attribute. n_h.bind(n_gah.getAttribute()); // Construct an attribute reference map to map attributes. GA_AttributeRefMap hmap(*gdp, input_geo); // Get the attribute selection string. ATTRIBUTES(pattern, now); // Make sure we entered something. if (pattern.length() > 0) { // Tokenize the pattern. pattern.tokenize(tokens, " "); // The primitive attributes on the incoming geometry. dict = &input_geo->primitiveAttribs(); // Iterate over all the primitive attributes. for (a_it=dict->begin(GA_SCOPE_PUBLIC); !a_it.atEnd(); ++a_it) { // The current attribute. source_attr = a_it.attrib(); // Get the attribute name. attr_name = source_attr->getName(); // If the name doesn't match our pattern, skip it. if (!attr_name.matchPattern(tokens)) continue; // Create a new point attribute on the current geometry // that is the same as the source attribute. Append it and // the source to the map. hmap.append(gdp->addPointAttrib(source_attr).getAttribute(), source_attr); } // Copy local variables. if (COPY(now)) { // Traverse the variable names on the input geometry and attempt to // copy any that match to our new geometry. input_geo->traverseVariableNames( SOP_PrimCentroid::copyLocalVariables, gdp ); } } // Get the list of input primitives. const GA_PrimitiveList &prim_list = input_geo->getPrimitiveList(); // Add points for each primitive. ptOff = gdp->appendPointBlock(input_geo->getNumPrimitives()); // Iterate over primitives using pages. for (GA_Iterator it(input_geo->getPrimitiveRange()); !it.atEnd(); ++it) { // Get the primitive from the list. prim = (const GEO_Primitive *) prim_list.get(*it); if (method) { // Get the bounding box for the primitive and set the point's // position to be the center of the box. prim->getBBox(&bbox); gdp->setPos3(ptOff, bbox.center()); } else // Set the point's position to be the bary center of the primitive gdp->setPos3(ptOff, prim->baryCenter()); // Set the point's normal to be the normal of the primitive. n_h.set(ptOff, prim->computeNormal()); // If we are copying attributes, copy the primitive attributes from // the current primitive to the new point. if (hmap.entries() > 0) hmap.copyValue(GA_ATTRIB_POINT, ptOff, GA_ATTRIB_PRIMITIVE, *it); // Increment the point offset. ptOff++; } unlockInputs(); return error(); }
(THREE, = 3, "comment on enum value"), (FOUR, /* value */, /* comment */, { "metadata as a void pointer" }), (FIVE, /* value */, /* comment */, { "metadata as a void pointer" }, "char" /* type of metadata void pointer as string */), (SIX, /* value */, /* comment */, { (mr_enum_t[]){ 2 } }, "mr_enum_t" /* even enum itself */), SEVEN /* trailing comma is optional */ ) TYPEDEF_ENUM (mr_bitmask_t, (NONE, = 0), (FIRST, = 1 << 0), (SECOND, = 1 << 1), (THIRD, = 1 << 2), (FORTH, = 1 << 3), ) TYPEDEF_ENUM (mr_enum_uint8_t, ATTRIBUTES (__attribute__ ((packed, aligned (sizeof (uint8_t))))), UINT8_ZERO, UINT8_ONE, (UINT8_TWO, = 2), (UINT8_THREE, = 3)) TYPEDEF_ENUM (mr_enum_uint16_t, ATTRIBUTES (__attribute__ ((packed, aligned (sizeof (uint16_t))))), UINT16_ZERO, UINT16_ONE, (UINT16_TWO, = 2), (UINT16_THREE, = 3)) TYPEDEF_ENUM (mr_enum_uint32_t, ATTRIBUTES (__attribute__ ((packed, aligned (sizeof (uint32_t))))), UINT32_ZERO, UINT32_ONE, (UINT32_TWO, = 2), (UINT32_THREE, = 3)) TYPEDEF_ENUM (mr_enum_uint64_t, ATTRIBUTES (__attribute__ ((packed, aligned (sizeof (uint64_t))))), UINT64_ZERO, UINT64_ONE, (UINT64_TWO, = 2), (UINT64_THREE, = 3)) TYPEDEF_STRUCT (struct_mr_enum_t, (mr_enum_t, x)) TYPEDEF_STRUCT (struct_mr_enum_uint8_t, (mr_enum_uint8_t, x)) TYPEDEF_STRUCT (struct_mr_enum_uint16_t, (mr_enum_uint16_t, x)) TYPEDEF_STRUCT (struct_mr_enum_uint32_t, (mr_enum_uint32_t, x)) TYPEDEF_STRUCT (struct_mr_enum_uint64_t, (mr_enum_uint64_t, x)) TYPEDEF_STRUCT (struct_mr_bitmask_t, BITMASK (mr_bitmask_t, x))