[SESI logo]

Houdini Development Toolkit - Version 6.5

Side Effects Software Inc. 2004

Geometry

Attributes

Attributes

Each geometry entity (points, vertices, primitives and details) may have arbitrary attribute data associated with them. There are some restrictions (i.e. if one point has an attribute bound to it, then all points must have the same attribute), but the attribute data mechanism is fairly flexible.

Each attribute is defined by the GB_Attribute class and consists of:

  • A name (preferrably unique)
  • A type, which is one of the following enums:
  • GB_ATTRIB_FLOAT - Floating point data
  • GB_ATTRIB_INT - Integer data
  • GB_ATTRIB_STRING - This should not be used and is only provided for backward compatibility (see GB_ATTRIB_INDEX)
  • GB_ATTRIB_MIXED - Unlike other data, this data is of mixed types. Houdini will be unable to save or load attributes of this type, so in fact, this data will be "hidden". Attributes of this type can be used to store simple classes or structs.
  • GB_ATTRIB_INDEX - The data associated with attributes of this type is a single integer. The attribute also contains a list of strings which can be indexed by the integer data.
  • GB_ATTRIB_VECTOR - Three floats which are handled as a special case in transformations on the geometry. Attributes of this type are transformed according to the rules for "normal" transforms.
  • A size (which is specified in bytes).
  • A default value (may be a null pointer)
  • A list of strings (for index attributes)
  • The detail (container class for all points and primitives) contains four sets of attribute "dictionaries". Each dictionary contains a list of attributes with their offsets into the void * array for each data element.

    For example, to add a point attribute called "specular_color" representing an RGB color:

    static float def_value[3] = { 1, 1, 1 }; GEO_Detail *gdp; int id; id = gdp->addPointAttrib("specular_color", sizeof(float)*3, GB_ATTRIB_FLOAT, def_value);

    The id returned by the addPointAttrib method is the "offset" into a void * array stored with every point in the detail. Adding the attribute will cause every point to allocate enough space to store the color data. If the function fails, a negative id will be returned. To access the data for each point, you must ask the point for it's attribute data at the id specified. For example:

    int i; for (i = 0; i < gdp->points().entries(); i++) { GEO_Point *ppt; float *clr; ppt = gdp->points()(i); clr = (float *)ppt->getAttribData(id); clr[0] = drand48(); clr[1] = drand48(); clr[2] = drand48(); }

    There are also methods available to:

  • findPointAttrib(...) - Find a point attribute
  • destroyPointAttrib(...) - Destroy a point attribute
  • Accessing GB_ATTRIB_INT or GB_ATTRIB_VECTOR attributes is very similar. The interface is also fairly similar for:
  • addVertexAttrib(...) - Manipulate vertex attributes
  • addPrimAttrib(...) - Manipulate primitive attributes
  • addAttrib(...) - Manipulate detail attributes
  • It is also possible to access the dictionary and avoid the wrapper methods. To do this, call one of the methods:

  • pointAttribs()
  • primitiveAttribs()
  • vertexAttribs()
  • attribs()
  • which will return a reference to the appropriate dictionary. This is currently stored as a linked list of attribute table entries. It is possible to traverse the list and query attributes by hand.

    Accessing attributes of type GB_ATTRIB_INDEX are a little trickier to deal with since a pointer to the GB_Attribute * is required. Strings may be added by calling addIndex on the attribute. However, you might want to use a little caution. The attribute class currently does not check for duplicate strings, so it's possible to add the same string multiple times. The string added is copied to local storage so it isn't necessary to maintain pointers to the strings. Here is a simple example on using indexed strings as primitive attributes:

    GEO_Detail *gdp; const char *strings[] = { "butterfly1.pic", "butterfly2.pic", "butterfly3.pic", "butterfly4.pic", }; int string_index[4]; GB_Attribute *atr; int i, id; int def_int = -1; id = gdp->addPrimAttrib("texmap", sizeof(int), GB_ATTRIB_INDEX, &def_int); atr = gdp->primAttribs().find("texmap", sizeof(int), GB_ATTRIB_INDEX); assert(atr && "We just added the attribute so it better exist"); // Now, add the strings to the attribute for (i = 0; i < 4; i++) string_index[i] = atr->addIndex(strings[i]); // Now, set the attribute data for (i = 0; i < gdp->primitives().entries(); i++) { GEO_Primitive *prim; int *attrib_data; prim = gdp->primivies()(i); attrib_data = (int *)prim->getAttribData(id); *attrib_data = i % 4; }
    Table of Contents
    Operators | Surface Operations | Particle Operations | Composite Operators | Channel Operators
    Material & Texture | Objects | Command and Expression | Render Output |
    Mantra Shaders | Utility Classes | Geometry Library | Image Library | Clip Library
    Customizing UI | Questions & Answers

    Copyright © 2004 Side Effects Software Inc.
    477 Richmond Street West, Toronto, Ontario, Canada M5V 3E7