BIM Coordinator Program (INT) April 22, 2024

Find the next step in your career as a Graphisoft Certified BIM Coordinator!

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

Offset all edges of a polygon/polyarc.

ReignBough
Enthusiast
Previously known as: PGPolyPositionExt crashes.
Geometry::PGRelPolyPosExt pos = Geometry::UnknownStatus;
g_PolyArc_LastError = Geometry::PGPolyPositionExt(&polyExt1, &polyExt2, &pos);
Both polyExt1 and polyExt2 are derived from memo:

memo to Polygon2DData: (from Element_Snippents.cpp)
static GSErrCode	ConstructPoly2DDataFromElementMemo (const API_ElementMemo& memo, Geometry::Polygon2DData& polygon2DData)
{
	GSErrCode err = NoError;

	Geometry::InitPolygon2DData (&polygon2DData);

	static_assert (sizeof (API_Coord) == sizeof (Coord), "sizeof (API_Coord) != sizeof (Coord)");
	static_assert (sizeof (API_PolyArc) == sizeof (PolyArcRec), "sizeof (API_PolyArc) != sizeof (PolyArcRec)");

	polygon2DData.nVertices = BMGetHandleSize (reinterpret_cast<GSHandle> (memo.coords)) / sizeof (Coord) - 1;
	polygon2DData.vertices = reinterpret_cast<Coord**> (BMAllocateHandle ((polygon2DData.nVertices + 1) * sizeof (Coord), ALLOCATE_CLEAR, 0));
	if (polygon2DData.vertices != NULL)
		BNCopyMemory (*polygon2DData.vertices, *memo.coords, (polygon2DData.nVertices + 1) * sizeof (Coord));
	else
		err = APIERR_MEMFULL;

	if (err == NoError && memo.parcs != NULL) {
		polygon2DData.nArcs = BMGetHandleSize (reinterpret_cast<GSHandle> (memo.parcs)) / sizeof (PolyArcRec);
		if (polygon2DData.nArcs > 0) {
			polygon2DData.arcs = reinterpret_cast<PolyArcRec**> (BMAllocateHandle ((polygon2DData.nArcs + 1) * sizeof (PolyArcRec), ALLOCATE_CLEAR, 0));
			if (polygon2DData.arcs != NULL)
				BNCopyMemory (*polygon2DData.arcs + 1, *memo.parcs, polygon2DData.nArcs * sizeof (PolyArcRec));
			else
				err = APIERR_MEMFULL;
		}
	}

	if (err == NoError) {
		polygon2DData.nContours = BMGetHandleSize (reinterpret_cast<GSHandle> (memo.pends)) / sizeof (Int32) - 1;
		polygon2DData.contourEnds = reinterpret_cast<UIndex**> (BMAllocateHandle ((polygon2DData.nContours + 1) * sizeof (UIndex), ALLOCATE_CLEAR, 0));
		if (polygon2DData.contourEnds != NULL)
			BNCopyMemory (*polygon2DData.contourEnds, *memo.pends, (polygon2DData.nContours + 1) * sizeof (UIndex));
		else
			err = APIERR_MEMFULL;
	}

	if (err == NoError) {
		Geometry::GetPolygon2DDataBoundBox (polygon2DData, &polygon2DData.boundBox);
		polygon2DData.status.isBoundBoxValid = true;
	} else {
		Geometry::FreePolygon2DData (&polygon2DData);
	}

	return err;
}		// ConstructPoly2DDataFromElementMemo
Polygon2DData to PGPOLYEXT: (from: Post #212330)
GSErrCode Convert_Polygon2DData_To_PGPOLYEXT (const Geometry::Polygon2DData&    polygon2DData, 
                                                Geometry::PGPOLYEXT*         pgPOLYEXT) 
{ 
   if (&polygon2DData == NULL) 
      return ErrParam; 
 
   BNZeroMemory (pgPOLYEXT, sizeof (Geometry::PGPOLYEXT)); 
 
   // here comes a little bit ugly cast 
   pgPOLYEXT->data = reinterpret_cast<GSPtr> (const_cast<Geometry::Polygon2DData*> (&polygon2DData)); 
 
   // Perhaps you need to set some other attributes too: 
   //  pgPOLYEXT->status.isSameDirEdgeLegal = polygon2DData.status.isSameDirEdgeLegal; 
   //  pgPOLYEXT->epsilon = SMALLEPS * 8; 
   //  pgPOLYEXT->minVertexDist = 3 * pgPOLYEXT->epsilon; 
 
   return NoError; 
} 
The crash is for some instances only. I tested it in a small test model, it works. But when I tested on large test model, it crashes. When I skipped the slab polygons that cause the crash (on debug mode), it is okay.

EDIT 1: (2018 Feb 23)

Found what causes the crash. It is when i called OffsetPolygon2DDataEdge() function to adjust the main polygon. When I removed this code, it does not crash anymore. It probably beacuse I adjust one edge at a time.

What I need now is a function the same as this but adjust all the edges all at once. Is there such thing? Like this:
~ReignBough~
ARCHICAD 26 INT (from AC18)
Windows 11 Pro, AMD Ryzen 7, 3.20GHz, 32.0GB RAM, 64-bit OS
0 REPLIES 0
Learn and get certified!