2023-10-12 08:26 PM - last edited on 2024-09-16 02:27 PM by Doreena Deng
HI guys,
I have an object tool loaded into ArchiCAD and it has a parameter which is an array value. Now I want to get it and set a new value for it.
I did it like this as in LibPart_Test:
UInt32 totalParams1 = BMGetHandleSize((GSConstHandle)memo.params);
UInt32 totalParams = BMGetHandleSize((GSConstHandle)memo.params) / sizeof(API_AddParType);
for (UInt32 i = 0; i < totalParams; i++) {
if ((*memo.params)[i].name == (GS::UniString)"matrix_area")
{
(*memo.params)[i].value.array = BMAllocateHandle((*memo.params)[i].dim1 * (*memo.params)[i].dim2 * sizeof(double), ALLOCATE_CLEAR, 0);
double** arrHdl = reinterpret_cast<double**>((*memo.params)[i].value.array);
for (Int32 k = 0; k < (*memo.params)[i].dim1; k++)
for (Int32 j = 0; j < (*memo.params)[i].dim2; j++)
(*arrHdl)[k * (*memo.params)[i].dim2 + j] = (k == j ? 1.1 : 0.0);
}
}
But It's not right.
Can you help me know where I'm wrong?
Thank you very much.
2023-10-13 07:58 AM
Hi,
There could be a lot of different issues, depending mostly on where you get the memo from.
So please specify what you do before this code with the memo structure and also what specifically is not working.
One of my guesses is, that one of your dim1 or dim2 are maybe 0.
Best,
Bernd
2023-10-13 01:24 PM - edited 2023-10-13 06:41 PM
Hi bschwb,
Thank you for responding, I get the memo like this. And my dim1 and dim2 have a value.
Can you help me tell me where I'm wrong?
API_Element element;
API_ElementMemo memo;
API_LibPart libPart;
BNZeroMemory(&element, sizeof(API_Element));
BNZeroMemory(&libPart, sizeof(API_LibPart));
BNZeroMemory(&memo, sizeof(API_ElementMemo));
BNClear(element);
BNClear(memo);
GSErrCode err;
BNZeroMemory(&libPart, sizeof(API_LibPart));
libPart.typeID = APILib_ObjectID;
CHCopyC("{4FD10D67-2F29-4844-A65A-6597589B0CB5}-{3BC96B79-9E97-42A3-969C-600334C0D18D}", libPart.parentUnID);
GS::ucscpy(libPart.docu_UName, L("Schedule1"));
err = ACAPI_LibPart_Search(&libPart, false);
if (err == APIERR_BADNAME)
ACAPI_WriteReport("Khong tim thay thu vien", false);
element.header.type = API_ObjectID;
err = ACAPI_Element_GetDefaults(&element, &memo);
if (err != NoError) {
ACAPI_WriteReport("ACAPI_Element_GetDefaults has failed with error code %ld!", true, err);
ACAPI_DisposeElemMemoHdls(&memo);
return;
}
double aa = 0, bb = 0;
Int32 addParNum;
ACAPI_LibPart_GetParams(libPart.index, &aa, &bb, &addParNum, &memo.params);
element.object.libInd = libPart.index;
err = ACAPI_Goodies(APIAny_CloseParametersID);
And I change to this but it's still not right.
UInt32 totalParams1 = BMGetHandleSize((GSConstHandle)memo.params);
UInt32 totalParams = BMGetHandleSize((GSConstHandle)memo.params) / sizeof(API_AddParType);
int num_row = 8;
int num_col = 4;
for (UInt32 i = 0; i < totalParams; i++) {
if ((*memo.params)[i].name == (GS::UniString)"matrix_area")
{
API_AddParType* pAddPar = &(*memo.params)[i];
double** arrHdl = reinterpret_cast<double**>(pAddPar->value.array);
for (Int32 k = 0; k < num_row; k++)
for (Int32 j = 0; j < num_col; j++)
(*arrHdl)[k * num_col + j] = 11;
BMKillHandle(reinterpret_cast<GSHandle*>(&arrHdl));
}
}
2023-10-16 12:57 AM
There are a few issues with your code.
Here's your code changed so it creates an object if you have a library part with an existing parameter called "matrix_area".
I'm using references instead of handles and pointers in some places because it's easier for me to read.
void Create ()
{
API_Element element;
API_ElementMemo memo;
API_LibPart libPart;
BNZeroMemory (&element, sizeof (API_Element));
BNZeroMemory (&libPart, sizeof (API_LibPart));
BNZeroMemory (&memo, sizeof (API_ElementMemo));
BNClear (element);
BNClear (memo);
GSErrCode err;
libPart.typeID = APILib_ObjectID;
GS::ucscpy (libPart.docu_UName, L ("test"));
err = ACAPI_LibPart_Search (&libPart, false);
if (err == APIERR_BADNAME) {
ACAPI_WriteReport ("Khong tim thay thu vien", false);
}
element.header.type = API_ObjectID;
err = ACAPI_Element_GetDefaults (&element, &memo);
if (err != NoError) {
ACAPI_WriteReport ("ACAPI_Element_GetDefaults has failed with error code %ld!", true, err);
ACAPI_DisposeElemMemoHdls (&memo);
return;
}
double aa = 0, bb = 0;
Int32 addParNum;
ACAPI_LibPart_GetParams (libPart.index, &aa, &bb, &addParNum, &memo.params);
element.object.libInd = libPart.index;
UInt32 totalParams = BMGetHandleSize((GSConstHandle)memo.params) / sizeof(API_AddParType);
int num_row = 8;
int num_col = 4;
for (UInt32 i = 0; i < totalParams; i++) {
if ((*memo.params)[i].name == (GS::UniString)"matrix_area")
{
auto& currentParam = (*memo.params)[i];
currentParam.dim1 = num_row;
currentParam.dim2 = num_col;
currentParam.value.array =
BMReallocHandle (currentParam.value.array,
num_row * num_col * sizeof (double),
REALLOC_FULLCLEAR, 0);
auto paramArray = reinterpret_cast<double*>(*currentParam.value.array);
for (Int32 k = 0; k < num_row; k++)
for (Int32 j = 0; j < num_col; j++)
paramArray[k * num_col + j] = 11.0;
// DON'T kill handle here already! We still need it to create the element!
// It's just referenced through 'memo' there.
}
}
err = ACAPI_Element_Create (&element, &memo);
ACAPI_DisposeElemMemoHdls (&memo);
}
If you can't get it to work, please provide more details of what is not working specifically (error codes, expected vs. actual behavior or crashes).
Hope that helps!
Bernd