Modify an existing Library part's section destroys Libpart
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-10-16
03:32 PM
- last edited on
2023-07-13
03:19 PM
by
Doreena Deng

I try to modifiy an existing Library part by adding some parameters.
Here is a part of the code i use :
API_LibPart libPart; BNZeroMemory (&libPart, sizeof (API_LibPart)); //TODO : Get type of libpart ? libPart.typeID = APILib_ObjectID; libPart.location = &destinationFile; // Register the copied library part file err = ACAPI_LibPart_Register(&libPart); if(err == NoError) { // Get the library part err = ACAPI_LibPart_Get(&libPart); if(err == NoError) { // GS Doc says to free the location... if (libPart.location != NULL) { delete libPart.location; libPart.location = NULL; } // Add parameters/properties for this object API_LibPartSection section; BNZeroMemory (§ion, sizeof (API_LibPartSection)); section.sectType = API_SectParamDef; GSHandle sectionHdl = NULL; err = ACAPI_LibPart_GetSection(libPart.index, §ion, §ionHdl, NULL); short nPars = 3; API_AddParType** addPars = reinterpret_cast<API_AddParType**>(BMAllocateHandle (nPars * sizeof (API_AddParType), ALLOCATE_CLEAR, 0)); if (addPars != NULL) { API_AddParType* pAddPar = &(*addPars)[0]; pAddPar->typeID = APIParT_Mater; pAddPar->typeMod = 0; CHTruncate ("mat", pAddPar->name, sizeof (pAddPar->name)); GS::ucscpy (pAddPar->uDescname, L("Tom's Material")); pAddPar->value.real = 1; pAddPar = &(*addPars)[1]; pAddPar->typeID = APIParT_Length; pAddPar->typeMod = 0; CHTruncate ("len", pAddPar->name, sizeof (pAddPar->name)); GS::ucscpy (pAddPar->uDescname, L("Tom's Length")); pAddPar->value.real = 2.5; pAddPar = &(*addPars)[2]; pAddPar->typeID = APIParT_CString; pAddPar->typeMod = 0; CHTruncate ("myStr", pAddPar->name, sizeof (pAddPar->name)); GS::ucscpy (pAddPar->uDescname, L("Tom's String parameter")); GS::ucscpy (pAddPar->value.uStr, L("This is Tom's string")); double aa = 1.0; double bb = 1.0; GSHandle Sect2DHdl = NULL; err = ACAPI_LibPart_GetSect_ParamDef (&libPart, addPars, &aa, &bb, Sect2DHdl, §ionHdl); API_LibPartDetails details; BNZeroMemory (&details, sizeof (API_LibPartDetails)); details.object.autoHotspot = false; err = ACAPI_LibPart_SetDetails_ParamDef (&libPart, sectionHdl, &details); err = ACAPI_LibPart_UpdateSection (libPart.index, §ion, sectionHdl, NULL); BMKillHandle (reinterpret_cast<GSHandle*>(&addPars)); BMKillHandle (§ionHdl); }
After running this code on a valid library part the library part is no more valid. In the Library Part dialog there are messages indicating that the 2D symbol and 3D symbol are not valid.
Probably i'm not using correctly the APIs.
Do you have any idea what i am doing wrong ?
Thanks 😉
- Labels:
-
Add-On (C++)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-10-19 12:38 PM
gehairing wrote:I think you need to include both the new and additional parameters when you make this call:
I try to modifiy an existing Library part by adding some parameters.
After running this code on a valid library part the library part is no more valid. In the Library Part dialog there are messages indicating that the 2D symbol and 3D symbol are not valid.
Do you have any idea what i am doing wrong ?
err = ACAPI_LibPart_SetDetails_ParamDef (&libPart, sectionHdl, &details);Your existing code will be setting the library part to have only the 3 parameters in
Central Innovation
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-10-19 01:32 PM
Thank's for your answer.
I don't understand what you mean

(Probably i don't understand how these api calls work togheter)
I "get" a section, create some additional parameters, "update" the section with these added parameters.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-10-19 02:45 PM
// Set parameters to the given libPart void TestSetParameters(const API_LibPart& libPart) { // Add parameters/properties for this object API_LibPartSection section; BNZeroMemory (§ion, sizeof (API_LibPartSection)); section.sectType = API_SectParamDef; GSHandle sectionHdl = NULL; GSErrCode err = ACAPI_LibPart_GetSection(libPart.index, §ion, §ionHdl, NULL); API_LibPartDetails details; BNZeroMemory (&details, sizeof (API_LibPartDetails)); details.object.autoHotspot = false; err = ACAPI_LibPart_SetDetails_ParamDef (&libPart, sectionHdl, &details); err = ACAPI_LibPart_UpdateSection (libPart.index, §ion, sectionHdl, NULL); BMKillHandle (§ionHdl); }When is use this code i have the problem :
// Set parameters to the given libPart void TestSetParameters(const API_LibPart& libPart) { // Add parameters/properties for this object API_LibPartSection section; BNZeroMemory (§ion, sizeof (API_LibPartSection)); section.sectType = API_SectParamDef; GSHandle sectionHdl = NULL; GSErrCode err = ACAPI_LibPart_GetSection(libPart.index, §ion, §ionHdl, NULL); short nPars = 1; API_AddParType** addPars = reinterpret_cast<API_AddParType**>(BMAllocateHandle (nPars * sizeof (API_AddParType), ALLOCATE_CLEAR, 0)); if (addPars != NULL) { API_AddParType* pAddPar = &(*addPars)[0]; pAddPar->typeID = APIParT_Mater; pAddPar->typeMod = 0; CHTruncate ("mat", pAddPar->name, sizeof (pAddPar->name)); GS::ucscpy (pAddPar->uDescname, L("Tom's testing parameter")); pAddPar->value.real = 1; double aa = 1.0; double bb = 1.0; GSHandle Sect2DHdl = NULL; err = ACAPI_LibPart_GetSect_ParamDef (&libPart, addPars, &aa, &bb, Sect2DHdl, §ionHdl); BMKillHandle (reinterpret_cast<GSHandle*>(&addPars)); } err = ACAPI_LibPart_UpdateSection (libPart.index, §ion, sectionHdl, NULL); BMKillHandle (§ionHdl); }This is only testing code based on code i found in the Libpart_test project.
When i create a LibPart i have no problems at all.
I didn't find code samples for modifying existing Libpart.
I forgot to say that i have no error codes returned on any of the above api calls.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-10-19 03:25 PM
gehairing wrote:There is a marked difference between your 2 examples. Consider the contents of
When i use following code i have no problems at all :
[...]
When is use this code i have the problem :
[...]
This is only testing code based on code i found in the Libpart_test project.
When i create a LibPart i have no problems at all.
err = ACAPI_LibPart_UpdateSection (libPart.index, §ion, sectionHdl, NULL);In the first example,
The call to
- 1. Get all the existing parameters in a handle;
2. Add the new parameter to the handle (so the list contains both new and existing parameters);
3. CallACAPI_LibPart_UpdateSectionand pass the list with existing and new parameters in it.
Central Innovation
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-10-19 03:45 PM
I thought getting the current section with GetSection and adding the new data with GetSect_ParamDef would update the section with the new data. That's what i understand after reading the API doc. But my english is not so good so i probably misunterstood this.
Do you have an idea how i can :
- Get actual parameters,
- Add a few new ones,
- Set all back again.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-10-19 04:23 PM
gehairing wrote:The code you've written is almost right. Try getting the existing parameters with
Thanks for your reply.
I thought getting the current section with GetSection and adding the new data with GetSect_ParamDef would update the section with the new data. That's what i understand after reading the API doc. But my english is not so good so i probably misunterstood this.
Do you have an idea how i can :
- Get actual parameters,
- Add a few new ones,
- Set all back again.
Central Innovation
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-10-19 04:36 PM
After my previous message i have tried following :
Creating a "dump" code :
(completely based on sample code i found in the API doc)
static void DumpParameters (Int32 libInd, API_LibTypeID typeID) { API_LibPartDetails details; double a, b; Int32 addParNum, i, ind, i1, i2; API_AddParType **addPars; double value; char *valueStr; GSErrCode err; err = ACAPI_LibPart_GetParams (libInd, &a, &b, &addParNum, &addPars); if (err) return; for (i = 0; i < addParNum; i++) { if ((*addPars).typeMod == API_ParSimple) { ACAPI_WriteReport ((*addPars).name, false); } else { ind = 0; ACAPI_WriteReport ((*addPars).name, false); for (i1 = 1; i1 <= (*addPars).dim1; i1++) { for (i2 = 1; i2 <= (*addPars).dim2; i2++) { if ((*addPars).typeID != APIParT_CString) { value = (Int32) ((double *) *(*addPars).value.array) [ind]; valueStr = NULL; ind ++; } else { value = 0.0; valueStr = *(*addPars).value.array + ind; ind += strlen (valueStr) + 1; } ACAPI_WriteReport (valueStr, false); } } } } ACAPI_DisposeAddParHdl (&addPars); }Called this method to dump all parameters before my code :
A B ZZYZX AC_show2DHotspotsIn3D ac_bottomlevel ac_toplevel showerType services matFinish SKU gs_2D_representation gs_cont_pen gs_fill_type gs_fill_pen gs_back_pen gs_list gs_list_cost gs_list_manufacturer gs_list_note gs_list_location gs_list_accessories FM_Type iFMType FM_InventoryNumber FM_SerialNumber FM_ProductionYear FM_ObjectWeight FM_ObjectWeightUnit gs_list_custom1 gs_list_custom2 gs_list_custom3 gs_list_custom4 gs_list_custom5 gs_3D_representation gs_detlevel_3D gs_shadow doorOpenThen i run this code (the same as in my previous message) to "add" a parameter :
// Set parameters to the given libPart void TestSetParameters(const API_LibPart& libPart) { // Add parameters/properties for this object API_LibPartSection section; BNZeroMemory (§ion, sizeof (API_LibPartSection)); section.sectType = API_SectParamDef; GSHandle sectionHdl = NULL; GSErrCode err = ACAPI_LibPart_GetSection(libPart.index, §ion, §ionHdl, NULL); short nPars = 1; API_AddParType** addPars = reinterpret_cast<API_AddParType**>(BMAllocateHandle (nPars * sizeof (API_AddParType), ALLOCATE_CLEAR, 0)); if (addPars != NULL) { API_AddParType* pAddPar = &(*addPars)[0]; pAddPar->typeID = APIParT_Mater; pAddPar->typeMod = 0; CHTruncate ("mat", pAddPar->name, sizeof (pAddPar->name)); GS::ucscpy (pAddPar->uDescname, L("Tom's testing parameter")); pAddPar->value.real = 1; double aa = 1.0; double bb = 1.0; GSHandle Sect2DHdl = NULL; err = ACAPI_LibPart_GetSect_ParamDef (&libPart, addPars, &aa, &bb, Sect2DHdl, §ionHdl); BMKillHandle (reinterpret_cast<GSHandle*>(&addPars)); } err = ACAPI_LibPart_UpdateSection (libPart.index, §ion, sectionHdl, NULL); BMKillHandle (§ionHdl); }Then run the dump code again :
A B ZZYZX AC_show2DHotspotsIn3D ac_bottomlevel ac_toplevel gs_2D_representation gs_cont_pen gs_fill_type gs_fill_pen gs_back_pen gs_list gs_list_cost gs_list_manufacturer gs_list_note gs_list_location gs_list_accessories FM_Type iFMType FM_InventoryNumber FM_SerialNumber FM_ProductionYear FM_ObjectWeight FM_ObjectWeightUnit gs_list_custom1 gs_list_custom2 gs_list_custom3 gs_list_custom4 gs_list_custom5 mat"mat" is the one i "added".
So It seem's to me that i have lost (or destroyed or whatever

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-10-19 04:46 PM
gehairing wrote:I suspect that all the parameters before 'mat' are required for the object subtype, so ARCHICAD automatically injects them. So your original list is destroyed and replaced with the subtype parameters and the 1 you added.
Thanks Ralph. I'll try to find how to do what you've explained.
After my previous message i have tried following :
Creating a "dump" code :
(completely based on sample code i found in the API doc)
[...]
"mat" is the one i "added".
So It seem's to me that i have lost (or destroyed or whatever)some parameters but not all.
Central Innovation
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2015-10-19 05:49 PM
Thank you Ralph for guiding me.

Here is some testing code that works, hope it can help someone one day.
Now i have to do the real clean code...
static void AddParameterTest (const API_LibPart& libPart) { GSErrCode err; API_LibPartSection section; BNZeroMemory (§ion, sizeof (API_LibPartSection)); section.sectType = API_SectParamDef; GSHandle sectionHdl = NULL; err = ACAPI_LibPart_GetSection(libPart.index, §ion, §ionHdl, NULL); if (err) return; double a, b; Int32 addParNum, i; API_AddParType **addPars; err = ACAPI_LibPart_GetParams (libPart.index, &a, &b, &addParNum, &addPars); if (err) return; // Create enough space for all parameters Int32 myParameterCount = 1; short nPars = addParNum + myParameterCount; API_AddParType** newAddPars = reinterpret_cast<API_AddParType**>(BMAllocateHandle (nPars * sizeof (API_AddParType), ALLOCATE_CLEAR, 0)); if (addPars != NULL) { // Copy all parameters for (i = 0; i < addParNum; i++) { (*newAddPars) = (*addPars); } // Add our new parameter API_AddParType* pAddPar = &(*newAddPars)[nPars-1]; pAddPar->typeID = APIParT_Mater; pAddPar->typeMod = 0; CHTruncate ("mat", pAddPar->name, sizeof (pAddPar->name)); GS::ucscpy (pAddPar->uDescname, L("Tom's testing parameter")); pAddPar->value.real = 1; // Build a section handle with all parameters GSHandle Sect2DHdl = NULL; err = ACAPI_LibPart_GetSect_ParamDef (&libPart, newAddPars, &a, &b, NULL, §ionHdl); BMKillHandle (reinterpret_cast<GSHandle*>(&newAddPars)); } // Update our section... err = ACAPI_LibPart_UpdateSection (libPart.index, §ion, sectionHdl, NULL); BMKillHandle (§ionHdl); ACAPI_DisposeAddParHdl (&addPars); }