License Delivery maintenance is expected to occur on Saturday, November 30, between 8 AM and 11 AM CET. This may cause a short 3-hours outage in which license-related tasks: license key upload, download, update, SSA validation, access to the license pool and Graphisoft ID authentication may not function properly. We apologize for any inconvenience.
Archicad C++ API
About Archicad add-on development using the C++ API.

How to triangulate arcs

Anonymous
Not applicable
Hello,

I'm new to Archicad and am looking into a bug whereby shell objects doesn't appear ( I suspect because there isn't an implementation to handle arcs/shell). The original implementer of our archicad codebase left so I'm picking up the pieces so to say.

From what I can tell, we are using ACPI_Goodies(API_RegularizePolyID) to triangulate Archicad primitives. I did fix the case for APIERR_IRREGULARPOLY by using API_RegularizedPolyID. However I'm still seeing error APIERR_REFUSEDPAR return by APIAny_TriangulatePolyID due to arc since the function only accept polygons w/o arc segments. I was just wondering if someone could point me towards tutorial/sample codes/ or how to go about triangulating arcs?

Thanks in advance,
Ian
4 REPLIES 4
Akos Somorjai
Graphisoft
Graphisoft
IanTr wrote:
Hello,

I'm new to Archicad and am looking into a bug whereby shell objects doesn't appear ( I suspect because there isn't an implementation to handle arcs/shell). The original implementer of our archicad codebase left so I'm picking up the pieces so to say.

From what I can tell, we are using ACPI_Goodies(API_RegularizePolyID) to triangulate Archicad primitives. I did fix the case for APIERR_IRREGULARPOLY by using API_RegularizedPolyID. However I'm still seeing error APIERR_REFUSEDPAR return by APIAny_TriangulatePolyID due to arc since the function only accept polygons w/o arc segments. I was just wondering if someone could point me towards tutorial/sample codes/ or how to go about triangulating arcs?

Thanks in advance,
Ian
Hello Ian,

I would take a look at ACAPI_Goodies (APIAny_TriangulatePolyID, ...).

Best, Akos
Anonymous
Not applicable
Akos,

According to the API doc, ACAPI_Goodies (APIAny_TriangulatePolyID, ...) only accept polygons that has no arc segments. The code snippet on that page also shows it skips over nArcs > 0. I was just wondering if there are functions/methods that I missed looking through the samples that handles triangulation of arcs.

Cheers,
Ian
Ralph Wessel
Mentor
IanTr wrote:
According to the API doc, ACAPI_Goodies (APIAny_TriangulatePolyID, ...) only accept polygons that has no arc segments. The code snippet on that page also shows it skips over nArcs > 0. I was just wondering if there are functions/methods that I missed looking through the samples that handles triangulation of arcs.
You could facet the arc edges to the required level of precision first.
Ralph Wessel BArch
Software Engineer Speckle Systems
Akos Somorjai
Graphisoft
Graphisoft
Ralph wrote:
IanTr wrote:
According to the API doc, ACAPI_Goodies (APIAny_TriangulatePolyID, ...) only accept polygons that has no arc segments. The code snippet on that page also shows it skips over nArcs > 0. I was just wondering if there are functions/methods that I missed looking through the samples that handles triangulation of arcs.
You could facet the arc edges to the required level of precision first.
Ian,

Here comes a sample which shows how to do that with the help of the Geometry module.
#include "GenArc2DData.h"
#include "Ellipse2DData.h"

/*----------------------------------------------------------**
**	Gets the current ARCHICAD settings for arc division		**
**----------------------------------------------------------*/
static double GetMaxDiff ()
{
	double	maxDiff = EPS;
	if (ACAPI_Environment (APIEnv_GetExportToleranceID, &maxDiff) != NoError) {
		API_MagicWandInfo	mwi = {0};
		if (ACAPI_Environment (APIEnv_GetMagicWandSetsID, &mwi) != NoError)
			maxDiff = EPS;
		else
			maxDiff = mwi.arcDiff;
	}

	return maxDiff;
}

/*----------------------------------------------------------**
**	Divides an arc according to the currect AC settings		**
**----------------------------------------------------------*/
static GSErrCode DivideArc (const API_Coord& orig, double r,
							double begAng, double endAng, bool reflected,
							double ratio, bool elliptic,
							USize * nCo, Coord** hCo)
{
	GenArc genArc;

	if (elliptic) {
		genArc.SetToEllipseArc (Geometry::Ellipse ((const Coord &)orig, r, ratio, 0.0), begAng, endAng, reflected);
	} else {
		genArc.SetToCircleArc ((const Coord &)orig, r, begAng, endAng, reflected);
	}
	Geometry::DivideEllArcToCo  (genArc, GetMaxDiff (), hCo, nCo);

	return NoError;
}

/*----------------------------------------------------------**
**	Writes out a Circular/Elliptic Arc, divided				**
**----------------------------------------------------------*/
static GSErrCode	DWF_WrDividedArc (const API_Coord& orig, double r,
									  double begAng, double endAng, bool reflected = false,
									  double ratio = 1.0, bool elliptic = false)
{
	USize	nCo = 0;
	Coord	**hCo = reinterpret_cast<Coord **> (BMhAll (0));
	GSErrCode lastErr = DivideArc (orig, r, begAng, endAng, reflected, ratio, elliptic, &nCo, hCo);
	if (lastErr != NoError) {
		BMhFree ((GSHandle) hCo);
		return lastErr;
	}

	// ...

	BMhFree ((GSHandle) hCo);

	return lastErr;
}
Regards, Akos