Colors and materials

In PRC, colors can exist in two places. If the model's vertices are colored individually, then those color values are embedded with the model's tessellation. Otherwise, the colors will be indexed at the product occurrence level. In the latter case, the global material library contains the actual color values. The following subsections demonstrate how to get color values.

Finding color for an entity

Recall that all entities have an associated root base which encapsulates fields common to all entities. If the entity has graphical information, it will also have a root base with graphics node. This is the case for product occurrences and representation items. As you are parsing, get a reference to the graphical information in the following way:

A3DRootBaseWithGraphicsData rbwgData;
A3D_INITIALIZE_DATA(A3DRootBaseWithGraphicsData, rbwgData);
A3DRootBaseWithGraphicsGet(po, &rbwgData);
if (rbwgData.m_pGraphics != NULL)
{
// this entity has an attached graphics object
A3DGraphicsData graphicsData;
A3D_INITIALIZE_DATA(A3DGraphicsData, graphicsData);
A3DGraphicsGet(rbwgData.m_pGraphics, &graphicsData);

When color is set at the entity level, it will have an associated style. You can use the graphicsData object to get the entity's style information.

if (graphicsData.m_uiStyleIndex == A3D_DEFAULT_STYLE_INDEX)
// entity is unstyled
else
// note style index
styleIndex = graphicsData.m_uiStyleIndex;

Note the special identifier A3D_DEFAULT_STYLE_INDEX. If the style index is equal to this constant, then it effectively means the entity has no style information of its own. If the style index is equal to any other value, then that value is an index into the global style array. See the next section for information on how to get the color value from the global array.

Reading colors from the material library

In HOOPS Exchange, global data is embedded in a special node. This node is not part of the model assembly, but its contents are indexed by nodes in the assembly tree. The global information node contains all the defined colors, styles, materials, line patterns, textures, and fill patterns used by the model.

You can get a reference to the node and its data using the following code:

// get global data
A3DGlobalGetPointer(&pGlobal);
A3DGlobalData globalData;
A3D_INITIALIZE_DATA(A3DGlobalData, globalData);
A3DGlobalGet(pGlobal, &globalData);

Getting global style information

When color is set at the entity level, it will have an associated style. Global style data is kept in a simple array, and can be accessed in the following way. Note the m_bMaterial field, which indicates whether the style points to a material or a color:

int numStyles = globalData.m_uiStylesSize;
A3DGraphStyleData styleData;
A3D_INITIALIZE_DATA(A3DGraphStyleData, styleData);
for (size_t n = 0; n < numStyles; ++n)
{
// get the nth style from the global data
A3DGlobalGetGraphStyleData(n, &styleData);
if (styleData.m_bMaterial == true)
// the style points to a material
else
// the style points to a color
}

See the next sections for information on how to get the actual color or material values.

Getting colors

PRC uses indexed colors, which are defined in an array in the material library. To get the colors, we'll use the A3DGraphRgbColorData structure with the styleData.m_uiRgbColorIndex field from the previous subsection. Colors are stored sequentially as RGB triplets, each of type A3DDouble. The relationship looks like this:

A3DGraphRgbColorData sColorData;
A3D_INITIALIZE_DATA(A3DGraphRgbColorData, sColorData);
A3DGlobalGetGraphRgbColorData(styleData.m_uiRgbColorIndex, &sColorData);
// red component
sColorData.m_dRed;
// green component
sColorData.m_dGreen;
// blue component
sColorData.m_dBlue;

Alternatively, if you need to get a list of all defined colors, you could do this:

A3DGraphRgbColorData sColorData;
A3D_INITIALIZE_DATA(A3DGraphRgbColorData, sColorData);
for (size_t i = 0; i < globalData.m_uiColorsSize; ++i)
{
A3DGlobalGetGraphRgbColorData(i * 3, &ColorData);
// red component
sColorData.m_dRed;
// green component
sColorData.m_dGreen;
// blue component
sColorData.m_dBlue;
}

Thus, as you are parsing a PRC entity, note its style index and use it to get the applied color by following the procedure above.

Getting materials and textures

HOOPS Exchange considers textures to be a type of material. If the model you're parsing uses a material or texture, its A3DGraphStyleData::m_bMaterial field will be true. You can determine whether the style is a material or a texture by using the following code:

if (styleData.m_bMaterial == true)
{
A3DBool isTexture = false;
A3DGlobalIsMaterialTexture(graphicsData.m_uiStyleIndex, &isTexture);
if (isTexture == true)
// style is a texture
else
// style is a material

All images, including those used as textures, are stored in a global array separate from the texture definitions. To get the image data associated with a texture, you need to follow the chain from style index to texture definition to picture data. The following example assumes you already have the style index from the previous sections:

A3DGraphTextureDefinitionData tdd;
A3D_INITIALIZE_DATA(A3DGraphTextureDefinitionData, tdd);
// get texture definition associated with the style index
A3DGlobalGetGraphTextureDefinitionData(graphicsData.m_uiStyleIndex, &tdd);
// get the picture index used by the texture definition
A3DGraphPictureData pictureData;
A3D_INITIALIZE_DATA(A3DGraphPictureData, pictureData);
A3DGlobalGetGraphPictureData(tdd.m_uiPictureIndex, &pictureData);
// picture size
pictureData.m_uiSize;
// picture pixels
pictureData.p_ucBinaryData;

Alternatively, if your style is a material, you may need to get the material properties associated with it. Material properties include ambient, diffuse, emissive, specular, and shininess components. Be aware that there are separate components for the color channels and the alpha channel. The material properties are accessed in this way:

A3DGraphMaterialData gmd;
A3D_INITIALIZE_DATA(A3DGraphMaterialData, gmd);
A3DGlobalGetGraphMaterialData(graphicsData.m_uiStyleIndex, &gmd);
gmd.m_uiAmbient; // ambient component
gmd.m_dDiffuseAlpha; // diffuse alpha channel
gmd.m_dShininess; // get material shininess

Retrieving informations about Entity materials

When the input entity is a Representation Item or aPart Definition, material data can be retrieved using A3DMiscGetMaterialProperties. This example prints the name of a entity's material:

A3DStatus PrintMaterialName(const A3DEntity* in_pEntity)
{
A3DMiscMaterialPropertiesData sData;
A3D_INITIALIZE_DATA(A3DMiscMaterialPropertiesData, sData);
A3DStatus iRet = A3DMiscGetMaterialProperties(in_pEntity, &sData);
if(iRet == A3D_SUCCESS)
{
printf("Material Name: %s\n", sData.m_pcMaterialName);
}
A3DMiscGetMaterialProperties(NULL, &sData);
return iRet;
}

Effects of entity references

It should be noted that computed values for inheritance can be supplanted by entity references. Entity references have the effect of replacing an entity's computed attribute values with those of another entity, or applying attributes to subentities such as individual faces. Entity references are explained in this section.

top_level:1 prog_guide:3