2023-12-20 01:35 AM - last edited on 2024-09-16 02:41 PM by Doreena Deng
Hello ArchiCAD Developer Community,
I'm currently developing an add-on for ArchiCAD and have encountered a challenge that I need some assistance with. My add-on aims to process various building elements like walls, slabs, and doors, and I need to retrieve not only their GUIDs but also their names (or local names) and bounding boxes.
So far, I have successfully obtained the GUIDs of the elements, but I'm struggling with how to fetch their names and bounding boxes. I'm looking for a way to access these additional details for each building element.
Here's a summary of my current approach:
My question is:
I suspect there are specific API functions or properties that I need to use, but I haven't been able to find the right approach.
Here is a snippet of the code where I process the elements:
void ReportElementProperties(const API_Guid& elementGuid, API_ElemTypeID elemType, std::ofstream& outFile)
{
char reportStr[1024];
API_Element element;
BNZeroMemory(&element, sizeof(API_Element));
element.header.guid = elementGuid;
// Retrieve the element
if (ACAPI_Element_Get(&element) == NoError) {
GS::UniString elemName;
// Handle Zone type specifically
if (elemType == API_ZoneID) {
// Assuming API_ZoneID correctly identifies a Zone
API_ZoneType& zone = element.zone;
GS::Guid gsGuid = APIGuid2GSGuid(zone.stampGuid);
std::string guidStr = (const char*)gsGuid.ToUniString().ToCStr().Get();
sprintf(reportStr, "Zone Stamp GUID: %s, Position: (%.2f, %.2f)", guidStr.c_str(), zone.pos.x, zone.pos.y);
// Include the room or zone name if it exists
if (!zone.roomName[0]) {
strcat(reportStr, ", Room/Zone Name: ");
strcat(reportStr, (const char*)zone.roomName);
}
}
else if (elemType == API_DoorID) {
// Handle Door elements
API_DoorType& door = element.door;
// Access markGuid from openingBase
GS::Guid markGuid = APIGuid2GSGuid(door.openingBase.markGuid);
std::string markGuidStr = (const char*)markGuid.ToUniString().ToCStr().Get();
sprintf(reportStr, "Door Element, GUID: %s, Marker GUID: %s", APIGuidToString(elementGuid).ToCStr().Get(), markGuidStr.c_str());
}
else {
// Handle other types (walls, slabs, etc.)
if (ACAPI_Element_GetElemTypeName(elemType, elemName) == NoError) {
sprintf(reportStr, "Element Type: %s, GUID: %s", (const char*)elemName.ToCStr(), APIGuidToString(elementGuid).ToCStr().Get());
}
else {
sprintf(reportStr, "Element Type: %d, GUID: %s", elemType, APIGuidToString(elementGuid).ToCStr().Get());
}
}
Any guidance on how to retrieve both the name and bounding box for each building element within the add-on would be greatly appreciated. Are there specific API calls or structs that I should be looking into?
Thank you in advance for your time and assistance!
Best regards,
Solved! Go to Solution.
2023-12-20 06:52 AM
For the bounding box you can use the ACAPI_Element_CalcBounds function.
For the name it depends on what you are trying to do. It may be different for some element types, but these are functions that work with all types:
2023-12-20 06:52 AM
For the bounding box you can use the ACAPI_Element_CalcBounds function.
For the name it depends on what you are trying to do. It may be different for some element types, but these are functions that work with all types:
2023-12-20 11:52 PM
@Viktor Kovacs Thank you very much for the feedback.
// Retrieve the element
if (ACAPI_Element_Get(&element) == NoError) {
GS::UniString elemName;
// Handle Zone type specifically
if (elemType == API_ZoneID) {
// Assuming API_ZoneID correctly identifies a Zone
API_ZoneType& zone = element.zone;
GS::Guid gsGuid = APIGuid2GSGuid(zone.stampGuid);
std::string guidStr = (const char*)gsGuid.ToUniString().ToCStr().Get();
sprintf(reportStr, "Zone Stamp GUID: %s, Position: (%.2f, %.2f)", guidStr.c_str(), zone.pos.x, zone.pos.y);
// Include the room or zone name if it exists
if (!zone.roomName[0]) {
strcat(reportStr, ", Room/Zone Name: ");
strcat(reportStr, (const char*)zone.roomName);
}
}
I have a small follow-up question to that.
I tried to handle the zone part separately. I got zone details but not room details such as room name etc. Is there a way to get this one also?
Thanks.
2023-12-21 08:39 AM
There are two problems with your code:
Something like this:
if (zone.roomName[0]) {
strcat_s (reportStr, ", Room/Zone Name: ");
strcat_s (reportStr, GS::UniString (zone.roomName).ToCStr ());
}
2023-12-21 05:10 PM
FYI: Everything your asking for can be returned with a short Python script including the 2D and 3D bounding box coordinates - Just saying , it's a lot simpler??