Reference Keys in Inventor

By Vladimir Ananyev

Issue

How to get the reference key from an occurrence in an assembly and later get back the occurrence from the reference key?

Solution

Each object e.g. face, edge, surface body etc., has unique persistent id (just like handles in AutoCAD) and is referred to as ‘Reference Key’. Reference keys can be obtained using the ‘GetReferenceKey’ method and you can also trace back to the object with just the reference key using ‘BindKeyToObject’.

The sample VBA macro shown below creates a reference key from an occurrence in an assembly, print its name and again from the reference key get back the occurrence and print its name. You will observe that both point to the same occurrence.

 

Sub testRefKeys()

 

  Dim oDoc As Document

  Set oDoc = ThisApplication.ActiveDocument

 

  Dim nKeyCont As Long

  If oDoc.DocumentType = kAssemblyDocumentObject Then

 

    Dim oAssDoc As AssemblyDocument

    Set oAssDoc = oDoc

    Dim oCompDef As AssemblyComponentDefinition

    Set oCompDef = oAssDoc.ComponentDefinition

   

    ‘ Get the key context

    ‘ Calling this method is a must

    nKeyCont = oAssDoc.ReferenceKeyManager.CreateKeyContext

   

    Dim oOcc As ComponentOccurrence

    Set oOcc = oCompDef.Occurrences.Item(1)

   

    ‘Display the occurrence display name

    Debug.Print oOcc.Name

   

    ‘Get the reference Key from occurrence

    Dim oOccRef() As Byte

    Call oOcc.GetReferenceKey(oOccRef, nKeyCont)

   

    ‘Now get the occurrence from Reference Key

    Dim oOccnew As ComponentOccurrence

    Set oOccnew = oAssDoc.ReferenceKeyManager.BindKeyToObject(oOccRef, nKeyCont)

    Debug.Print oOccnew.Name

   

  End If

 

End Sub

 

 

 

void _Run()
{

HRESULT Result=NOERROR;
CLSID AppClsid;
CComPtr<IUnknown> pAppUnk;
CComPtr<Application> App;
 
 
Result = ::CLSIDFromProgID (L"Inventor.Application", &AppClsid);
 
// Latch on to the currently active Inventor session.
Result = ::GetActiveObject (AppClsid, NULL, &pAppUnk);
if (FAILED (Result)){
  printf ("*** Could not get hold of an active Inventor application ***\n");
  return ;
}
 
Result = pAppUnk->QueryInterface (DIID_Application, (void **) &App);
if (FAILED (Result)) return ;
 
//open a document
CComBSTR fname = ("C:\\Temp\\MyAssembly.iam");

 

CComPtr<Documents> pDocs;
Result = App->get_Documents(&pDocs);
 
CComPtr<Document> pDoc;
Result = pDocs->Open(fname, VARIANT_TRUE, &pDoc);
 
CComQIPtr<AssemblyDocument> pAssemDoc(pDoc);
CComPtr<AssemblyComponentDefinition> pAssemCompDef;
Result = pAssemDoc->get_ComponentDefinition(&pAssemCompDef);
 
CComPtr<ReferenceKeyManager> pDispRefMgr;
Result = pAssemDoc->get_ReferenceKeyManager(&pDispRefMgr);
 
long m_dwKeyContext;
Result = pDispRefMgr->CreateKeyContext(&m_dwKeyContext);
 
CComPtr<ComponentOccurrences> pCompOccs;
Result = pAssemCompDef->get_Occurrences(&pCompOccs);
 
CComPtr<ComponentOccurrence> pCompOcc;
Result = pCompOccs->get_Item(1, &pCompOcc);

 

SAFEARRAY *pRefKey =NULL ;
Result = pCompOcc->GetReferenceKey(&pRefKey,m_dwKeyContext);
 
CComBSTR name;
Result = pCompOcc->get_Name(&name);
MessageBox(NULL, name, L"Before binding", 0);

 

CComVariant mtype;
CComPtr<IDispatch> pDispatch;
Result = pDispRefMgr->BindKeyToObject(&pRefKey, m_dwKeyContext, &mtype, &pDispatch);

 

CComQIPtr<ComponentOccurrence> pCompOcc1(pDispatch);
Result = pCompOcc1->get_Name(&name);
MessageBox(NULL, name, L"After binding", 0);
 
}

 

<

p style=”line-height: normal;margin: 0cm 0cm 0pt” class=”MsoNormal”>int main(int argc, char* argv[])
{
CoInitialize(NULL);
 
_Run();
 
CoUninitialize();
return 0;
}


Comments

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading