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

Missing doors from ACAPI_Element_GetRelations() when placed in middle of room/zone

Bitwreckage
Booster

I have been investigating an issue where our Archicad plugin did not seem able to fetch doors, which were placed in the middle of a room/zone.

Eventually I found that our code uses in essence ACAPI_Element_GetRelations( roomGuid, API_DoorID, &relData ) to get all doors belonging to a room/zone, but that this method would never give us a result with a door residing in the middle of a zone.

I started out testing this method with API_DoorID as the "otherType" parameter, but soon tried out the whole range of types from API_ZombieElemID up to and including API_OpeningID plus API_ExternalElemID, but to no avail. No in-the-middle-of-room doors for me!

My current "hack solution" is to use ACAPI_Element_GetElemList() with the element type id API_DoorID, and then filtering the result on fromRoom or toRoom of the received doors being the room of interest.

I am concerned though about the efficiency of this approach - thinking of how this would work in big models, where the user could be dealing with several thousand instances of doors.

Can anybody recommend an efficient way of retrieving all doors belonging to a room (including doors residing in the middle of the room)?

2 REPLIES 2
mszaraz
Newcomer

 

I think some parameter or its combination is wrong. The following code snippet works for me (if the doors are connected to the Zone/Room). The code snippet is based on the Element_Test example addon's source (Do_DumpZone method).

API_Element			element = {};

if (!ClickAnElem ("Click a zone", API_ZoneID, nullptr, &element.header.type, &element.header.guid)) {
	WriteReport_Alert ("No zone was clicked");
	return;
}

WriteReport ("Doors connected to the selected room:");
API_RoomRelation	roomInfo;
GSErrCode err = ACAPI_Element_GetRelations (element.header.guid, API_ZombieElemID, &roomInfo);
if (err == NoError && roomInfo.elementsGroupedByType.ContainsKey (API_DoorID)) {
	for (const auto& id : roomInfo.elementsGroupedByType[API_DoorID]) {
		WriteReport ("%s", APIGuidToString (id).ToCStr ().Get ());
	}
}

The output is:

Doors connected to the selected room:
05958BF9-E5F0-3046-8BDD-12C0EE5E501B
7C23555D-563A-D940-838C-4B85C1DE4CFE

For this zone/room:

Screenshot 2023-01-23 at 14.18.15.png

 

Thank you mszaraz - I have been busy attending other tasks for a while, so I was only recently able to get back to this one.

 

While the code snippet gave me very valuable insight into how I might potentially improve our current code, it did unfortunately not work with my example model.

In accordance with your suggestion, I am doing this in my code:

 

ACAPI_Element_GetRelations(zoneGuid, API_ZombieElemID, &roomRelation);

if( roomRelation.elementsGroupedByType.ContainsKey(API_DoorID))

 

I never get into the if-block for the zone where the door is place in the middle. However for the zone where the door is attached to the bounding wall, the if-block does get activated.

Could there be some other conditions for getting this right in the model? I noticed that the model in your example contains a bounding wall on the zone, whereas my model has a “raw” zone for that part of the model.

Here is a screenshot of my model:

Bitwreckage_0-1681193976189.png

 

Any further suggestions are much welcome.

Thank you for your help!