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

How to change Symbol Type using ArchiCAD API?

Tran Thanh Lo
Booster

Hi guys, 

Does anyone know How to change the symbol type when tagging like this in the image below?

i’m very happy to receive your reply. 
Thank you very much

 

received_289674507279371.png

 

6 REPLIES 6

Hi!

You'll have to first know the index of the library part. You can search it with ACAPI_LibPart_Search.

And then for the label element, you set the libPart index correctly.

So a rough sketch of the 2 steps:

API_LibPart libPart{};
GS::ucscpy(libPart.docu_UName, "YourLibPartNameHere");
ACAPI_LibPart_Search(&libPart, false);
labelElement.label.u.symbol.libIndex = libPart.libIndex;

 Also you'll have to use ACAPI_LibPart_GetParams to get the parameters of the symbol label.

 

Hope that helps!

Hi bschwb,

Thank you very much for responding to my question.

I followed your instructions but it doesn't work. Can you check my code? And tell me where I'm wrong?

Thanks in advance

 

received_304069542333158.png

 

received_1021461469190431.png

  

Please provide the code in a code block for us to copy from. Screenshots of code are very cumbersome to use.
And also please provide more details of what is not working. What are the error codes you get in which lines etc.

After a quick look on your screenshot, I'm confused why you are using both ACAPI_Element_Change and ACAPI_Element_Create. Are you trying to create a label or change an existing label?

Hi @BerndSchwarzenbacher,

This is my code

 

static void	ReplaceEmptyTextWithPredefined(API_ElementMemo& memo)
{
	const char* predefinedContent = "Default text was empty.";

	if (memo.textContent == nullptr || Strlen32(*memo.textContent) < 2) {
		BMhKill(&memo.textContent);
		memo.textContent = BMhAllClear(Strlen32(predefinedContent) + 1);
		strcpy(*memo.textContent, predefinedContent);
		(*memo.paragraphs)[0].run[0].range = Strlen32(predefinedContent);
	}
}


void CreateLable(API_Guid guid, API_Coord coord)
{

	bool	bAutoText;
	ACAPI_Goodies(APIAny_GetAutoTextFlagID, &bAutoText);

	if (bAutoText) {
		bool _bAutoText = false;
		ACAPI_Goodies(APIAny_ChangeAutoTextFlagID, &_bAutoText);
	}

	GSErrCode		err;
	API_Element		element = {};
	API_ElementMemo	memo = {};
	API_ElemType	type;
	type.typeID = API_ZoneID;
	element.header.type = API_LabelID;
	element.label.parentType = type;

	err = ACAPI_Element_GetDefaults(&element, &memo);

	if (bAutoText) {
		ACAPI_Goodies(APIAny_ChangeAutoTextFlagID, &bAutoText);
	}

	if (err != NoError) {
		ErrorBeep("ACAPI_Element_GetDefaults", err);
		return;
	}

	element.label.begC = coord;
	element.label.endC = coord;
	element.label.createAtDefaultPosition = false;
	element.label.parent =guid;

	if (element.label.labelClass == APILblClass_Text) {
		ReplaceEmptyTextWithPredefined(memo);
		element.label.u.text.nonBreaking = true;
	}

	// Create lable
	err = ACAPI_Element_Create(&element, &memo);
	if (err != NoError)
		ErrorBeep("ACAPI_Element_Create (Associative Label)", err);


	// Change Lable Type
	API_LibPart libPart{};
	BNZeroMemory(&libPart, sizeof(API_LibPart));
	CHCopyC(drawingGuid, libPart.parentUnID);
	GS::ucscpy(libPart.docu_UName, GS::UniString("Zone Label 26").ToUStr());
	ACAPI_LibPart_Search(&libPart, false);
	element.label.u.symbol.ltypeInd = libPart.index;


	//API_Element mask;
	//ACAPI_ELEMENT_MASK_CLEAR(mask);
	//ACAPI_ELEMENT_MASK_SET(mask, API_LabelType, u.symbol.libInd);
	//element.label.u.symbol.libInd = libPart.index;
	//if (ACAPI_Element_Change(&element, &mask, nullptr, 0, true) != NoError);

	ACAPI_DisposeElemMemoHdls(&memo);
}

 

Hi @BerndSchwarzenbacher ,

Sorry for the inconvenience but can you answer me?
I created a new label and tried to change its type but I couldn't. Same as the code in the previous comment.

Can you help me?

Thanks in advance

Hi,

Your code has a few errors and unnecessary lines, so I changed it quite a bit.
First, you don't need to create and then change the label.

I think it's easier to set it up correctly first and then just create it.


Here's an example code for an independent label (it was faster for me to program),

but your parts for the associativity were correct I think, so you will be able to adapt it.

void CreateLabel (API_Coord coord)
{
  GSErrCode err;
  API_Element element{};
  element.header.type = API_LabelID;
  // We don't get the memo here, since it depends on the library part!
  err = ACAPI_Element_GetDefaults (&element, nullptr);
  if (err != NoError) {
    ACAPI_WriteReport ("Error in GetDefaults: %d", true, err);
    return;
  }

  element.label.begC = coord;
  element.label.endC = coord;
  element.label.createAtDefaultPosition = false;
  // In case a text label is selected in label tool defaults, we switch to a symbol label.
  if (element.label.labelClass == APILblClass_Text) {
    element.label.labelClass = APILblClass_Symbol;
  }

  API_LibPart libPart{};
  GS::ucscpy (libPart.docu_UName, GS::UniString ("Zone Label 26").ToUStr ());
  err = ACAPI_LibPart_Search (&libPart, false);
  if (err != NoError) {
    ACAPI_WriteReport ("Error in LibPart_Search: %d", true, err);
    return;
  }
  element.label.u.symbol.libInd = libPart.index;

  // We need to get the parameters of the actual library part!
  // They are stored in memo.params
  API_ElementMemo	memo{};
  Int32 addParNum = 0;
  err = ACAPI_LibPart_GetParams (libPart.index, nullptr, nullptr, &addParNum, &memo.params);
  if (err != NoError) {
    ACAPI_WriteReport ("Error in LibPart_GetParams: %d", true, err);
    return;
  }

  // Create label
  err = ACAPI_Element_Create (&element, &memo);
  if (err != NoError) {
    ACAPI_WriteReport ("Error in Element_Create: %d", true, err);
    return;
  }

  ACAPI_DisposeElemMemoHdls (&memo);
}

 
Hope that helps!
Bernd