Choose your top Archicad wishes!

Read more
GDL
About building parametric objects with GDL.

Changing custom GDL parameters - Zone Stamps

Hi all,

I am having problems changing custom GDL parameters on Zone Stamp objects.

I am trying to correct an API that I have inherited - the function I am working on changes a custom GDL parameter of objects placed in the floor plan. The function is called from a for loop of all API_ObjectID type within an undoable session.

The function works correctly for most items, however it is not updating Zone Stamps (which are included in the list using 'ACAPI_Element_GetElemList(API_ObjectID, &elemList)'). The ChangeElementParameter function gives me an error in ACAPI_Element_Change: -2130312313 (APIERR_NOTSUPPORTED).

Interestingly, in the loop of all API_ObjectID types, the original code has the following lines after GETting the element, and before calling the ChangeElementParameter function. This is causing random crashing in the API, but also seems to allow the Zone Stamp objects GDL parameters to be edited using the ChangeElementParameter function.

ACAPI_ELEMENT_MASK_CLEAR (mask);
err = ACAPI_Element_Change (&element, &mask, NULL, 0, true);


Code for ChangeElementParameter function:
GSErrCode ChangeElementParameter	(API_ElemTypeID elementType,
									long elementIndex,
									const char* name,
									double value)
{
	GSErrCode			err = NoError;
	API_ParamOwnerType	paramOwner;
	API_Element			element, mask;
	API_ElementMemo		memo;
	char				msgStr[256];

	BNZeroMemory (&paramOwner, sizeof (API_ParamOwnerType));
	paramOwner.libInd = 0;
	paramOwner.typeID = elementType;
	paramOwner.index = elementIndex;
	err = ACAPI_Goodies (APIAny_OpenParametersID, &paramOwner, NULL);

	if (err == NoError)
	{
		API_ChangeParamType chgParam;
		BNZeroMemory (&chgParam, sizeof (API_ChangeParamType));
		CHCopyC (name, chgParam.name);
		chgParam.realValue = value;
		err = ACAPI_Goodies (APIAny_ChangeAParameterID, &chgParam, NULL);
		if (err == NoError)
		{
			API_GetParamsType getParams;
			BNZeroMemory (&getParams, sizeof (API_GetParamsType));
			err = ACAPI_Goodies (APIAny_GetActParametersID, &getParams, NULL);
			if (err == NoError)
			{
				BNZeroMemory (&element, sizeof (API_Element));
				BNZeroMemory (&mask, sizeof (API_Element));
				BNZeroMemory (&memo, sizeof (API_ElementMemo));
				element.header.typeID = elementType;
				element.header.index = elementIndex;
				memo.params = getParams.params;
				err = ACAPI_Element_Change (&element, &mask, &memo, APIMemoMask_AddPars, true);
				if (err != NoError) {
					sprintf(msgStr, "Error in ACAPI_Element_Change: %li", err);
					ACAPI_WriteReport(msgStr, false);
				}
			} else {
				sprintf(msgStr, "Error in APIAny_GetActParametersID: %li", err);
				ACAPI_WriteReport(msgStr, false);
			}
			ACAPI_DisposeAddParHdl(&getParams.params);
		}  else {
			sprintf(msgStr, "Error in APIAny_ChangeAParameterID: %li", err);
			ACAPI_WriteReport(msgStr, false);
		}
		err = ACAPI_Goodies (APIAny_CloseParametersID, NULL, NULL);
	} else {
		sprintf(msgStr, "Error in APIAny_OpenParametersID: %li", err);
		ACAPI_WriteReport(msgStr, false);
	}
	return err;
}
Any clues on changing GDL parameters on Zone Stamps correctly?

Thanks,
Danny
3 REPLIES 3
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
Hi Danny,

You can read in the documentation of ACAPI_Element_Change function that for each element type which fields can be edited:
API_ZoneID :
beside the setting parameters the following fields can be edited:
libInd, pos and the polygon of the zone (coords, pends, parcs, vertexIDs memo handles)


So as you can see, unfortunately the params field cannot be edited, that's why it gives you APIERR_NOTSUPPORTED.

For all API_ObjectID elements it should be successful, but there's some little mistakes in your code, those could cause the crashes.
I have corrected your code, I hope this will work correctly:
GSErrCode ChangeElementParameter   (API_ElemTypeID elementType,  
                                       long elementIndex,  
                                       const char* name,  
                                       double value)  
{  
    API_ParamOwnerType   paramOwner; 
    API_ChangeParamType  chgParam; 
    API_GetParamsType    getParams; 
    API_Element          element, mask; 
    API_ElementMemo      memo; 
    GSErrCode            err; 
    char                 msgStr[256]; 
 
    BNZeroMemory (&paramOwner, sizeof (API_ParamOwnerType)); 
    paramOwner.libInd = 0; 
    paramOwner.typeID = elementType; 
    paramOwner.index  = elementIndex; 
 
    BNZeroMemory (&getParams, sizeof (API_GetParamsType)); 
 
    err = ACAPI_Goodies (APIAny_OpenParametersID, &paramOwner, NULL); 
    if (err == NoError) { 
        BNZeroMemory (&chgParam, sizeof (API_ChangeParamType)); 
 
        err = ACAPI_Goodies (APIAny_GetActParametersID, &getParams, NULL); 
        if (err == NoError) { 
            chgParam.index = 0; 
            CHCopyC (name, chgParam.name); 
            chgParam.realValue = value; 
            err = ACAPI_Goodies (APIAny_ChangeAParameterID, &chgParam, NULL); 
            if (err == NoError) { 
                err = ACAPI_Goodies (APIAny_GetActParametersID, &getParams, NULL); 
                if (err != NoError) { 
                    sprintf(msgStr, "Error in APIAny_GetActParametersID");  
                    ACAPI_WriteReport(msgStr, false);  
                } 
            } else { 
                sprintf(msgStr, "Error in APIAny_ChangeAParameterID");  
                ACAPI_WriteReport(msgStr, false);  
            } 
        } else { 
            sprintf(msgStr, "Error in APIAny_GetActParametersID");  
            ACAPI_WriteReport(msgStr, false);  
        } 
        ACAPI_Goodies (APIAny_CloseParametersID, NULL, NULL); 
    } else { 
        sprintf(msgStr, "Error in APIAny_OpenParametersID");  
        ACAPI_WriteReport(msgStr, false);  
    } 
 
    if (err == NoError) { 
        BNZeroMemory (&element, sizeof (API_Element)); 
        BNZeroMemory (&memo, sizeof (API_ElementMemo)); 
        element.header.typeID = elementType; 
        element.header.index  = elementIndex; 
        ACAPI_ELEMENT_MASK_CLEAR (mask); 
        memo.params = getParams.params; 
        err = ACAPI_Element_Change (&element, &mask, &memo, APIMemoMask_AddPars, true); 
        if (err != NoError) { 
            sprintf(msgStr, "Error in ACAPI_Element_Change"); 
            ACAPI_WriteReport(msgStr, false); 
        } 
    } 
 
    ACAPI_DisposeAddParHdl (&getParams.params); 
 
    return err; 
} 


Don't forget that you should use guids instead of indexes since AC17.

You can use APIDb_RefreshElementID also, if you want to force rebuild the elements from updated libpart. Maybe this could solve your problem instead of ACAPI_Element_Change.
bool force = true;
err = ACAPI_Database (APIDb_RefreshElementID, &elem.header, &force);
Regards,
Tibor
Thanks for checking through the code Tibor. I have amended my function with your updates.

The Zone Stamp object is selected using the API_ObjectID type (not API_ZoneID) through;
ACAPI_Element_GetElemList(API_ObjectID, &elemList)
It is the stamp object that I am changing, not the zone itself.

I get each object in the elemList using;
element.header.guid = *it;
err = ACAPI_Element_Get (&element);
If I include the following BEFORE calling the ChangeElementParameter function, the zone stamp will allow me to change the custom parameter. If I remove this code it will not allow me to change the custom parameter.
err = ACAPI_Element_Change (&element, &mask, NULL, 0, true);
I understand that API_ZoneID cannot change additional custom parameters, but this is API_ObjectID.

Thanks,
Danny
Ralph Wessel
Mentor
Tibor wrote:
You can read in the documentation of ACAPI_Element_Change function that for each element type which fields can be edited:
API_ZoneID :
beside the setting parameters the following fields can be edited:
libInd, pos and the polygon of the zone (coords, pends, parcs, vertexIDs memo handles)


So as you can see, unfortunately the params field cannot be edited, that's why it gives you APIERR_NOTSUPPORTED.
We're changing zone parameters with ACAPI_Element_Change - perhaps the documentation isn't up to date?
Ralph Wessel BArch