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();
}
Beispiel #3
0
	      (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))