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!

I would like to know how to create a wall using Wall Geometry Method:Polygonal.

LeeJaeYoung
Virtuoso

LeeJaeYoung_1-1696588536446.png

I would like to know how to create a wall using Wall Geometry.
What sample code can I study?

 

AC27 on window 11
1 ACCEPTED SOLUTION

Accepted Solutions
Solution

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;
}

View solution in original post

8 REPLIES 8
Tim Ball
Expert

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.

Tim Ball

AC26, iMac

User since V5

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.

LeeJaeYoung_0-1696810947599.png

 

LeeJaeYoung_1-1696812103234.png

 

 

AC27 on window 11
Solution

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;
}
kency
Enthusiast

@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.

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

kency
Enthusiast

Adding the Bug report link here for other community members to track

Viktor Kovacs
Graphisoft
Graphisoft

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;

 

 

Yes both in the video from kency and in my tests the wall type was explicitly set to basic and we get a crash.