<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Offset all edges of a polygon/polyarc. in Archicad C++ API</title>
    <link>https://community.graphisoft.com/t5/Archicad-C-API/Offset-all-edges-of-a-polygon-polyarc/m-p/265495#M4024</link>
    <description>&lt;DIV class="actalk-migrated-content"&gt;&lt;I&gt;&lt;/I&gt;&lt;S&gt;&lt;I&gt;&lt;I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/S&gt;Previously known as: &lt;STRONG&gt;PGPolyPositionExt crashes.&lt;/STRONG&gt;&lt;BR /&gt;
&lt;PRE&gt;Geometry::PGRelPolyPosExt pos = Geometry::UnknownStatus;
g_PolyArc_LastError = Geometry::PGPolyPositionExt(&amp;amp;polyExt1, &amp;amp;polyExt2, &amp;amp;pos);&lt;/PRE&gt;
Both polyExt1 and polyExt2 are derived from memo:&lt;BR /&gt;&lt;BR /&gt;memo to Polygon2DData: (from Element_Snippents.cpp)
&lt;PRE&gt;static GSErrCode	ConstructPoly2DDataFromElementMemo (const API_ElementMemo&amp;amp; memo, Geometry::Polygon2DData&amp;amp; polygon2DData)
{
	GSErrCode err = NoError;

	Geometry::InitPolygon2DData (&amp;amp;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&amp;lt;GSHandle&amp;gt; (memo.coords)) / sizeof (Coord) - 1;
	polygon2DData.vertices = reinterpret_cast&amp;lt;Coord**&amp;gt; (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 &amp;amp;&amp;amp; memo.parcs != NULL) {
		polygon2DData.nArcs = BMGetHandleSize (reinterpret_cast&amp;lt;GSHandle&amp;gt; (memo.parcs)) / sizeof (PolyArcRec);
		if (polygon2DData.nArcs &amp;gt; 0) {
			polygon2DData.arcs = reinterpret_cast&amp;lt;PolyArcRec**&amp;gt; (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&amp;lt;GSHandle&amp;gt; (memo.pends)) / sizeof (Int32) - 1;
		polygon2DData.contourEnds = reinterpret_cast&amp;lt;UIndex**&amp;gt; (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, &amp;amp;polygon2DData.boundBox);
		polygon2DData.status.isBoundBoxValid = true;
	} else {
		Geometry::FreePolygon2DData (&amp;amp;polygon2DData);
	}

	return err;
}		// ConstructPoly2DDataFromElementMemo
&lt;/PRE&gt;
Polygon2DData to PGPOLYEXT: (from: &lt;A href="https://archicad-talk.graphisoft.com/viewtopic.php?p=212330#p212330" target="_blank" rel="noopener"&gt;Post #212330&lt;/A&gt;)
&lt;PRE&gt;GSErrCode Convert_Polygon2DData_To_PGPOLYEXT (const Geometry::Polygon2DData&amp;amp;    polygon2DData, 
                                                Geometry::PGPOLYEXT*         pgPOLYEXT) 
{ 
   if (&amp;amp;polygon2DData == NULL) 
      return ErrParam; 
 
   BNZeroMemory (pgPOLYEXT, sizeof (Geometry::PGPOLYEXT)); 
 
   // here comes a little bit ugly cast 
   pgPOLYEXT-&amp;gt;data = reinterpret_cast&amp;lt;GSPtr&amp;gt; (const_cast&amp;lt;Geometry::Polygon2DData*&amp;gt; (&amp;amp;polygon2DData)); 
 
   // Perhaps you need to set some other attributes too: 
   //  pgPOLYEXT-&amp;gt;status.isSameDirEdgeLegal = polygon2DData.status.isSameDirEdgeLegal; 
   //  pgPOLYEXT-&amp;gt;epsilon = SMALLEPS * 8; 
   //  pgPOLYEXT-&amp;gt;minVertexDist = 3 * pgPOLYEXT-&amp;gt;epsilon; 
 
   return NoError; 
} &lt;/PRE&gt;
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.&lt;BR /&gt;&lt;BR /&gt;&lt;STRONG&gt;EDIT 1:&lt;/STRONG&gt; (2018 Feb 23)&lt;BR /&gt;&lt;BR /&gt;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.&lt;BR /&gt;&lt;BR /&gt;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:&lt;/DIV&gt;</description>
    <pubDate>Wed, 12 Jul 2023 15:51:10 GMT</pubDate>
    <dc:creator>ReignBough</dc:creator>
    <dc:date>2023-07-12T15:51:10Z</dc:date>
    <item>
      <title>Offset all edges of a polygon/polyarc.</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/Offset-all-edges-of-a-polygon-polyarc/m-p/265495#M4024</link>
      <description>&lt;DIV class="actalk-migrated-content"&gt;&lt;I&gt;&lt;/I&gt;&lt;S&gt;&lt;I&gt;&lt;I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/S&gt;Previously known as: &lt;STRONG&gt;PGPolyPositionExt crashes.&lt;/STRONG&gt;&lt;BR /&gt;
&lt;PRE&gt;Geometry::PGRelPolyPosExt pos = Geometry::UnknownStatus;
g_PolyArc_LastError = Geometry::PGPolyPositionExt(&amp;amp;polyExt1, &amp;amp;polyExt2, &amp;amp;pos);&lt;/PRE&gt;
Both polyExt1 and polyExt2 are derived from memo:&lt;BR /&gt;&lt;BR /&gt;memo to Polygon2DData: (from Element_Snippents.cpp)
&lt;PRE&gt;static GSErrCode	ConstructPoly2DDataFromElementMemo (const API_ElementMemo&amp;amp; memo, Geometry::Polygon2DData&amp;amp; polygon2DData)
{
	GSErrCode err = NoError;

	Geometry::InitPolygon2DData (&amp;amp;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&amp;lt;GSHandle&amp;gt; (memo.coords)) / sizeof (Coord) - 1;
	polygon2DData.vertices = reinterpret_cast&amp;lt;Coord**&amp;gt; (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 &amp;amp;&amp;amp; memo.parcs != NULL) {
		polygon2DData.nArcs = BMGetHandleSize (reinterpret_cast&amp;lt;GSHandle&amp;gt; (memo.parcs)) / sizeof (PolyArcRec);
		if (polygon2DData.nArcs &amp;gt; 0) {
			polygon2DData.arcs = reinterpret_cast&amp;lt;PolyArcRec**&amp;gt; (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&amp;lt;GSHandle&amp;gt; (memo.pends)) / sizeof (Int32) - 1;
		polygon2DData.contourEnds = reinterpret_cast&amp;lt;UIndex**&amp;gt; (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, &amp;amp;polygon2DData.boundBox);
		polygon2DData.status.isBoundBoxValid = true;
	} else {
		Geometry::FreePolygon2DData (&amp;amp;polygon2DData);
	}

	return err;
}		// ConstructPoly2DDataFromElementMemo
&lt;/PRE&gt;
Polygon2DData to PGPOLYEXT: (from: &lt;A href="https://archicad-talk.graphisoft.com/viewtopic.php?p=212330#p212330" target="_blank" rel="noopener"&gt;Post #212330&lt;/A&gt;)
&lt;PRE&gt;GSErrCode Convert_Polygon2DData_To_PGPOLYEXT (const Geometry::Polygon2DData&amp;amp;    polygon2DData, 
                                                Geometry::PGPOLYEXT*         pgPOLYEXT) 
{ 
   if (&amp;amp;polygon2DData == NULL) 
      return ErrParam; 
 
   BNZeroMemory (pgPOLYEXT, sizeof (Geometry::PGPOLYEXT)); 
 
   // here comes a little bit ugly cast 
   pgPOLYEXT-&amp;gt;data = reinterpret_cast&amp;lt;GSPtr&amp;gt; (const_cast&amp;lt;Geometry::Polygon2DData*&amp;gt; (&amp;amp;polygon2DData)); 
 
   // Perhaps you need to set some other attributes too: 
   //  pgPOLYEXT-&amp;gt;status.isSameDirEdgeLegal = polygon2DData.status.isSameDirEdgeLegal; 
   //  pgPOLYEXT-&amp;gt;epsilon = SMALLEPS * 8; 
   //  pgPOLYEXT-&amp;gt;minVertexDist = 3 * pgPOLYEXT-&amp;gt;epsilon; 
 
   return NoError; 
} &lt;/PRE&gt;
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.&lt;BR /&gt;&lt;BR /&gt;&lt;STRONG&gt;EDIT 1:&lt;/STRONG&gt; (2018 Feb 23)&lt;BR /&gt;&lt;BR /&gt;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.&lt;BR /&gt;&lt;BR /&gt;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:&lt;/DIV&gt;</description>
      <pubDate>Wed, 12 Jul 2023 15:51:10 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/Offset-all-edges-of-a-polygon-polyarc/m-p/265495#M4024</guid>
      <dc:creator>ReignBough</dc:creator>
      <dc:date>2023-07-12T15:51:10Z</dc:date>
    </item>
  </channel>
</rss>

