# How to traverse linkedItems from markups/PMIs

**URL:** <https://forum.techsoft3d.com/t/how-to-traverse-linkeditems-from-markups-pmis/1462>\
**Category:** HOOPS Exchange\
**Tags:** code, knowledge-base, how-to, product-structure\
**Created:** [April 30, 2022, 4:00am UTC](https://forum.techsoft3d.com/t/how-to-traverse-linkeditems-from-markups-pmis/1462 "2022-04-30T04:00:00Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![gabriel.peragine](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.techsoft3d.com/gabriel.peragine/32/1535_2.png) [@gabriel.peragine](https://forum.techsoft3d.com/u/gabriel.peragine)\
**Post date:** [April 30, 2022, 4:00am UTC](https://forum.techsoft3d.com/t/how-to-traverse-linkeditems-from-markups-pmis/1462/1 "2022-04-30T04:00:00Z")

</div>

The code sample below will dump in the console geometry indexes of all linkedItems associated to root product occurrence markups/PMIs:

```auto
/ ***********************************************************************************************************************
*
* Copyright (c) 2021 by Tech Soft 3D, LLC.
* The information contained herein is confidential and proprietary to Tech Soft 3D, LLC., and considered a trade secret
* as defined under civil and criminal statutes. Tech Soft 3D shall pursue its civil and criminal remedies in the event
* of unauthorized use or misappropriation of its trade secrets. Use of this information by anyone other than authorized
* employees of Tech Soft 3D, LLC. is granted only under a written non-disclosure agreement, expressly prescribing the
* scope and manner of such use.
*
*********************************************************************************************************************** /

#define INITIALIZE_A3D_API
#include <A3DSDKIncludes.h>

#include "../common.hpp"

static MY_CHAR acSrcFileName[_MAX_PATH * 2];
static MY_CHAR acDstFileName[_MAX_PATH * 2];
static MY_CHAR acLogFileName[_MAX_PATH * 2];

void browseRefOnTopo(A3DEntity * pRefOnTopo)
{
	A3DMiscReferenceOnTopologyData miscRefOnTopoData;
	A3D_INITIALIZE_DATA(A3DMiscReferenceOnTopologyData, miscRefOnTopoData);
	A3DMiscReferenceOnTopologyGet(pRefOnTopo, &miscRefOnTopoData);

	A3DTopoBrepDataData brepData;
	A3D_INITIALIZE_DATA(A3DTopoBrepDataData, brepData);
	A3DTopoBrepDataGet(miscRefOnTopoData.m_pBrepData, &brepData);

	printf("face: %d", miscRefOnTopoData.m_puiAdditionalIndexes[0]);

	if(miscRefOnTopoData.m_uiSize > 1)
		printf(" loop: %d", miscRefOnTopoData.m_puiAdditionalIndexes[1]);

	if(miscRefOnTopoData.m_uiSize > 2)
		printf(" edge: %d", miscRefOnTopoData.m_puiAdditionalIndexes[2]);

	if (miscRefOnTopoData.m_uiSize > 3)
		printf(" vertex: %d", miscRefOnTopoData.m_puiAdditionalIndexes[3]);

	printf("\n");
}

void browseLinkedItem(A3DMiscMarkupLinkedItem * pLinkedItem)
{
	A3DMiscMarkupLinkedItemData miscLinkedItemData;
	A3D_INITIALIZE_DATA(A3DMiscMarkupLinkedItemData, miscLinkedItemData);
	A3DMiscMarkupLinkedItemGet(pLinkedItem, &miscLinkedItemData);

	A3DEEntityType eType = kA3DTypeUnknown;
	A3DEntityGetType(miscLinkedItemData.m_pReference, &eType);

	if (eType == kA3DTypeMiscReferenceOnTopology)
	{
		browseRefOnTopo(miscLinkedItemData.m_pReference);
	}
}

void browseMarkup(A3DMkpAnnotationEntity * pMarkup)
{
	A3DEEntityType eType = kA3DTypeUnknown;
	A3DEntityGetType(pMarkup, &eType);

	switch (eType)
	{
		case kA3DTypeMkpAnnotationSet:
		{
			A3DMkpAnnotationSetData annotationSetData;
			A3D_INITIALIZE_DATA(A3DMkpAnnotationSetData, annotationSetData);
			A3DMkpAnnotationSetGet(pMarkup, &annotationSetData);

			for (int i = 0; i < annotationSetData.m_uiAnnotationsSize; i++)
			{
				browseMarkup(annotationSetData.m_ppAnnotations[i]);
			}

			break;
		}

		case kA3DTypeMkpAnnotationReference:
		{
			A3DMkpAnnotationReferenceData annotationRefData;
			A3D_INITIALIZE_DATA(A3DMkpAnnotationReferenceData, annotationRefData);
			A3DMkpAnnotationReferenceGet(pMarkup, &annotationRefData);

			for (int i = 0; i < annotationRefData.m_uiLinkedItemsSize; i++)
			{
				browseLinkedItem(annotationRefData.m_ppLinkedItems[i]);
			}

			break;
		}

		case kA3DTypeMkpAnnotationItem:
		{
			A3DMkpAnnotationItemData annotationItemData;
			A3D_INITIALIZE_DATA(A3DMkpAnnotationItemData, annotationItemData);
			A3DMkpAnnotationItemGet(pMarkup, &annotationItemData);

			A3DMkpMarkupData mkpData;
			A3D_INITIALIZE_DATA(A3DMkpMarkupData, mkpData);
			A3DMkpMarkupGet(annotationItemData.m_pMarkup, &mkpData);

			A3DRootBaseData rbData;
			A3D_INITIALIZE_DATA(A3DRootBaseData, rbData);
			A3DRootBaseGet(annotationItemData.m_pMarkup, &rbData);

			if (rbData.m_pcName != NULL)
			{
				printf("%s (%d linkedItems):\n", rbData.m_pcName, mkpData.m_uiLinkedItemsSize);
			}

			for (int i = 0; i < mkpData.m_uiLinkedItemsSize; i++)
			{
				browseLinkedItem(mkpData.m_ppLinkedItems[i]);
			}

			printf("\n");

			break;
		}
	}
}

//######################################################################################################################
#ifdef _MSC_VER
int wmain(A3DInt32 iArgc, A3DUniChar** ppcArgv)
#else
int main(A3DInt32 iArgc, A3DUTF8Char** ppcArgv)
#endif
{
	//
	// ### COMMAND LINE ARGUMENTS
	//

	if (iArgc < 2)
	{
		MY_PRINTF2("Usage:\n %s [input CAD file] [output CAD file] [output LOG file]\n", ppcArgv[0]);
		MY_PRINTF(" Default output CAD file is [input CAD file].prc\n");
		MY_PRINTF(" Default output LOG file is [output CAD file]_Log.txt\n\n");
		return A3D_ERROR;
	}

	if (iArgc > 1) MY_STRCPY(acSrcFileName, ppcArgv[1]);
	else MY_STRCPY(acSrcFileName, DEFAULT_INPUT_CAD);
	if (iArgc > 2) MY_STRCPY(acDstFileName, ppcArgv[2]);
	else MY_SPRINTF(acDstFileName, "%s.prc", acSrcFileName);
	if (iArgc > 3) MY_STRCPY(acLogFileName, ppcArgv[3]);
	else MY_SPRINTF(acLogFileName, "%s_Log.txt", acDstFileName);
	GetLogFile(acLogFileName); // Initialize log file

	//
	// ### INITIALIZE HOOPS EXCHANGE
	//

	A3DSDKHOOPSExchangeLoader sHoopsExchangeLoader(_T(HOOPS_BINARY_DIRECTORY));
	CHECK_RET(sHoopsExchangeLoader.m_eSDKStatus);
	CHECK_RET(A3DDllSetCallbacksReport(PrintLogMessage, PrintLogWarning, PrintLogError));

	//
	// ### PROCESS SAMPLE CODE
	//

	// specify input file
	A3DImport sImport(acSrcFileName); // see A3DSDKInternalConvert.hxx for import and export detailed parametersc

	A3DStatus importStatus = sHoopsExchangeLoader.Import(sImport);

	A3DAsmModelFileData modelData;
	A3D_INITIALIZE_DATA(A3DAsmModelFileData, modelData);
	A3DAsmModelFileGet(sHoopsExchangeLoader.m_psModelFile, &modelData);

	A3DAsmProductOccurrenceData poData;
	A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, poData);
	A3DAsmProductOccurrenceGet(modelData.m_ppPOccurrences[0], &poData);

        // We only browse trough markups located on the root PO level !

	for (int i = 0; i < poData.m_uiAnnotationsSize; i++)
	{
		browseMarkup(poData.m_ppAnnotations[i]);
	}

	A3DAsmPartDefinitionData partDefData;
	A3D_INITIALIZE_DATA(A3DAsmPartDefinitionData, partDefData);
	A3DAsmPartDefinitionGet(poData.m_pPart, &partDefData);

	for (int i = 0; i < partDefData.m_uiAnnotationsSize; i++)
	{
		browseMarkup(partDefData.m_ppAnnotations[i]);
	}

	//
	// ### TERMINATE HOOPS EXCHANGE
	//

	return A3D_SUCCESS;
}

```

---

<div class="post-metadata">

**Author:** ![minh](https://avatars.discourse-cdn.com/v4/letter/m/53a042/32.png) [@minh](https://forum.techsoft3d.com/u/minh)\
**Post date:** [February 4, 2025, 2:08pm UTC](https://forum.techsoft3d.com/t/how-to-traverse-linkeditems-from-markups-pmis/1462/2 "2025-02-04T14:08:38Z")

</div>

> [@gabriel.peragine](#):
>
> below will dump in the console geometry i

Where is HOOPS\_BINARY\_DIRECTORY configured?

---

<div class="post-metadata">

**Author:** ![tino](https://avatars.discourse-cdn.com/v4/letter/t/9dc877/32.png) [@tino](https://forum.techsoft3d.com/u/tino)\
**Post date:** [February 4, 2025, 2:38pm UTC](https://forum.techsoft3d.com/t/how-to-traverse-linkeditems-from-markups-pmis/1462/3 "2025-02-04T14:38:55Z")

</div>

Hello @minh,

The binary directory refers to _HOOPS\_Exchange\_Publish\_2024.X.x\bin\win64\_v142_. Additional Exchange examples can be found in the Visual Studio solution included in the Exchange package:

HOOPS\_Exchange\_Publish\_2024.X.x\samples\exchange.sln

Thanks,  
Tino
