Learn to manage BIM workflows and create professional Archicad templates with the BIM Manager Program.

Archicad C++ API
About Archicad add-on development using the C++ API.

Replacing one BIM Object with Another Object in the Archicad Project.

KirthikaSrinivasan-L
Participant

Hi there! I'm trying to replace one BIM Object (which is already available in the Embedded Library) with another BIM Object using the code below. I'm finding the Lib_Part indices of both objects and setting the libInd of the old object to the new object's libInd (element.object.libInd = replacementLibPart.index;).

 

I'm facing APIERR_REFUSEDCMD error or APIERR_BADPARS error, when the code reaches ACAPI_Element_Change(). No Matter what I try, I'm unable to fix this. Can you please help me fix this?

 

Please let me know if my approach has any issues.

 

Thanks in Advance!.

 

 

// Function to find an object by name
API_LibPart FindLibPartByName(const char* partName) {
	API_LibPart libPart;
	BNZeroMemory(&libPart, sizeof(API_LibPart));

	GSErrCode err;
	Int32 numLibParts;
	ACAPI_LibraryPart_GetNum(&numLibParts);

	for (Int32 i = 1; i <= numLibParts; i++) {
		BNZeroMemory(&libPart, sizeof(API_LibPart));
		libPart.index = i;

		err = ACAPI_LibraryPart_Get(&libPart);
		char	docuname[256];
		GS::UniString docName = GS::UniString(libPart.docu_UName);
		const char* cString = docName.ToCStr().Get();

		if (err == NoError && strcmp(cString, partName) == 0) {
			return libPart;
		}
	}

	libPart.index = 0; // Return invalid index if not found
	return libPart;
}

// Function to replace all instances of an old object with a new one
GSErrCode BrowserPalette::ReplaceBIMObjects(const char* oldObjectName, const char* newObjectName) {

	// Get current object's library part
	API_LibPart oldLibPart;
	BNZeroMemory(&oldLibPart, sizeof(API_LibPart));

	//Adding oldobjectname's libpart
	oldLibPart = FindLibPartByName(oldObjectName);
	GS::UniString OldLibpartName(oldLibPart.docu_UName);

	API_LibPart replacementLibPart;
	BNZeroMemory(&replacementLibPart, sizeof(API_LibPart));

	replacementLibPart = FindLibPartByName(newObjectName);
	GS::UniString newLibpartName(replacementLibPart.docu_UName);

	if (ACAPI_LibPart_Get(&oldLibPart) == NoError) {

		ACAPI_WriteReport("Found Object: %s", true, OldLibpartName);

		if (ACAPI_LibPart_Get(&replacementLibPart) == NoError) {

			ACAPI_WriteReport("Replacing %s with %s", true, OldLibpartName.ToCStr().Get(), newLibpartName.ToCStr().Get());

			// Update the object's library part reference
			GS::Array<API_Guid> objectList;
			ACAPI_Element_GetElemList(API_ObjectID, &objectList);

			for (const auto& objGuid : objectList) {
				API_Element element;
				BNZeroMemory(&element, sizeof(API_Element));
				element.header.guid = objGuid;

				if (ACAPI_Element_Get(&element) == NoError) {

					if (element.object.libInd == oldLibPart.index) {
						//ACAPI_WriteReport("Found Element: %s", true, element.object.libInd);

						element.object.libInd = replacementLibPart.index; // Replace with new object index

						GSErrCode err = ACAPI_CallUndoableCommand("Change Object",
							[&]() -> GSErrCode {
							return ACAPI_Element_Change(&element, nullptr, nullptr, 0, false);
						});
						
						//GSErrCode err = ACAPI_Element_Change(&element, nullptr, nullptr, 0, true);

						if (err != NoError) {
								ACAPI_WriteReport("Error updating object: %d", true, err);
						}

					}
				}
			}

		}
		else {
			ACAPI_WriteReport("Replacement object %s not found in Embedded Library.", true, newLibpartName.ToCStr().Get());
		}
	}

	return NoError;
	}

 

0 REPLIES 0