6.0 Markup and Views

In HOOPS Exchange, markup refers to PMI and all the supporting infrastructure related to displaying it with the model. HOOPS Exchange groups this data into the markup module. Most markup is represented as tessellation, although text can be represented as either tessellation or semantic data.

A model containing PMI

Despite being an important part of the PRC standard, markup is not represented by an entity type. Instead, one of three annotation entities are used. Annotation entities are represented by A3DMkpAnnotationEntity structures, and the structure can be one of three types:

Annotation entities may be present on product occurrences or part definitions.

Parsing annotation entities

Each type of annotation entity should be parsed in a slightly different manner in order to extract all information contained within. The following examples demonstrate how to do this. First, you'll want to get the annotation type:

A3DMkpAnnotationEntity* ae = // get annotation entity
A3DEEntityType entityType;
A3DEntityGetType(ae, &entityType);

Next, test the type. If it is an annotation set, this means the entity contains other annotations. Your parsing function should process each one. Here are a few examples of parsing annotation entities based on their types. Annotation sets are quite simple:

if (entityType == kA3DTypeMkpAnnotationSet)
{
A3DMkpAnnotationSetData annotationSet;
A3DMkpAnnotationSetGet(ae, &annotationSet);
for (int i = 0; i < annotationSet.m_uiAnnotationsSize; i++)
{
parseAnnotation(annotationSet.m_ppAnnotations[i];
}
}

If the entity is of type kA3DTypeMkpAnnotationItem, parsing is more complicated as there are possible subtypes. There will also be a markup node hanging off the annotation item in the field m_pMarkup.

else if (entityType == kA3DTypeMkpAnnotationItem)
{
// get the markup node
A3DMkpMarkup* markupNode = aid.m_pMarkup;
// at this point, you can call A3DEntityGetType to test the markup node type
A3DEEntityType markupNodeType;
A3DEntityGetType(markupNode, &markupNodeType);

If markupNodeType comes back as the general type A3DMkpMarkup, then the node contains only tessellation. If it comes back as one of the more specific classes, such as A3DMarkupText or A3DMarkupDimension, then you have tessellation plus semantic data.

NOTE: Tessellation is always available, so you are guaranteed to at least get a A3DMkpMarkup structure. For an illustration of the related type hierarchy, see the diagram in the detailed description of this page.

Since tessellation is always available, you can start by getting it before anything else.

A3DMkpMarkupData markupNodeData;
A3DMkpMarkupGet(markupNode, &markupNodeData);
// since tessellation is always available, you can get it from the markupNodeData
A3DTessMarkupData tessMarkupData;
A3DTessMarkupGet(markupNodeData.m_pTessellation, &tessMarkupData);

6.1 Linked items

In the preceding code snippet, the A3DMkpMarkupData object may also contain definitions for leader lines and linked items. A3DMkpLeader has a tessellation field (which may be NULL), plus an array of linked items. A linked item represents a link between a markup object and an entity such as a solid, a topological entity, a construction entity, a coordinate system, or even another markup.

For example, if you have a dimension line which indicates the distance between two planes, the dimension is a markup object. It will have two A3DMiscMarkupLinkedItem references, and each reference will define a link to a plane.

The next step is to decide how you will parse the markup node. This depends on its entity type. Each markup type is quite different and warrants its own parsing method.

// get entity type
A3DEntityGetType(markupNode, &entityType);
switch (entityType)
{
// the markup is of a general type - only tessellation
// we have a text markup - tessellation plus semantic data
// a dimension markup - tessellation plus semantic data
// test for other types
}
}

Show and delete behaviors

In A3DMiscMarkupLinkedItem, note the boolean fields such as m_bMarkupDeleteControl and m_bLeaderShowControl, which enable you to control what happens when a referenced entity is deleted, hidden, or shown. For example, if the m_bMarkupDeleteControl flag is enabled, then the markup will be deleted when the entity is deleted. Similarly, if the m_bLeaderShowControl is enabled, then the markup is shown when the associated entity is shown.

6.2 Markup views

PMI items are often organized under PMI views. A PMI view includes a camera and defines a particular model state - often including visibility for particular parts, certain PMI items, highlighted parts, or even has some parts arranged in an exploded view. All of these things are managed by linked items.

The purpose of a PMI view is to arrange the model to convey a certain idea. The HOOPS Exchange type for a PMI view is A3DMkpViewData. This object can be part of a product occurrence or a part definition.

To get data associated with a view:

// get parent object - in this case we'll use a product occurrence
CHECK_RET(A3DAsmProductOccurrenceGet(productOccurrence, &pod));
// there may be multiple views - check each one
for (unsigned int j = 0; j < pod.m_uiViewsSize; j++)
{
// get view data object
A3DMkpViewGet(pod.m_ppViews[j], &mvd);
// get view name
A3DRootBaseData rbdView;
A3DRootBaseGet(pod.m_ppViews[j], &rbdView);
rbdView.m_pcName; // field has the view name as a string
// get camera
A3DGraphSceneDisplayParametersData* displayParameters = mvd.m_psSceneDisplayParameters;
A3DGraphCamera camera = displayParameters.m_pCamera; // field has the camera
// get display filters to show or hide your geometry
}

PMI is often arranged on a single plane. The view object defines this plane in the A3DMkpMarkupViewData::m_pPlane field.

Linked items defined in the view will affect the state of the model. For example, visibility for particular parts, PMI items, highlighted parts, or the location of bodies can all be affected by a linked item. A3DMkpViewData.m_ppAnnotations defines the markup items associated to the view, while A3DMkpViewData::m_ppLinkedItems->m_pReference points to the linked entity.

In some cases, markups associated to a product occurrence can be displayed in a view associated to another product occurrence. Markups or geometry not associated to any view can also be displayed or hidden in the view. For example, in the diagram below, ProductOccurrence1 has a markup (Markup1) associated with its view. However, ProductOccurrence2 and View2 have a linked item which refers to Markup1. This means Markup1 will be displayed in View2.

Visibility is affected when using a linked item in this way. The item contained in A3DMiscMarkupLinkedItemData::m_pReference will see its default visibility changed in the view. If the visibility is on by default, the entity's visibility will be turned off in View2. Conversely, the visibility will be turned on if it was off by default.

Markups and bodies are not the only items you can have in a linked item, you can also manage the position of the items in a view. You can redefine the position of the parts of an assembly using a linked item, for example, to create an exploded view. You will define a new coordinate system for the position of the entity you want to adjust, and set this entity in A3DMiscMarkupLinkedItemData::m_pReference. Don't forget to specified on which PO the item belongs (or set to NULL if the item is at the same level).

Here, we are creating an exploded view, one of the two PO of the model will be "exploded":

// creating the linked item
A3DMiscMarkupLinkedItem* pMarkupLinkedItem = NULL;
// setting the target ProductOccurrence to NULL if the reference is at the same level as the PO,
// or to the level above if the PO tree has several levels
sLinkedItemData.m_pTargetProductOccurrence = NULL;
// setting a non-null reference to create the LI
sLinkedItemData.m_pReference = sData.m_ppPOccurrences[0];
CHECK_RET(A3DMiscMarkupLinkedItemCreate(&sLinkedItemData, &pMarkupLinkedItem));
// creating the entity reference containing the new coordinate system
A3DMiscEntityReferenceData sEntityReferenceData;
// applying the new coordinate system on the first ProductOccurrence
sEntityReferenceData.m_pEntity = sData.m_ppPOccurrences[0];
sEntityReferenceData.m_pCoordinateSystem = psRiCoordinateSystem;
// setting the linked item with the new entity reference
CHECK_RET(A3DMiscEntityReferenceSet(pMarkupLinkedItem, &sEntityReferenceData));
// adding the linked item to the view and creating of the view
mkpViewData.m_uiLinkedItemsSize = 1;
mkpViewData.m_ppLinkedItems = (A3DMiscMarkupLinkedItem**)
malloc(size_t(mkpViewData.m_uiLinkedItemsSize) * sizeof(A3DMiscMarkupLinkedItem*));
mkpViewData.m_ppLinkedItems[0] = pMarkupLinkedItem;

To summarize, when determining how a view should be arranged, you must consider three things:

Not all CAD model files have markups, linked items, or filters in their views. Some file formats do not support these entities, so your application must decide how to handle each situation based on the type of file you are parsing.