 
					
				
		
2021-11-06 12:23 PM - edited 2021-11-06 12:23 PM
How to read the parameter value of curtain wall panels? Curtain wall panels are made by GDL objects. The usual way (ACAPI_Element_GetMemo(guid, &memo, APIMemoMask_AddPars) of reading parameters for objects does not work, because the panels do not have memo. Is there an alternative way to read panel parameters?
GSErrCode GetCWPanelsForCWall(const API_Guid& elemGuid, GS::Array<API_Guid>& panelGuid) {
	GSErrCode			err = NoError;
	API_Elem_Head elementhead = {};
	elementhead.guid = elemGuid;
	err = ACAPI_Element_GetHeader(&elementhead);
	if (err != NoError) return err;
	if (!elementhead.hasMemo) return err;
	API_ElementMemo	memo;
	BNZeroMemory(&memo, sizeof(API_ElementMemo));
	bool isDegenerate;
	err = ACAPI_Element_GetMemo(elemGuid, &memo, APIMemoMask_CWallPanels);
	if (err != NoError) {
		ACAPI_DisposeElemMemoHdls(&memo);
		return err;
	}
	GSSize nPanels = BMGetPtrSize(reinterpret_cast<GSPtr>(memo.cWallPanels)) / sizeof(API_CWPanelType);
	for (Int32 idx = 0; idx < nPanels; ++idx) {
		err = ACAPI_Database(APIDb_IsCWPanelDegenerateID, &memo.cWallPanels[idx].head.guid, &isDegenerate);
		if (!isDegenerate && memo.cWallPanels[idx].hasSymbol) {
			panelGuid.Push(memo.cWallPanels[idx].symbolID);
			API_Elem_Head panelhead = {};
			panelhead.guid = memo.cWallPanels[idx].symbolID;
			err = ACAPI_Element_GetHeader(&panelhead);
			if (!panelhead.hasMemo) {
				ErrorBeep("ACAPI_Element_GetMemo", err);
			}
		}
	}
	ACAPI_DisposeElemMemoHdls(&memo);
	return err;
}
Industrial Architect and Structural Design Engineer, developer of free addon for sync GDL param and properties
Solved! Go to Solution.
 
					
				
		
2021-11-07 08:57 AM - edited 2021-11-07 09:05 AM
If you have the GUID of the placed library part instance (= GDL based element = symbol), then you can get its parameters by using the APIAny_OpenParametersID, APIAny_GetActParametersID and APIAny_CloseParametersID methods. See the GetGDLParametersOfSymbol function below.
This works for CWPanels also.
API_Guid GetSymbolGuidOfCWPanel (const API_CWPanelType& cwPanel)
{
	bool isDegenerate = false;
	ACAPI_Database (APIDb_IsCWPanelDegenerateID, (void*)(&cwPanel.head.guid), &isDegenerate);
	if (isDegenerate || !cwPanel.hasSymbol) {
		return APINULLGuid;
	}
	return cwPanel.symbolID;
}
GSErrCode GetSymbolGuidOfCWPanel (const API_Guid& cwPanelGuid, API_Guid& symbolGuid)
{
	API_Element	elem = {};
	elem.header.guid = cwPanelGuid;
	const GSErrCode err = ACAPI_Element_Get (&elem);
	if (err != NoError) {
		return err;
	}
	symbolGuid = GetSymbolGuidOfCWPanel (elem.cwPanel);
	if (symbolGuid == APINULLGuid) {
		return APIERR_BADPARS;
	}
	return NoError;
}
GSErrCode GetCWPanelSymbolGuidsOfCW (const API_Guid& cwGuid, GS::Array<API_Guid>& panelSymbolGuids)
{
	GSErrCode	err = NoError;
	API_ElementMemo	memo = {};
	err = ACAPI_Element_GetMemo (cwGuid, &memo, APIMemoMask_CWallPanels);
	if (err != NoError) {
		ACAPI_DisposeElemMemoHdls (&memo);
		return err;
	}
	const GSSize nPanels = BMGetPtrSize (reinterpret_cast<GSPtr>(memo.cWallPanels)) / sizeof (API_CWPanelType);
	for (Int32 idx = 0; idx < nPanels; ++idx) {
		const API_Guid symbolGuid = GetSymbolGuidOfCWPanel (memo.cWallPanels[idx]);
		if (symbolGuid != APINULLGuid) {
			panelSymbolGuids.Push (std::move (symbolGuid));
		}
	}
	ACAPI_DisposeElemMemoHdls (&memo);
	return err;
}
GSErrCode GetGDLParametersOfSymbol (const API_Guid& symbolGuid, API_AddParType**& params)
{
	GSErrCode	err = NoError;
	API_ParamOwnerType	apiOwner = {};
	API_GetParamsType	apiParams = {};
	apiOwner.guid = symbolGuid;
	apiOwner.typeID = API_ObjectID;
	err = ACAPI_Goodies (APIAny_OpenParametersID, &apiOwner);
	if (err != NoError) {
		return err;
	}
	err = ACAPI_Goodies (APIAny_GetActParametersID, &apiParams);
	if (err != NoError) {
		return err;
	}
	params = apiParams.params;
	err = ACAPI_Goodies (APIAny_CloseParametersID);
	return err;
}
GSErrCode HandleGDLParameters (API_AddParType** params)
{
	Int32	addParNum = BMGetHandleSize ((GSHandle)params) / sizeof (API_AddParType);
	for (Int32 ii = 0; ii < addParNum; ++ii) {
		API_AddParType& actualParam = (*params)[ii];
		// Do whatever you want with it
		UNUSED_VARIABLE (actualParam);
	}
	return NoError;
}
// -----------------------------------------------------------------------------
void	Do_CWPanelGDLParameters (void)
{
	API_ElemTypeID	typeID;
	API_Guid		clickedElemGuid;
	if (!ClickAnElem ("Click a curtain wall or a cwpanel.", API_ZombieElemID, nullptr, &typeID, &clickedElemGuid)) {
		WriteReport_Alert ("No element was clicked.");
		return;
	}
	GSErrCode err = NoError;
	if (typeID == API_CurtainWallID) {
		GS::Array<API_Guid> cwPanelSymbolGuids;
		err = GetCWPanelSymbolGuidsOfCW (clickedElemGuid, cwPanelSymbolGuids);
		for (const API_Guid& symbolGuid : cwPanelSymbolGuids) {
			API_AddParType** params = {};
			err = GetGDLParametersOfSymbol (symbolGuid, params);
			if (params == nullptr || err != NoError) {
				continue;
			}
			HandleGDLParameters (params);
			ACAPI_DisposeAddParHdl (¶ms);
		}
	}
	else if (typeID == API_CurtainWallPanelID) {
		API_Guid symbolGuid;
		err = GetSymbolGuidOfCWPanel (clickedElemGuid, symbolGuid);
		API_AddParType** params = {};
		err = GetGDLParametersOfSymbol (symbolGuid, params);
		if (params == nullptr || err != NoError) {
			return;
		}
		HandleGDLParameters (params);
		ACAPI_DisposeAddParHdl (¶ms);
	}
	else {
		WriteReport_Alert ("The clicked element is not a curtain wall or a cwpanel.");
		return;
	}
}
// -----------------------------------------------------------------------------
Don't forget that the API_AddParType list returned by the APIAny_GetActParametersID method is just a copy! So if you modify it, then the parameters of the placed element won't be changed automatically. You have to call the ACAPI_Element_ChangeMemo explicitly to modify the parameters of the element:
API_ElementMemo	elemMemo = {};
elemMemo.params = params;
ACAPI_Element_ChangeMemo (symbolGuid, APIMemoMask_AddPars, &elemMemo);
 
					
				
		
2021-11-07 08:57 AM - edited 2021-11-07 09:05 AM
If you have the GUID of the placed library part instance (= GDL based element = symbol), then you can get its parameters by using the APIAny_OpenParametersID, APIAny_GetActParametersID and APIAny_CloseParametersID methods. See the GetGDLParametersOfSymbol function below.
This works for CWPanels also.
API_Guid GetSymbolGuidOfCWPanel (const API_CWPanelType& cwPanel)
{
	bool isDegenerate = false;
	ACAPI_Database (APIDb_IsCWPanelDegenerateID, (void*)(&cwPanel.head.guid), &isDegenerate);
	if (isDegenerate || !cwPanel.hasSymbol) {
		return APINULLGuid;
	}
	return cwPanel.symbolID;
}
GSErrCode GetSymbolGuidOfCWPanel (const API_Guid& cwPanelGuid, API_Guid& symbolGuid)
{
	API_Element	elem = {};
	elem.header.guid = cwPanelGuid;
	const GSErrCode err = ACAPI_Element_Get (&elem);
	if (err != NoError) {
		return err;
	}
	symbolGuid = GetSymbolGuidOfCWPanel (elem.cwPanel);
	if (symbolGuid == APINULLGuid) {
		return APIERR_BADPARS;
	}
	return NoError;
}
GSErrCode GetCWPanelSymbolGuidsOfCW (const API_Guid& cwGuid, GS::Array<API_Guid>& panelSymbolGuids)
{
	GSErrCode	err = NoError;
	API_ElementMemo	memo = {};
	err = ACAPI_Element_GetMemo (cwGuid, &memo, APIMemoMask_CWallPanels);
	if (err != NoError) {
		ACAPI_DisposeElemMemoHdls (&memo);
		return err;
	}
	const GSSize nPanels = BMGetPtrSize (reinterpret_cast<GSPtr>(memo.cWallPanels)) / sizeof (API_CWPanelType);
	for (Int32 idx = 0; idx < nPanels; ++idx) {
		const API_Guid symbolGuid = GetSymbolGuidOfCWPanel (memo.cWallPanels[idx]);
		if (symbolGuid != APINULLGuid) {
			panelSymbolGuids.Push (std::move (symbolGuid));
		}
	}
	ACAPI_DisposeElemMemoHdls (&memo);
	return err;
}
GSErrCode GetGDLParametersOfSymbol (const API_Guid& symbolGuid, API_AddParType**& params)
{
	GSErrCode	err = NoError;
	API_ParamOwnerType	apiOwner = {};
	API_GetParamsType	apiParams = {};
	apiOwner.guid = symbolGuid;
	apiOwner.typeID = API_ObjectID;
	err = ACAPI_Goodies (APIAny_OpenParametersID, &apiOwner);
	if (err != NoError) {
		return err;
	}
	err = ACAPI_Goodies (APIAny_GetActParametersID, &apiParams);
	if (err != NoError) {
		return err;
	}
	params = apiParams.params;
	err = ACAPI_Goodies (APIAny_CloseParametersID);
	return err;
}
GSErrCode HandleGDLParameters (API_AddParType** params)
{
	Int32	addParNum = BMGetHandleSize ((GSHandle)params) / sizeof (API_AddParType);
	for (Int32 ii = 0; ii < addParNum; ++ii) {
		API_AddParType& actualParam = (*params)[ii];
		// Do whatever you want with it
		UNUSED_VARIABLE (actualParam);
	}
	return NoError;
}
// -----------------------------------------------------------------------------
void	Do_CWPanelGDLParameters (void)
{
	API_ElemTypeID	typeID;
	API_Guid		clickedElemGuid;
	if (!ClickAnElem ("Click a curtain wall or a cwpanel.", API_ZombieElemID, nullptr, &typeID, &clickedElemGuid)) {
		WriteReport_Alert ("No element was clicked.");
		return;
	}
	GSErrCode err = NoError;
	if (typeID == API_CurtainWallID) {
		GS::Array<API_Guid> cwPanelSymbolGuids;
		err = GetCWPanelSymbolGuidsOfCW (clickedElemGuid, cwPanelSymbolGuids);
		for (const API_Guid& symbolGuid : cwPanelSymbolGuids) {
			API_AddParType** params = {};
			err = GetGDLParametersOfSymbol (symbolGuid, params);
			if (params == nullptr || err != NoError) {
				continue;
			}
			HandleGDLParameters (params);
			ACAPI_DisposeAddParHdl (¶ms);
		}
	}
	else if (typeID == API_CurtainWallPanelID) {
		API_Guid symbolGuid;
		err = GetSymbolGuidOfCWPanel (clickedElemGuid, symbolGuid);
		API_AddParType** params = {};
		err = GetGDLParametersOfSymbol (symbolGuid, params);
		if (params == nullptr || err != NoError) {
			return;
		}
		HandleGDLParameters (params);
		ACAPI_DisposeAddParHdl (¶ms);
	}
	else {
		WriteReport_Alert ("The clicked element is not a curtain wall or a cwpanel.");
		return;
	}
}
// -----------------------------------------------------------------------------
Don't forget that the API_AddParType list returned by the APIAny_GetActParametersID method is just a copy! So if you modify it, then the parameters of the placed element won't be changed automatically. You have to call the ACAPI_Element_ChangeMemo explicitly to modify the parameters of the element:
API_ElementMemo	elemMemo = {};
elemMemo.params = params;
ACAPI_Element_ChangeMemo (symbolGuid, APIMemoMask_AddPars, &elemMemo);
 
					
				
		
2021-11-09 10:13 AM
Works great, thanks!
Industrial Architect and Structural Design Engineer, developer of free addon for sync GDL param and properties