4.1 Getting tessellation

Tessellation entities represent polygon facets. HOOPS Exchange can use a variety of structures for tessellation, and they are all parsed in a slightly different way. Additionally, since representation items can also store B-rep, there is a specific flow to interpreting them. Assuming you have a reference to the representation item, the general operation is as follows:

Controlling tessellation delivery

HOOPS Exchange can give you the tessellation for any representation item at any time. However, for many applications, getting the default tessellation is not sufficient because your application may have specific expectations for how it is formed. For this reason, HOOPS Exchange gives you the ability to control how tessellation is delivered. The A3DRWParamsTessellationData structure has various fields that affect the delivery:

An example of using the A3DRWParamsTessellationData structure is shown below:

A3DRWParamsTessellationData tessellationParameters;
// setting the tessellation detail to 'extra low'
// the tessellation itself is retrieved by this call
pRepItem, &tessellationParameters);
// get the representation item associated with the tessellation you requested
A3DRiRepresentationItemGet(pRepItem, &repItemData);

The effect of some of the settings can be seen in this chart:

Level of detailAccurateTessellation == trueAccurateTessellation == false
low
medium
high

More examples of the various quality settings can be found here.

Finding the tessellation type

After the tessellation is generated by a call to A3DRiRepresentationItemGetTessellation, HOOPS Exchange can use a variety of different data structures to represent tessellation depending on how the triangles are arranged. Therefore, to get the actual geometry that makes up the tessellation, you first need to examine the tessellation type before getting a reference to the underlying data structure. Possible types include:

Like B-rep, tessellation is always stored as part of a representation item. The tessellation types have the following UML relationships:

When you ask HOOPS Exchange to examine a representation item and return the tessellation type, it will return the type as some constant starting with kA3DTypeTess. The A3DEntityGetType method gets this constant for any HOOPS Exchange object, including tessellation types. Therefore, you could do this to get the type:

A3DEntityGetType(repItemData.m_pTessBase, eType);
// find out the object's type
switch (eType)
{
// handle tessellation with normals and index array
A3DTess3DData sTess3DData;
A3DTess3DGet(pTess3D, &sTess3DData);
// handle wire tessellation
// ...
// handle triangle tessellation
// ...
// test for other types
}

4.1.1 Getting the triangles

Getting the tessellated triangles from a PRC representation item can be complicated for the uninitiated. However, by following the steps below, the operation should be simpler to understand:

Step 1: Get the tessellation vertices

Now that you know the tessellation type and have a reference to the data structure, you can get the vertices and faces that make up the geometry. To get the raw points associated with the model, examine the representation item's m_pTessBase::m_pdCoords field:

// get the tessellation base entity from the representation item
A3DTessBase* tessBase = riData.m_pTessBase;
// fill the tessellation data structure
A3DTessBaseData tessBaseData;
A3DTessBaseGet(tessBase, &tessBaseData);
for (unsigned int n = 0; n < tessBaseData.m_uiCoordSize; n++)
{
// get each coordinate
tessBaseData.m_pdCoords[n];
}

Step 2: Accessing the index array

The code snippet in Step 1 gives you the model's vertices but does not tell you how the faces are connected. Connectivity information is stored in an array within each tessellation structure. For example, in A3DTess3DData, the m_puiTriangulatedIndexes array.

For this example, imagine our index array looks like this:

// pseudocode example
sTess3DData.m_puiTriangulatedIndexes = [ X X X 6 12 15 21 24 27 30 33 36
39 45 48 51 54 60 81 84 87 90 93 96 99
105 102 108 111 114 117 130 ]
// offset into m_puiTriangulatedIndexes where data begins

This array controls the relationship between points and faces. The meaning of each value will be explained in Step 4. But we need one more piece of information first.

Step 3: Find tessellation representation

CAD systems will often optimize lists of triangles by removing redundant vertices and forming triangle strips or fans. HOOPS Exchange uses the same concepts to represent tessellation in PRC. A3DTess3DData::m_psFaceTessData::m_usUsedEntitiesFlags is a bit field flag which indicates the types of tessellation present in the tessellation structure. Possible tessellation types include triangles, triangle strips, and triangle fans. You should check which types of tessellation are present because the result will affect the way the rest of the structure is interpreted.

A3DTess3DData sTess3DData;
A3DTess3DGet(pTess3D, &sTess3DData);
// iterate over the faces
A3DUns32 tessArraySize = sTess3DData.m_uiFaceTessSize;
for (int i = 0; i < tessArraySize; i++)
{
A3DTessFaceData &sTessFaceData = sTess3DData.m_psFaceTessData[i];
// get the specific tessellation type
if (sTessFaceData.m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleStripe)
// triangle strips are used
;
if (sTessFaceData.m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleFan)
// triangle fans are used
;

Step 4: Interpret index array

Finally, we have enough information to get the complete tessellation. The A3DTess3DData::m_psFaceTessData::m_puiSizesTriangulated field is the array which brings together all the information we've collected. Let's imagine that the array has this value:

// pseudocode example
m_puiSizesTriangulated = [ 3 2 7 6 1 7 ]

This array represents the tessellation types and the number of vertices that correspond to that type. Tessellation metadata is always packed in the following way:

We'll use this information to interpret the array in the following code snippet. This is one such arrangement the array could represent:

In this image, the red color indicates individual triangles, the orange indicates triangle strips, and the grey indicates triangle fans. The numbers on the vertices correspond to the array A3DTess3DData::m_puiTriangulatedIndexes, which in turn indexes the A3DTessBaseData::m_pdCoords array. Revisiting the m_puiTriangulatedIndexes array:

// pseudocode example
// offset into m_puiTriangulatedIndexes where data begins
// the index array
sTess3DData.m_puiTriangulatedIndexes = [ X X X 6 12 15 21 24 27 30 33 36 // three triangles
39 45 48 51 54 60 81 84 87 90 93 96 99 // two fans
105 102 108 111 114 117 130 ] // one strip

From m_puiSizesTriangulated with value [ 3 2 7 6 1 7 ], we know we have 3 triangles - starting from offset 2 in the array - and they are made from the indices [6 12 15], [21 24 27], and [30 33 36]. Each of these indices point to a set of 3 entries in m_pdCoords. Using this information, we know the first triangle would have these points:

Next, m_puiSizesTriangulated indicates we have 2 triangle fans. It also tells us the first fan has 7 indices - [39 45 48 51 54 60 81], and the second fan has 6 - [84 87 90 93 96 99]. Finally, we read the triangle strips. We have one strip: [105 102 108 111 114 117 130].

Summary

A3DTess3DData::m_psFaceTessData::m_pucRGBAVertices has the tessellation color data

At this point, you know the type of tessellation and can process it accordingly. All that is left is to represent the relevant data from the 3D tessellation data element in your export structure.

For an example on creating tessellation entities, see this tessellation example.