{"id":11448,"date":"2020-03-13T07:52:51","date_gmt":"2020-03-13T11:52:51","guid":{"rendered":"https:\/\/blogs.sw.siemens.com\/solidedge\/?p=11448"},"modified":"2026-03-26T07:31:40","modified_gmt":"2026-03-26T11:31:40","slug":"storing-roadmap-of-an-object-using-solid-edge-api","status":"publish","type":"post","link":"https:\/\/blogs.sw.siemens.com\/solidedge\/storing-roadmap-of-an-object-using-solid-edge-api\/","title":{"rendered":"Storing the Roadmap of an Object using Solid Edge API"},"content":{"rendered":"\n<p>Many Solid Edge automation users would like to store the roadmap of an object so that they can get the same object back across different sessions. In this article, I will walk you through the recommended way to achieve this in Solid Edge. <\/p>\n\n\n\n<p>Roadmap can be stored for many objects such as Body, Curve, Face, Edge, Vertex, etc. In this example, I am assuming that the entity for which user would like to store the roadmap is &#8220;Face&#8221;.<\/p>\n\n\n\n<p><strong>What is a ReferenceKey ? How can I get ReferenceKey of a face? <\/strong><\/p>\n\n\n\n<p>ReferenceKey is mainly used in automation and it&#8217;s the ID of an object in Solid Edge. Automation users can get this ID with the help of&nbsp; GetReferenceKey method available on that object. GetReferenceKey method returns an array of bytes. This key can be stored and used later to get the same object back. The most important thing is this key can be used across multiple sessions. <\/p>\n\n\n\n<p>Below is the sample code to get the ReferenceKey of a face in C++. &nbsp;You can use it for objects on which GetReferenceKey method is available. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FacePtr pFacePtr = pFaces-&gt;Item(IndexFace);\nSAFEARRAY* sapInputRefKey = NULL;\npFacePtr-&gt;GetReferenceKey(&amp;sapInputRefKey);<\/code><\/pre>\n\n\n\n<p><strong>Where to store  ReferenceKey?<\/strong> <strong>How?<\/strong><\/p>\n\n\n\n<p>Now that the user got ReferenceKey, the next question is where to store it so that it can be accessed via automation as and when required. Please don&#8217;t store the ReferenceKey in a separate file to avoid the possibilities of file being deleted\/modified in future. It should be stored such that it&#8217;s not easily accessible interactively.<\/p>\n\n\n\n<p>I would recommend storing it to AddInsStorage so that the valid ReferenceKey will be available via automation anytime in future. AddInsStorage property is available for all types of Solid Edge files. Since Solid Edge also uses <a href=\"https:\/\/en.wikipedia.org\/wiki\/COM_Structured_Storage\" target=\"_blank\" rel=\"noopener\">COM Structured Storage<\/a> to store data, it&#8217;s safe to save user data here as well. <\/p>\n\n\n\n<p>Here&#8217;s the sample code to open the file storage and add a new stream:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PartDocumentPtr pPartDoc1;\n_bstr_t bstrDocName1; \n\/\/ empty string will cause GetDocPtr to retrieve the active document\nGetDocPtr(bstrDocName1,pPartDoc1);\nif (!pPartDoc1)\nreturn E_FAIL;\nif(NULL == pStorage)\n\tpStorage = pPartDoc1-&gt;GetAddInsStorage(L\"MyStorage1\", 0);\n\n\/\/ Create a new stream in the storage.\nhr = pStorage-&gt;OpenStream(L\"Info1\", NULL, STGM_DIRECT | STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &amp;pStream);\n\nif(NULL == pStream)\n\tpStorage-&gt;CreateStream(L\"Info1\", STGM_DIRECT | STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &amp;pStream);\n\n\/\/ sapInputRefKey is the ReferenceKey of face.\nSaveAddInStorageInfo(pDoc,sapInputRefKey);<\/code><\/pre>\n\n\n\n<p>The byte array that you get from GetReferenceKey method can\u2019t be stored as is. You will have to convert it to string as shown in sample code below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void SaveAddInStorageInfo(LPDISPATCH theDocument, SAFEARRAY* sapInputRefKey)\n{\n\tSolidEdgeDocumentPtr pDocument = NULL;\n\tpDocument = theDocument;\n\t\/\/ Get SE ReferenceKey Data....\n\tSAFEARRAY* pSERefKey = sapInputRefKey;\n\tVARTYPE vt;\n\t\/\/ Get the VARTYPE of the data stored inside the SAFEARRAY.\n\tSafeArrayGetVartype(pSERefKey, &amp;vt);\n\t\/\/ This should be VT_UI1 (byte).\n\tif (vt != VT_UI1)\n\treturn;\n\n\t\/\/ Get the number of dimensions in the SAFEARRAY.\n\tUINT uiDim = SafeArrayGetDim(pSERefKey);\n\t\/\/ This should be just 1.\n\tif (uiDim != 1)\n\treturn;\n\n\tlong lLBound = 0, lUBound = 0;\n\t\/\/ Obtain the lower and upper bounds of dimension 1 of the SAFEARRAY.\n\tSafeArrayGetLBound(pSERefKey, 1, &amp;lLBound);\n\tSafeArrayGetUBound(pSERefKey, 1, &amp;lUBound);\n\n\t\/\/ At present, I am assuming that every ReferenceKey lLBound equal to '0' &amp; lUBound should always greater then '0'.\n\tif ((lLBound != 0) || (lUBound &lt;= 0))\n\treturn;\n\n\t\/\/ Connect to the addin storage specifying the storage name.\n\t\/\/ Add RefKey Byte data .............\n\tfor (long l = lLBound; l &lt;= (lUBound ); l++)\n\t{\n\t\tbyte byValue = 0;\n\t\tSafeArrayGetElement(pSERefKey, &amp;l, (void*)&amp;byValue);\n\t\tULONG pcbWritten = 0;\n\t\tpStream-&gt;Write(&amp;byValue, sizeof(byte), &amp;pcbWritten);\n\t}\t\n\t\n}\n<\/code><\/pre>\n\n\n\n<p>Please note that it must to commit the stream after writing the data as shown below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pStream-&gt;Commit(STGC_DEFAULT | STGC_OVERWRITE); <\/code><\/pre>\n\n\n\n<p><strong>How to read  ReferenceKey from storage and highlight the face?<\/strong><\/p>\n\n\n\n<p>Once the data is stored in File storage the next step is to read the data from storage. The code below will read the data from storage, convert it back to byte array, and then bind it using BindKeyToObject to highlight the face.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>for (long IndexFace = 0; IndexFace &lt; nFaceCount; ++IndexFace)\n{\nFacePtr pFacePtr = pFaces-&gt;Item(IndexFace + 1);\t\t\t\t\t\nvariant_t oVarPersist = NULL;\nlong sizeToRead = 0;\npStream-&gt;Read(&amp;sizeToRead, sizeof(long), &amp;pcbRead);\n\t\t\t\nSAFEARRAYBOUND  rgsabound[] = { sizeToRead,0 };\n\n\/\/set data type variant going to hold\noVarPersist.vt = VT_ARRAY | VT_UI1;\n\/\/create safe array from above data\noVarPersist.parray = SafeArrayCreate(VT_UI1, 1, rgsabound);\n\t\t\t\t\t\nfor (long index = 0; index &lt;= sizeToRead; index++)\n\t\t{\n\t\t\tbyte bref = 0;\n\t\t\tpStream-&gt;Read(&amp;bref, sizeof(byte), &amp;pcbRead);\n\t\t\t\t\t\t\n\t\t\thr = SafeArrayPutElement(oVarPersist.parray, &amp;index, (void*)&amp;bref);\n\t\t}\n\t\t\tLPDISPATCH lpDispObj = NULL;\n\t\t\tpPartDoc1-&gt;BindKeyToObject(&amp;(oVarPersist.parray), &amp;lpDispObj);\n\t\t\tpPartDoc1-&gt;GetSelectSet()-&gt;Add(lpDispObj);\n}\n<\/code><\/pre>\n\n\n\n<p>I hope you&#8217;ll find this information useful. Happy Coding. \ud83d\ude0a <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post, I&#8217;ll walk you through how to store a roadmap of an object using the ReferenceKey automation in Solid Edge to access the same object across different sessions.<\/p>\n","protected":false},"author":56576,"featured_media":11485,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spanish_translation":"","french_translation":"","german_translation":"","italian_translation":"","polish_translation":"","japanese_translation":"","chinese_translation":"","footnotes":""},"categories":[96],"tags":[253],"industry":[],"product":[],"coauthors":[],"class_list":["post-11448","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tips-tricks","tag-referencekey"],"featured_image_url":"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/8\/2020\/03\/Header.jpg","_links":{"self":[{"href":"https:\/\/blogs.sw.siemens.com\/solidedge\/wp-json\/wp\/v2\/posts\/11448","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.sw.siemens.com\/solidedge\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.sw.siemens.com\/solidedge\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/solidedge\/wp-json\/wp\/v2\/users\/56576"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/solidedge\/wp-json\/wp\/v2\/comments?post=11448"}],"version-history":[{"count":4,"href":"https:\/\/blogs.sw.siemens.com\/solidedge\/wp-json\/wp\/v2\/posts\/11448\/revisions"}],"predecessor-version":[{"id":11503,"href":"https:\/\/blogs.sw.siemens.com\/solidedge\/wp-json\/wp\/v2\/posts\/11448\/revisions\/11503"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/solidedge\/wp-json\/wp\/v2\/media\/11485"}],"wp:attachment":[{"href":"https:\/\/blogs.sw.siemens.com\/solidedge\/wp-json\/wp\/v2\/media?parent=11448"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/solidedge\/wp-json\/wp\/v2\/categories?post=11448"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/solidedge\/wp-json\/wp\/v2\/tags?post=11448"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/solidedge\/wp-json\/wp\/v2\/industry?post=11448"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/solidedge\/wp-json\/wp\/v2\/product?post=11448"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/solidedge\/wp-json\/wp\/v2\/coauthors?post=11448"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}