We value your input! Please participate in Archicad 28 Home Screen and Tooltips/Quick Tutorials survey
2023-10-06 12:38 PM - last edited on 2024-09-17 01:14 PM by Doreena Deng
I would like to know how to create a wall using Wall Geometry.
What sample code can I study?
Solved! Go to Solution.
2023-10-10 08:41 AM
Yes that's what you are looking for. You will have to use the polygon data in the memos.
Something like this:
GSErrCode CreatePolyWall ()
{
API_Element element {};
element.header.type = API_WallID;
ACAPI_Element_GetDefaults (&element, nullptr);
element.wall.type = APIWtyp_Poly;
element.wall.modelElemStructureType = API_BasicStructure;
element.wall.poly.nCoords = 5;
element.wall.poly.nSubPolys = 1;
element.wall.poly.nArcs = 0;
API_ElementMemo memo{};
memo.coords = reinterpret_cast<API_Coord**> (
BMAllocateHandle (sizeof (API_Coord) * (element.wall.poly.nCoords + 1), ALLOCATE_CLEAR, 0));
if (memo.coords == nullptr) { return APIERR_MEMFULL; }
(*memo.coords)[0] = { 0.0, 0.0 }; // always has to be (0,0)
(*memo.coords)[1] = { 0.0, 0.0 };
(*memo.coords)[2] = { 1.0, 0.0 };
(*memo.coords)[3] = { 1.0, 1.0 };
(*memo.coords)[4] = { 0.0, 1.0 };
(*memo.coords)[5] = (*memo.coords)[1];
memo.pends = reinterpret_cast<Int32**> (
BMAllocateHandle (sizeof (Int32) * (element.wall.poly.nSubPolys + 1), ALLOCATE_CLEAR, 0));
if (memo.pends == nullptr) { return APIERR_MEMFULL; }
(*memo.pends)[0] = 0;
(*memo.pends)[1] = 5; //index of polygon closing coordinate/vertex
memo.vertexIDs = reinterpret_cast<UInt32**> (
BMAllocateHandle (sizeof (UInt32) * (element.wall.poly.nCoords + 1), ALLOCATE_CLEAR, 0));
if (memo.vertexIDs == nullptr) { return APIERR_MEMFULL; }
(*memo.vertexIDs)[0] = element.wall.poly.nCoords;
for (Int32 vIdx = 1; vIdx <= element.wall.poly.nCoords; ++vIdx) {
(*memo.vertexIDs)[vIdx] = vIdx;
}
memo.edgeIDs = reinterpret_cast<UInt32**> (
BMAllocateHandle (sizeof (UInt32) * (element.wall.poly.nCoords + 1), ALLOCATE_CLEAR, 0));
if (memo.edgeIDs == nullptr) { return APIERR_MEMFULL; }
(*memo.edgeIDs)[0] = 0;
for (Int32 eIdx = 1; eIdx <= element.wall.poly.nCoords; ++eIdx) {
(*memo.edgeIDs)[eIdx] = eIdx;
}
GSErrCode err = ACAPI_Element_Create (&element, &memo);
ACAPI_DisposeElemMemoHdls (&memo);
return err;
}
2023-10-08 06:54 PM
I work on old buildings a lot where wall thicknesses vary and often are not even parallel. You can either draw the polygon directly or trace over a survey drawing using the space bar click.
2023-10-09 02:01 AM - edited 2023-10-09 02:42 AM
thank you.
This is the c++ api forum. ^^
I found Polygon in API_WallType. I think I'll probably use this.
I don't know if it's true.
It hasn't been tested yet.
2023-10-10 08:41 AM
Yes that's what you are looking for. You will have to use the polygon data in the memos.
Something like this:
GSErrCode CreatePolyWall ()
{
API_Element element {};
element.header.type = API_WallID;
ACAPI_Element_GetDefaults (&element, nullptr);
element.wall.type = APIWtyp_Poly;
element.wall.modelElemStructureType = API_BasicStructure;
element.wall.poly.nCoords = 5;
element.wall.poly.nSubPolys = 1;
element.wall.poly.nArcs = 0;
API_ElementMemo memo{};
memo.coords = reinterpret_cast<API_Coord**> (
BMAllocateHandle (sizeof (API_Coord) * (element.wall.poly.nCoords + 1), ALLOCATE_CLEAR, 0));
if (memo.coords == nullptr) { return APIERR_MEMFULL; }
(*memo.coords)[0] = { 0.0, 0.0 }; // always has to be (0,0)
(*memo.coords)[1] = { 0.0, 0.0 };
(*memo.coords)[2] = { 1.0, 0.0 };
(*memo.coords)[3] = { 1.0, 1.0 };
(*memo.coords)[4] = { 0.0, 1.0 };
(*memo.coords)[5] = (*memo.coords)[1];
memo.pends = reinterpret_cast<Int32**> (
BMAllocateHandle (sizeof (Int32) * (element.wall.poly.nSubPolys + 1), ALLOCATE_CLEAR, 0));
if (memo.pends == nullptr) { return APIERR_MEMFULL; }
(*memo.pends)[0] = 0;
(*memo.pends)[1] = 5; //index of polygon closing coordinate/vertex
memo.vertexIDs = reinterpret_cast<UInt32**> (
BMAllocateHandle (sizeof (UInt32) * (element.wall.poly.nCoords + 1), ALLOCATE_CLEAR, 0));
if (memo.vertexIDs == nullptr) { return APIERR_MEMFULL; }
(*memo.vertexIDs)[0] = element.wall.poly.nCoords;
for (Int32 vIdx = 1; vIdx <= element.wall.poly.nCoords; ++vIdx) {
(*memo.vertexIDs)[vIdx] = vIdx;
}
memo.edgeIDs = reinterpret_cast<UInt32**> (
BMAllocateHandle (sizeof (UInt32) * (element.wall.poly.nCoords + 1), ALLOCATE_CLEAR, 0));
if (memo.edgeIDs == nullptr) { return APIERR_MEMFULL; }
(*memo.edgeIDs)[0] = 0;
for (Int32 eIdx = 1; eIdx <= element.wall.poly.nCoords; ++eIdx) {
(*memo.edgeIDs)[eIdx] = eIdx;
}
GSErrCode err = ACAPI_Element_Create (&element, &memo);
ACAPI_DisposeElemMemoHdls (&memo);
return err;
}
2024-02-22 10:17 AM
@BerndSchwarzenbacher @LeeJaeYoung
For me, Archicad crashes with this change when the add-on is invoked. Only if I explicitly change the Wall structure to Basic and invoke the add-on it renders without crashing. I have also tried this on Archicad 26 and 27 and the non-demo version. Please watch the loom video linked here.
Is there any setting that we can use to avoid this? Rather than requesting the user to choose Basic Structure?
I am using MacOS.
2024-02-22 11:12 AM
Hi Kency,
I was able to reproduce the same issue as you have. It's very weird and I can't think of any explanation why it is like that.
It could be a bug in the API. So you could put a bug report for it with the developer support.
Best,
Bernd
2024-02-22 12:27 PM
Adding the Bug report link here for other community members to track
2024-02-22 12:32 PM - edited 2024-02-22 01:42 PM
Seems like a bug. Does it crash even if you explicitly set the wall type to basic in the code?
element.wall.modelElemStructureType = API_BasicStructure;
2024-02-22 12:40 PM - edited 2024-02-22 12:40 PM
Yes both in the video from kency and in my tests the wall type was explicitly set to basic and we get a crash.