2022-09-22 11:22 PM - edited 2022-09-22 11:42 PM
I know this questions has been asked a couple of time but looking at other answers and the API docs i just still can't get this to work.
I have created a dummy GDL object (just a simple 2D rect) and added a custom GDL parameter "test_param" of type length:
Then i created a simple function in my C++ addon that picks the selected element and changes "test_param" to 1234.0:
/* TESTING: Trying to change value of parameter "test_param" to 1234.0 in selected object*/
// 1: Get the first selected element
API_SelectionInfo selectionInfo;
GS::Array<API_Neig> selNeigs;
auto err = ACAPI_Selection_Get(&selectionInfo, &selNeigs, true);
BMKillHandle((GSHandle*)&selectionInfo.marquee.coords);
if (selNeigs.GetSize() != 1)
return NoError;
API_Element element;
element.header.guid = selNeigs[0].guid;
err = ACAPI_Element_Get(&element);
if (err)
return err;
// 2: Open the parameter list for the selected element
API_ParamOwnerType paramOwner;
BNZeroMemory(¶mOwner, sizeof(API_ParamOwnerType));
paramOwner.libInd = 0; /* no library part */
paramOwner.type.typeID = API_ObjectID; /* object element */
paramOwner.guid = element.header.guid; /* selected element */
err = ACAPI_Goodies(APIAny_OpenParametersID, ¶mOwner, nullptr);
if (err)
return err;
// 3: Change the param "test_param" to 1234.0 in the parameter list
API_ChangeParamType chgParam;
BNZeroMemory(&chgParam, sizeof(API_ChangeParamType));
CHCopyC("test_param", chgParam.name);
chgParam.realValue = 1234.0;
err = ACAPI_Goodies(APIAny_ChangeAParameterID, &chgParam, nullptr);
if (err)
return err;
// 4: Get the updated parameter list
API_GetParamsType getParams;
BNZeroMemory(&getParams, sizeof(API_GetParamsType));
err = ACAPI_Goodies(APIAny_GetActParametersID, &getParams, nullptr);
if (err)
return err;
// 5: VERIFICATION, check that the parameter "test_param" was updated correctly to 1234.0
bool testParamWasChanged = false;
for (int i = 0; i < GetHandleSize(getParams.params); i++) {
auto param = (*getParams.params)[i];
if (strcmp(param.name, "test_param") == 0 && param.value.real == 1234.0) {
testParamWasChanged = true;
break;
}
}
assert(testParamWasChanged);
// 6: Close the updated parameter list
err = ACAPI_Goodies(APIAny_CloseParametersID, nullptr, nullptr);
if (err)
return err;
// 7 Update the memo of the selected element with the updated parameter list
API_ElementMemo memo;
BNZeroMemory(&memo, sizeof(API_ElementMemo));
memo.params = getParams.params;
API_Element mask;
ACAPI_ELEMENT_MASK_CLEAR(mask);
err = ACAPI_CallUndoableCommand("Change test_param to 1234.0", [&]() {
return ACAPI_Element_Change(&element, &mask, &memo, APIMemoMask_AddPars, true);
});
if (err)
return err;
//8: VERIFICATION, Check that "test_param" was updated correctly in the memo structure after "ACAPI_Element_Change"
err = ACAPI_Element_GetMemo(element.header.guid, &memo, APIMemoMask_AddPars);
testParamWasChanged = false;
for (int i = 0; i < GetHandleSize(memo.params); i++) {
auto param = (*memo.params)[i];
if (strcmp(param.name, "test_param") == 0 && param.value.real == 1234.0) {
testParamWasChanged = true;
break;
}
}
assert(testParamWasChanged);
ACAPI_DisposeAddParHdl(&getParams.params);
return err;
I select the element and run the procedure, every error check passes and i can even verify that "test_param" was successfully changed to 1234.0 both in the parameter list and in the parameters of the elements memo after updating it.
But when opening up the parameter of the GDL object afterwards (in the first picture above) its initial value 10.0 is unchanged. I must have missed something obvious here, any help or thought is appretiated.
Solved! Go to Solution.
2022-09-23 07:00 AM
Simple mistake, the GDL object parameter is actually updated correctly if opened in the object tool (CTRL+T).
2022-09-23 07:00 AM
Simple mistake, the GDL object parameter is actually updated correctly if opened in the object tool (CTRL+T).
2022-09-30 06:36 AM - edited 2022-09-30 09:26 AM
I am also trying to change parameters but from an array. I have this code:
API_ParamOwnerType owner;
BNZeroMemory(&owner, sizeof(API_ParamOwnerType));
owner.libInd = 0;
owner.typeID = elem.header.typeID;
owner.variationID = elem.header.variationID;
owner.guid = elem.header.guid;
err = ACAPI_Goodies(APIAny_OpenParametersID, &owner);
API_GetParamsType params = {};
err = ACAPI_Goodies(APIAny_GetActParametersID, ¶ms);
API_AddParType neededPar = ...; // params[i].name = "neededPar"
for (Int32 r = 0; r < neededPar.dim1; ++r)
{
for (Int32 c = 0; c < neededPar.dim2; ++c)
{
API_ChangeParamType par = {};
CHCopyC(neededPar.name, par.name);
par.ind1 = r;
par.ind2 = c;
par.realValue = realVal;
err = ACAPI_Goodies(APIAny_ChangeAParameterID, &par); <-- returns APIERR_BADPARS
}
}
err = ACAPI_Goodies(APIAny_CloseParametersID);
But I got an APIERR_BADPARS. Where did I go wrong?
EDIT: added the neededPar to the code
2022-09-30 02:24 PM - edited 2022-09-30 02:32 PM
I think the error occurs because the integers (r and c) are starting at 0, they should start at 1. If I'm not mistaken the indexes of GDL arrays starts at 1.
Additionally, calling
ACAPI_Goodies(APIAny_CloseParametersID)
Is not enough to update the parameters of the element. You are not operating on the actual parameter list of an element when using APIAny_ChangeAParameterID , APIAny_CloseParametersID etc... but rather a copy. So when you are done you need to
get the parameter list using APIAny_GetActParametersID, this will contain the result of all your changes.
And then updating the memo of the element using the result of APIAny_GetActParametersID is what is actually updating the parameters. See step 7 in my code.