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

ACAPI_Element_Create won't work - help

zaza95
Participant

Hello, I'm pretty new to archicad api coding.

I'm trying to do what I think to be a very simple task, create an object via api. I'm doing a sample code that should create an object in coordinates (0,0).

 

I'm using an object that is already part of default archicad library (Culla.gsm for italian archicad). Could someone help me find what I'm doing wrong?

 

I want also to say that, for now, I'm using a DEMO version of Archicad, please tell me if this could also be the cause of the issue. I've been using archicad v28 and api dev kit 28.2000.

When I run the add-on,  I get error code -2130313112 when calling ACAPI_Element_Create. This is the case without memo. If I use memo and call ACAPI_Element_Create with memo archicad crashes. (now the screenshots are with memo)

 

I'm pasting the code I wrote:

GSErrCode PlaceObjectAtOrigin() {

        API_Element element;
        BNZeroMemory(&element, sizeof(API_Element));
        element.header.type = API_ObjectID;
        element.header.floorInd = 0;
        element.object.pos.x = 0.0;
        element.object.pos.y = 0.0;
        element.header.layer = ACAPI_CreateAttributeIndex(1);
 
        API_LibPart libPart;
        BNZeroMemory(&libPart, sizeof(API_LibPart));
        Int32 libPartCount;
        GS::UniString libPartName("Culla"); 
        const GS::uchar_t* libPartNameUChar = libPartName.ToUStr();  // Convert to uchar_t*
        size_t nameLength = libPartName.GetLength();                 // Get length of the string
        memcpy(libPart.docu_UName, libPartNameUChar, nameLength * sizeof(GS::uchar_t));// Copy the string to libPart.docu_UName using memcpy
        libPart.docu_UName[nameLength] = '\0';  // Null-terminate the string

        ACAPI_WriteReport("trying to assign default elements'", true);
        GSErrCode m_err = ACAPI_Element_GetDefaults(&element, NULL);
        ACAPI_WriteReport("assigned default elements'", true);
        Int32 m_ParamsCount = 0;
        double a, b;
        API_AddParType** params = NULL;
        m_err = ACAPI_LibraryPart_GetParams(libPart.index, &a, &b, &m_ParamsCount, &params);
        API_ElementMemo* m_memo;
        BNZeroMemory(&m_memo, sizeof(API_ElementMemo));
        m_memo->params = params;
        m_err = ACAPI_LibraryPart_Search(&libPart, false, false);      // Check if the library part was found
        if (m_err == NoError) {
            element.object.libInd = libPart.index;  // Set the object's library index
            ACAPI_WriteReport("library obj found and index assigned - culla", true);
        }
        else {
            ACAPI_WriteReport("Error: Could not find the library part 'Culla'", true);
            ACAPI_WriteReport((std::string("Error code: ") + std::to_string(m_err)).c_str(), true);
            return m_err;
        }


        // Place the object
        GSErrCode err_place = ACAPI_CallUndoableCommand("Place object", [&]() -> GSErrCode {
             return ACAPI_Element_Create(&element, m_memo);  //m_memo or null
        });

        if (err_place != NoError) {
            ACAPI_WriteReport((std::string("Error code: ") + std::to_string(err_place)).c_str(), true);
        }
        return err_place;
    }

 

 

 

Thanks in advance



1 ACCEPTED SOLUTION

Accepted Solutions
Solution
LChen
Graphisoft
Graphisoft

Hi, I modified your code. Please try the following one to see whether it works:

HTH.

 

GSErrCode PlaceObjectAtOrigin() {
	API_Element element;
	BNZeroMemory(&element, sizeof(API_Element));
	element.header.type = API_ObjectID;
	element.header.floorInd = 0;
	element.object.pos.x = 0.0;
	element.object.pos.y = 0.0;
	element.header.layer = ACAPI_CreateAttributeIndex(1);

	API_LibPart libPart;
	BNZeroMemory(&libPart, sizeof(API_LibPart));
	Int32 libPartCount;
	GS::UniString libPartName(L("Culla")); 
	const GS::uchar_t* libPartNameUChar = libPartName.ToUStr();  // Convert to uchar_t*
	size_t nameLength = libPartName.GetLength();                 // Get length of the string
	memcpy(libPart.docu_UName, libPartNameUChar, nameLength * sizeof(GS::uchar_t));// Copy the string to libPart.docu_UName using memcpy
	libPart.docu_UName[nameLength] = '\0';  // Null-terminate the string

	ACAPI_WriteReport("trying to assign default elements'", true);

	API_ElementMemo m_memo{};

	GSErrCode m_err = ACAPI_Element_GetDefaults(&element, &m_memo);
	ACAPI_WriteReport("assigned default elements'", true);
	Int32 m_ParamsCount = 0;
	m_err = ACAPI_LibraryPart_Search(&libPart, false, false);      // Check if the library part was found
	if (m_err == NoError) {
		element.object.libInd = libPart.index;  // Set the object's library index
		ACAPI_WriteReport("library obj found and index assigned - culla", true);

		double a, b;
		API_AddParType** params = NULL;
		m_err = ACAPI_LibraryPart_GetParams(libPart.index, &a, &b, &m_ParamsCount, &params);

		m_memo.params = params;
	}
	else {
		ACAPI_WriteReport("Error: Could not find the library part 'Culla'", true);
		ACAPI_WriteReport((std::string("Error code: ") + std::to_string(m_err)).c_str(), true);
		return m_err;
	}


	// Place the object
	GSErrCode err_place = ACAPI_CallUndoableCommand("Place object", [&]() -> GSErrCode {
			return ACAPI_Element_Create(&element, &m_memo);  //m_memo or null
	});

	ACAPI_DisposeElemMemoHdls(&m_memo);
	
	if (err_place != NoError) {
		ACAPI_WriteReport((std::string("Error code: ") + std::to_string(err_place)).c_str(), true);
	}
	return err_place;
}

 

 

View solution in original post

1 REPLY 1
Solution
LChen
Graphisoft
Graphisoft

Hi, I modified your code. Please try the following one to see whether it works:

HTH.

 

GSErrCode PlaceObjectAtOrigin() {
	API_Element element;
	BNZeroMemory(&element, sizeof(API_Element));
	element.header.type = API_ObjectID;
	element.header.floorInd = 0;
	element.object.pos.x = 0.0;
	element.object.pos.y = 0.0;
	element.header.layer = ACAPI_CreateAttributeIndex(1);

	API_LibPart libPart;
	BNZeroMemory(&libPart, sizeof(API_LibPart));
	Int32 libPartCount;
	GS::UniString libPartName(L("Culla")); 
	const GS::uchar_t* libPartNameUChar = libPartName.ToUStr();  // Convert to uchar_t*
	size_t nameLength = libPartName.GetLength();                 // Get length of the string
	memcpy(libPart.docu_UName, libPartNameUChar, nameLength * sizeof(GS::uchar_t));// Copy the string to libPart.docu_UName using memcpy
	libPart.docu_UName[nameLength] = '\0';  // Null-terminate the string

	ACAPI_WriteReport("trying to assign default elements'", true);

	API_ElementMemo m_memo{};

	GSErrCode m_err = ACAPI_Element_GetDefaults(&element, &m_memo);
	ACAPI_WriteReport("assigned default elements'", true);
	Int32 m_ParamsCount = 0;
	m_err = ACAPI_LibraryPart_Search(&libPart, false, false);      // Check if the library part was found
	if (m_err == NoError) {
		element.object.libInd = libPart.index;  // Set the object's library index
		ACAPI_WriteReport("library obj found and index assigned - culla", true);

		double a, b;
		API_AddParType** params = NULL;
		m_err = ACAPI_LibraryPart_GetParams(libPart.index, &a, &b, &m_ParamsCount, &params);

		m_memo.params = params;
	}
	else {
		ACAPI_WriteReport("Error: Could not find the library part 'Culla'", true);
		ACAPI_WriteReport((std::string("Error code: ") + std::to_string(m_err)).c_str(), true);
		return m_err;
	}


	// Place the object
	GSErrCode err_place = ACAPI_CallUndoableCommand("Place object", [&]() -> GSErrCode {
			return ACAPI_Element_Create(&element, &m_memo);  //m_memo or null
	});

	ACAPI_DisposeElemMemoHdls(&m_memo);
	
	if (err_place != NoError) {
		ACAPI_WriteReport((std::string("Error code: ") + std::to_string(err_place)).c_str(), true);
	}
	return err_place;
}