We value your input!
Please participate in Archicad 28 Home Screen and Tooltips/Quick Tutorials survey

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

Can Archicad Api control visibility of one Element?

Anonymous
Not applicable
Hi.
Is there any method to control the visibility of one element by Archicad Api?
1 ACCEPTED SOLUTION

Accepted Solutions
Solution
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
Hi,

Yes.
For example if you move the element to an invisible layer, that way the element will become invisible. If your element is on an invisible layer, then you can move it to a visible layer to make the element visible also:
GS::Array<API_Guid> walls;
ACAPI_Element_GetElemList (API_WallID, &walls);

const API_AttributeIndex hiddenLayerIndex = GetIndexOfHiddenNotLockedLayer ();

if (walls.GetSize () > 0 && hiddenLayerIndex > 0) {
	ACAPI_CallUndoableCommand (GS::UniString ("Move walls to an invisible layer"), [&] () -> GSErrCode {
		API_Element newParameters = {};
		API_Element newParametersMask = {};

		newParameters.header.layer = hiddenLayerIndex;
		ACAPI_ELEMENT_MASK_SET (newParametersMask, API_Elem_Head, layer);

		return ACAPI_Element_ChangeMore (walls, &newParameters, nullptr, &newParametersMask, 0, true);
	});
}

//------------------------------------------------------

static API_AttributeIndex GetIndexOfHiddenNotLockedLayer ()
{
	API_AttributeIndex	count;
	ACAPI_Attribute_GetNum (API_LayerID, &count);

	for (API_AttributeIndex ii = 1; ii <= count; ++ii) {
		API_Attribute attr = {};
		attr.header.typeID = API_LayerID;
		attr.header.index = ii;
		if (ACAPI_Attribute_Get (&attr) == NoError) {
			const bool isHidden = (attr.layer.head.flags & APILay_Hidden) != 0;
			const bool isLocked = (attr.layer.head.flags & APILay_Locked) != 0;
			if (isHidden && !isLocked)
				return attr.header.index;
		}
	}

	return -1;
}
Please note, that if you want to highlight elements in 3D, then you can use APIIo_HighlightElementsID method. That function highlights the given elements with the given color and the other (non-highlighted) elements can be switched to wireframed mode:
GS::Array<API_Guid> walls;
ACAPI_Element_GetElemList (API_WallID, &walls);

if (walls.GetSize () > 0) {
	GS::HashTable<API_Guid, API_RGBAColor>	highlightedElements;
	API_RGBAColor	highlightColor = { 0.0, 0.5, 0.75, 0.5 };
	for (const API_Guid& wallGuid : walls) {
		highlightedElements.Add (wallGuid, highlightColor);
		highlightColor.f_red += 0.2;
		if (highlightColor.f_red > 1.0)
			highlightColor.f_red = 0.0;
	}

	bool showNotHighlightedElementsWithWireframe = true;
	ACAPI_Interface (APIIo_HighlightElementsID, &highlightedElements, &showNotHighlightedElementsWithWireframe);
}
You can switch off the highlight with the following line:
ACAPI_Interface (APIIo_HighlightElementsID);
Regards,
Tibor

View solution in original post

2 REPLIES 2
Solution
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
Hi,

Yes.
For example if you move the element to an invisible layer, that way the element will become invisible. If your element is on an invisible layer, then you can move it to a visible layer to make the element visible also:
GS::Array<API_Guid> walls;
ACAPI_Element_GetElemList (API_WallID, &walls);

const API_AttributeIndex hiddenLayerIndex = GetIndexOfHiddenNotLockedLayer ();

if (walls.GetSize () > 0 && hiddenLayerIndex > 0) {
	ACAPI_CallUndoableCommand (GS::UniString ("Move walls to an invisible layer"), [&] () -> GSErrCode {
		API_Element newParameters = {};
		API_Element newParametersMask = {};

		newParameters.header.layer = hiddenLayerIndex;
		ACAPI_ELEMENT_MASK_SET (newParametersMask, API_Elem_Head, layer);

		return ACAPI_Element_ChangeMore (walls, &newParameters, nullptr, &newParametersMask, 0, true);
	});
}

//------------------------------------------------------

static API_AttributeIndex GetIndexOfHiddenNotLockedLayer ()
{
	API_AttributeIndex	count;
	ACAPI_Attribute_GetNum (API_LayerID, &count);

	for (API_AttributeIndex ii = 1; ii <= count; ++ii) {
		API_Attribute attr = {};
		attr.header.typeID = API_LayerID;
		attr.header.index = ii;
		if (ACAPI_Attribute_Get (&attr) == NoError) {
			const bool isHidden = (attr.layer.head.flags & APILay_Hidden) != 0;
			const bool isLocked = (attr.layer.head.flags & APILay_Locked) != 0;
			if (isHidden && !isLocked)
				return attr.header.index;
		}
	}

	return -1;
}
Please note, that if you want to highlight elements in 3D, then you can use APIIo_HighlightElementsID method. That function highlights the given elements with the given color and the other (non-highlighted) elements can be switched to wireframed mode:
GS::Array<API_Guid> walls;
ACAPI_Element_GetElemList (API_WallID, &walls);

if (walls.GetSize () > 0) {
	GS::HashTable<API_Guid, API_RGBAColor>	highlightedElements;
	API_RGBAColor	highlightColor = { 0.0, 0.5, 0.75, 0.5 };
	for (const API_Guid& wallGuid : walls) {
		highlightedElements.Add (wallGuid, highlightColor);
		highlightColor.f_red += 0.2;
		if (highlightColor.f_red > 1.0)
			highlightColor.f_red = 0.0;
	}

	bool showNotHighlightedElementsWithWireframe = true;
	ACAPI_Interface (APIIo_HighlightElementsID, &highlightedElements, &showNotHighlightedElementsWithWireframe);
}
You can switch off the highlight with the following line:
ACAPI_Interface (APIIo_HighlightElementsID);
Regards,
Tibor
Anonymous
Not applicable
Tibor wrote:
Hi,

Yes.
For example if you move the element to an invisible layer, that way the element will become invisible. If your element is on an invisible layer, then you can move it to a visible layer to make the element visible also:
GS::Array<API_Guid> walls;
ACAPI_Element_GetElemList (API_WallID, &walls);

const API_AttributeIndex hiddenLayerIndex = GetIndexOfHiddenNotLockedLayer ();

if (walls.GetSize () > 0 && hiddenLayerIndex > 0) {
	ACAPI_CallUndoableCommand (GS::UniString ("Move walls to an invisible layer"), [&] () -> GSErrCode {
		API_Element newParameters = {};
		API_Element newParametersMask = {};

		newParameters.header.layer = hiddenLayerIndex;
		ACAPI_ELEMENT_MASK_SET (newParametersMask, API_Elem_Head, layer);

		return ACAPI_Element_ChangeMore (walls, &newParameters, nullptr, &newParametersMask, 0, true);
	});
}

//------------------------------------------------------

static API_AttributeIndex GetIndexOfHiddenNotLockedLayer ()
{
	API_AttributeIndex	count;
	ACAPI_Attribute_GetNum (API_LayerID, &count);

	for (API_AttributeIndex ii = 1; ii <= count; ++ii) {
		API_Attribute attr = {};
		attr.header.typeID = API_LayerID;
		attr.header.index = ii;
		if (ACAPI_Attribute_Get (&attr) == NoError) {
			const bool isHidden = (attr.layer.head.flags & APILay_Hidden) != 0;
			const bool isLocked = (attr.layer.head.flags & APILay_Locked) != 0;
			if (isHidden && !isLocked)
				return attr.header.index;
		}
	}

	return -1;
}
Please note, that if you want to highlight elements in 3D, then you can use APIIo_HighlightElementsID method. That function highlights the given elements with the given color and the other (non-highlighted) elements can be switched to wireframed mode:
GS::Array<API_Guid> walls;
ACAPI_Element_GetElemList (API_WallID, &walls);

if (walls.GetSize () > 0) {
	GS::HashTable<API_Guid, API_RGBAColor>	highlightedElements;
	API_RGBAColor	highlightColor = { 0.0, 0.5, 0.75, 0.5 };
	for (const API_Guid& wallGuid : walls) {
		highlightedElements.Add (wallGuid, highlightColor);
		highlightColor.f_red += 0.2;
		if (highlightColor.f_red > 1.0)
			highlightColor.f_red = 0.0;
	}

	bool showNotHighlightedElementsWithWireframe = true;
	ACAPI_Interface (APIIo_HighlightElementsID, &highlightedElements, &showNotHighlightedElementsWithWireframe);
}
You can switch off the highlight with the following line:
ACAPI_Interface (APIIo_HighlightElementsID);
Regards,
Tibor
Thank you very much.