<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Custom GUID in Archicad C++ API</title>
    <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247589#M4275</link>
    <description>&lt;DIV class="actalk-migrated-content"&gt;I'm playing around with different Create functions. I have noticed that a new element has always new GUID. When I'm passing GUID in element it is getting new GUID anyway. In some cases, I would like to define my own GUID and create an element with it. Is this possible?&lt;/DIV&gt;</description>
    <pubDate>Thu, 06 Oct 2022 11:04:02 GMT</pubDate>
    <dc:creator>Anonymous</dc:creator>
    <dc:date>2022-10-06T11:04:02Z</dc:date>
    <item>
      <title>Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247589#M4275</link>
      <description>&lt;DIV class="actalk-migrated-content"&gt;I'm playing around with different Create functions. I have noticed that a new element has always new GUID. When I'm passing GUID in element it is getting new GUID anyway. In some cases, I would like to define my own GUID and create an element with it. Is this possible?&lt;/DIV&gt;</description>
      <pubDate>Thu, 06 Oct 2022 11:04:02 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247589#M4275</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2022-10-06T11:04:02Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247590#M4276</link>
      <description>No, it's not possible. The GUID will be generated by ARCHICAD for the new elements.&lt;BR /&gt;
What's your purpose? Why do you need an element with your specific own GUID?&lt;BR /&gt;
&lt;BR /&gt;
You can set custom 'Element ID' string to the elements. That could be also a good way to identify your own elements.&lt;BR /&gt;
Or you can set custom userdata for the elements using ACAPI_Element_SetUserData function.&lt;BR /&gt;
Or you can create your own property definition and set that property to any custom value/string for the elements.</description>
      <pubDate>Thu, 27 Sep 2018 14:55:08 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247590#M4276</guid>
      <dc:creator>Tibor Lorantfy</dc:creator>
      <dc:date>2018-09-27T14:55:08Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247591#M4277</link>
      <description>Thx I will look into it. I thought it will be simpler &lt;IMG src="https://community.graphisoft.com/legacyfs/online/emojis/icon_biggrin.gif" style="display : inline;" /&gt;.&lt;BR /&gt;
&lt;BR /&gt;
I'm trying to create external database. And some operations can't be updated with modify function so I'm deleting elements and createing new ones. Of course then I get different guids in files and database... &lt;IMG src="https://community.graphisoft.com/legacyfs/online/emojis/icon_biggrin.gif" style="display : inline;" /&gt;</description>
      <pubDate>Thu, 27 Sep 2018 15:44:10 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247591#M4277</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2018-09-27T15:44:10Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247592#M4278</link>
      <description>I did my first attempt base on this post:&lt;BR /&gt;
&lt;A href="https://archicad-talk.graphisoft.com/viewtopic.php?f=23&amp;amp;t=43940&amp;amp;p=221023&amp;amp;hilit=GSHandle#p221023" target="_blank"&gt;&lt;LINK_TEXT text="viewtopic.php?f=23&amp;amp;t=43940&amp;amp;p=221023&amp;amp;hil ... le#p221023"&gt;https://archicad-talk.graphisoft.com/viewtopic.php?f=23&amp;amp;t=43940&amp;amp;p=221023&amp;amp;hilit=GSHandle#p221023&lt;/LINK_TEXT&gt;&lt;/A&gt;&lt;BR /&gt;
&lt;BR /&gt;
However, I got the only Version and when I read value I got 0 or a bunch of integers. So I assume either I didn't assign value and It's 0 from allocation or in another case I'm saving pointer instead of value. &lt;BR /&gt;
&lt;BR /&gt;
There is only one difference with an example in BMPtrAndHandle second parameter is a pointer, not value. The function didn't accept the dereferenced value.&lt;BR /&gt;

&lt;PRE&gt;&lt;I&gt;
&lt;/I&gt;	int savedData = 234;
	int* savedDataPtr = &amp;amp;savedData;
	int** sDataPtrPtr = &amp;amp;savedDataPtr;
	API_AttributeUserData MyUserData;

	userData.dataVersion = 1234;
	userData.platformSign = GS::Win_Platform_Sign;
	userData.dataHdl = BMAllocateHandle(sizeof(int), ALLOCATE_CLEAR,0);
		
	GSErr ud_err = BMPtrAndHandle(&amp;amp;sDataPtrPtr, userData.dataHdl, sizeof(int));
	
	GS::ErrCode err = ACAPI_Attribute_SetUserData(&amp;amp;attr.header, &amp;amp;userData);
&lt;/PRE&gt;</description>
      <pubDate>Fri, 28 Sep 2018 08:35:47 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247592#M4278</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2018-09-28T08:35:47Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247593#M4279</link>
      <description>Any suggestions would be greatly appreciated &lt;IMG src="https://community.graphisoft.com/legacyfs/online/emojis/icon_biggrin.gif" style="display : inline;" /&gt;</description>
      <pubDate>Tue, 02 Oct 2018 15:09:36 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247593#M4279</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2018-10-02T15:09:36Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247594#M4280</link>
      <description>I suggest you to create a simple class for your userdata.&lt;BR /&gt;
I wrote an example. In this way you can store any kind of data. Feel free to extend it:
&lt;PRE&gt;#include	"MemoryIChannel.hpp"
#include	"MemoryOChannel.hpp"
#include	"SetPlatformProtocol.hpp"

class MyUserData {
	Int32	id;
	char	string[128];

	GSErrCode LoadFromUserData (const API_ElementUserData&amp;amp; userData);
	GSErrCode SaveToUserData (API_ElementUserData&amp;amp; userData) const;

public:
	MyUserData () : id (-1) {}
	MyUserData (Int32 id, const char* cstr) : id (id) {
		CHTruncate (cstr, string, sizeof (string));
	}

	GSErrCode GetFromElement (const API_Guid&amp;amp; elemGuid);
	GSErrCode SetToElement (const API_Guid&amp;amp; elemGuid) const;
};

// -----------------------------------------------------------------------------

// How to set:

MyUserData userData (1234, "My own ID");
userData.SetToElement (elemGuid);

// How to get:

MyUserData userData2;
if (userData2.GetFromElement (elemGuid2) != APIERR_NOUSERDATA) {
	//
}

// -----------------------------------------------------------------------------

GSErrCode MyUserData::LoadFromUserData (const API_ElementUserData&amp;amp; userData)
{
	IO::MemoryIChannel memChannel (*(userData.dataHdl), BMGetHandleSize (userData.dataHdl));
	IO::SetPlatformIProtocol (memChannel, static_cast&amp;lt;GS::PlatformSign&amp;gt; (userData.platformSign));
	GSErrCode err = NoError;
	err = memChannel.Read (id);
	if (err != NoError)
		return err;
	err = memChannel.Read (string);
	if (err != NoError)
		return err;

	return NoError;
}


GSErrCode MyUserData::SaveToUserData (API_ElementUserData&amp;amp; userData) const
{
	userData.dataVersion = 1;
	userData.platformSign = GS::Act_Platform_Sign;
	userData.flags = APIUserDataFlag_FillWith | APIUserDataFlag_Pickup;

	IO::MemoryOChannel memChannel;
	memChannel.Write (id);
	memChannel.Write (string);

	const USize nBytes = memChannel.GetDataSize ();
	const char* pData = memChannel.GetDestination ();

	userData.dataHdl = BMAllocateHandle (nBytes, ALLOCATE_CLEAR, 0);
	if (userData.dataHdl == nullptr)
		return APIERR_MEMFULL;

	BNCopyMemory (*(userData.dataHdl), pData, nBytes);
	return NoError;
}

GSErrCode MyUserData::GetFromElement (const API_Guid&amp;amp; elemGuid)
{
	API_ElementUserData userData = {};
	API_Elem_Head elemHead = {};
	elemHead.guid = elemGuid;
	GSErrCode err = ACAPI_Element_GetUserData (&amp;amp;elemHead, &amp;amp;userData);
	if (err != NoError)
		return err;

	err = LoadFromUserData (userData);
	BMKillHandle (&amp;amp;userData.dataHdl);
	return err;
}

GSErrCode MyUserData::SetToElement (const API_Guid&amp;amp; elemGuid) const
{
	API_ElementUserData userData = {};
	GSErrCode err = SaveToUserData (userData);
	if (err != NoError)
		return err;

	API_Elem_Head elemHead = {};
	elemHead.guid = elemGuid;
	err = ACAPI_Element_SetUserData (&amp;amp;elemHead, &amp;amp;userData);
	BMKillHandle (&amp;amp;userData.dataHdl);
	return err;
}&lt;/PRE&gt;</description>
      <pubDate>Tue, 02 Oct 2018 17:17:30 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247594#M4280</guid>
      <dc:creator>Tibor Lorantfy</dc:creator>
      <dc:date>2018-10-02T17:17:30Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247595#M4281</link>
      <description>Thanks a lot, Tibor, &lt;BR /&gt;
You are a life saver. I will test it right away!</description>
      <pubDate>Tue, 02 Oct 2018 20:30:58 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247595#M4281</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2018-10-02T20:30:58Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247596#M4282</link>
      <description>It's working perfectly. I added Attributes as well there is a slight adjustment since  ACAPI_Attribute_Set_UserData takes only type and Idx instead of GUID.  So I'm passing API_Attribute instead of GUID.&lt;BR /&gt;
&lt;BR /&gt;
I was recently wondering why the whole API is not structured as classes?? But with structs and all methods as separate functions. It would be much easier to have API_Element as a class with all parameters and methods warped up in one class.  I'm actually doing in spare time but it would be great to have it ready made by professional developers. Since there is always some conversion confusion and memory issues to consider. &lt;BR /&gt;
&lt;BR /&gt;
Anyway is there any reason or benefit of using such kind of coding style? &lt;BR /&gt;
&lt;BR /&gt;

&lt;PRE&gt;GS::ErrCode MyUserData::SetToAttrib(const API_Attribute&amp;amp; attrib) const
{
	API_AttributeUserData userData = {};
	GSErrCode err = SaveToUserDataAtt(userData);
	if (err != NoError)
		return err;

	API_Attr_Head attHead = {};
	attHead.index = attrib.header.index;
	attHead.typeID = attrib.header.typeID;
	err = ACAPI_Attribute_SetUserData(&amp;amp;attHead, &amp;amp;userData);
	BMKillHandle(&amp;amp;userData.dataHdl);
	return err;
}&lt;/PRE&gt;

&lt;PRE&gt;GS::ErrCode MyUserData::GetFromAttribute(const API_Attribute&amp;amp; attrib)
{
	API_AttributeUserData userData = {};
	API_Attr_Head attHead = {};

	attHead.index = attrib.header.index;
	attHead.typeID = attrib.header.typeID;

	GSErrCode err = ACAPI_Attribute_GetUserData(&amp;amp;attHead, &amp;amp;userData);
	if (err != NoError)
		return err;

	err = LoadFromUserDataAtt(userData);
	BMKillHandle(&amp;amp;userData.dataHdl);
	return err;
}&lt;/PRE&gt;</description>
      <pubDate>Sun, 07 Oct 2018 14:01:47 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247596#M4282</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2018-10-07T14:01:47Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247597#M4283</link>
      <description>&lt;BLOCKQUOTE&gt;kzaremba wrote:&lt;BR /&gt;
It's working perfectly. I added Attributes as well there is a slight adjustment since  ACAPI_Attribute_Set_UserData takes only type and Idx instead of GUID.  So I'm passing API_Attribute instead of GUID.&lt;/BLOCKQUOTE&gt;
Nice, I'm glad you succeed!&lt;BR /&gt;

&lt;BLOCKQUOTE&gt;kzaremba wrote:&lt;BR /&gt;
I was recently wondering why the whole API is not structured as classes?? But with structs and all methods as separate functions. It would be much easier to have API_Element as a class with all parameters and methods warped up in one class.
&lt;/BLOCKQUOTE&gt;
It has historical reasons. The first ARCHICAD version was released more than 30 years ago and the first API version is also more than 20 years old. Back then C++ was still just a baby...&lt;BR /&gt;
You're absolutely right, it would be much more easier that way, but ARCHICAD database is a very complex system.</description>
      <pubDate>Sun, 07 Oct 2018 15:02:09 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247597#M4283</guid>
      <dc:creator>Tibor Lorantfy</dc:creator>
      <dc:date>2018-10-07T15:02:09Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247598#M4284</link>
      <description>&lt;BLOCKQUOTE&gt;Tibor wrote:&lt;BR /&gt;Nice, I'm glad you succeed!
&lt;/BLOCKQUOTE&gt;
Thx to you &lt;IMG src="https://community.graphisoft.com/legacyfs/online/emojis/icon_biggrin.gif" style="display : inline;" /&gt;&lt;BR /&gt;

&lt;BLOCKQUOTE&gt;Tibor wrote:&lt;BR /&gt; it would be much more easier that way&lt;/BLOCKQUOTE&gt;
So if it's only historical... Do you think there is a possibility to start GitRepository (or similar solution) to create the library of classes working with actual API (like the example above)? So if someone is interested in developing such an approach could collaborate and build upon some examples like this? This might be an even better way to share this knowledge than the forum where some topics are covered by the others.</description>
      <pubDate>Mon, 08 Oct 2018 18:14:26 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247598#M4284</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2018-10-08T18:14:26Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247599#M4285</link>
      <description>I have some troubles with overwriting data. I assumed that the easiest way would be to delete user data and set a new one. Here is my attempt. But as always the easiest way doesn't work at all. As pointed in docs I used nullptr to delete data. I assume that some treatment od memorychannel is necessary, but all my attempts just crashed AC. Please help.
&lt;PRE&gt;	GS::ErrCode MyUserData::DelToAttrib(const API_Attribute&amp;amp; attrib) const {
		API_AttributeUserData userData = {};
		userData.dataHdl = nullptr;
	        API_Attr_Head attHead = {};
		attHead.index = attrib.header.index;
		attHead.typeID = attrib.header.typeID;
		GSErrCode err = ACAPI_Attribute_SetUserData(&amp;amp;attHead, &amp;amp;userData);
		BMKillHandle(&amp;amp;userData.dataHdl);
		return err;
		}&lt;/PRE&gt;</description>
      <pubDate>Fri, 19 Oct 2018 20:21:53 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247599#M4285</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2018-10-19T20:21:53Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247600#M4286</link>
      <description>Any suggestions ?</description>
      <pubDate>Fri, 26 Oct 2018 07:45:41 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247600#M4286</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2018-10-26T07:45:41Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247601#M4287</link>
      <description>&lt;BLOCKQUOTE&gt;kzaremba wrote:&lt;BR /&gt;
Do you think there is a possibility to start GitRepository (or similar solution) to create the library of classes working with actual API (like the example above)? So if someone is interested in developing such an approach could collaborate and build upon some examples like this? This might be an even better way to share this knowledge than the forum where some topics are covered by the others.
&lt;/BLOCKQUOTE&gt;

Yes, it's possible, but could be very hard to maintain.&lt;BR /&gt;
There should be an attached continous integration system which builds the code after anybody pushed some modification to make sure it builds successfully and it runs tests to make sure it still works correctly.&lt;BR /&gt;
Without this system I think that repository can be a big mess after few years (or it would take too many effort for somebody to maintain).</description>
      <pubDate>Thu, 08 Nov 2018 14:45:08 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247601#M4287</guid>
      <dc:creator>Tibor Lorantfy</dc:creator>
      <dc:date>2018-11-08T14:45:08Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247602#M4288</link>
      <description>Ok. I thought its easier since you have version control and branching.  Anyway, I understand that there are no plans for reorganizing API?&lt;BR /&gt;
I did some prototypes of polymorphic classes based on API and it seems much easier to build up commands and much less code to maintain.</description>
      <pubDate>Thu, 08 Nov 2018 15:57:49 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247602#M4288</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2018-11-08T15:57:49Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247603#M4289</link>
      <description>&lt;BLOCKQUOTE&gt;kzaremba wrote:&lt;BR /&gt;
I have some troubles with overwriting data. I assumed that the easiest way would be to delete user data and set a new one.
&lt;/BLOCKQUOTE&gt;

You don't have to delete the userdata, because if you call ACAPI_Attribute_SetUserData to the attribute for the second time then it will automatically overwrite the existing userdata.&lt;BR /&gt;

&lt;BLOCKQUOTE&gt;kzaremba wrote:&lt;BR /&gt;
I assume that some treatment od memorychannel is necessary, but all my attempts just crashed AC. Please help.
&lt;PRE&gt;&lt;I&gt;
&lt;/I&gt;...
		userData.dataHdl = nullptr;
...
		BMKillHandle(&amp;amp;userData.dataHdl);
...
&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;

Your code is ok, except the BMKillHandle call, I think that line caused the crash, because the userData.dataHdl is nullptr there.</description>
      <pubDate>Thu, 08 Nov 2018 16:29:30 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247603#M4289</guid>
      <dc:creator>Tibor Lorantfy</dc:creator>
      <dc:date>2018-11-08T16:29:30Z</dc:date>
    </item>
    <item>
      <title>Re: Custom GUID</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247604#M4290</link>
      <description>Aaaa... ok. Works now. Thank you!</description>
      <pubDate>Sun, 11 Nov 2018 14:14:01 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Custom-GUID/m-p/247604#M4290</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2018-11-11T14:14:01Z</dc:date>
    </item>
  </channel>
</rss>

