Developer forum
cancel
Showing results for 
Search instead for 
Did you mean: 

ACAPI_3D_DecomposePgon

stefan
Booster
I've done it again... I've relooked at my Radiance exporter and am stumbling on the decomposition of the ArchiCAD polygon into a set of valid convex polygons.

I think it is a strictly C++ question, but the sparse documentation leaves me not much choice.

The docs tell me:
ACAPI_3D_DecomposePgon(long ipgon, long ***cpoly)
This function is used to decompose a polygon into convex polygons.
The polygon is defined by ipgon index.
The decomposed polygon is returned in the cpoly long array,
which contains the following values:
[-n], [-m1], i1, i2, ... i(m1), [-m2], j1, j2, ... j(m2)...
And now the question:
Do I need to set up an array for the function to fill, or does the function allocates memory itself? I hate code that uses more then one * after eachother 😉
When I try the following, it compiles and runs, but somehow the array seems to be gone... Or at least the cpoly is pointing to nowhere:
//j is allready referencing the current polygon
long * Verts = new long[100]; // array of 100 longs (seems stupid)
long ** cpoly = &Verts; // a pointer to this array
GSErrCode TriangulationError = ACAPI_3D_DecomposePgon(j, &cpoly);
When I do this, ArchiCAD goes through, but I cannot do anything with the results... Do I miss something? Do I need to allocate memory? Or do I need an array with pointers to longs? Or is it actually an array of verts?

The documentation is rather vague and unfortunately I have no working example available...

(If I should go back to my first C++-class, then please tell me so)
--- stefan boeykens --- architect-engineer-musician ---
ARCHICAD25/Revit2022/Rhino7/Unity2021/Solibri
MBP2019:i9Octo2.4GHz32GBVega20/BigSur+Win11
ARCHICAD-user since 1998
5 REPLIES 5

Oleg
Advocate
cpoly is a pointer to handle.

long** cpoly=0; // this is handle
bool ok = ACAPI_3D_DecomposePgon( id, &cpoly ) == NoError;
... and after using 
BMhKill((GSHandle*)&cpoly );
PS: One more open source renderer for you http://www.cs.berkeley.edu/~okan/Pixie/pixie.htm

stefan
Booster
Thanks again!

Now, do I need to allocate memory myself or is that the responsability of the DecomposPgn function?

And lastly, I'm still struggling on getting access to the actual array that should be referenced by the cpoly.

Would *cpoly give me acces to it? Or do I need to cast it to a (GSHandle*) and then work through the handle?

----

Bytheway... the Pixie renderer seems nice. And (in contrast with BMRT) the source is included, so it might be possible to link that to an executable. This did work more or less with BMRT, but only single-threaded, not debug and it also gave library conflicts. So I gave up that time.
--- stefan boeykens --- architect-engineer-musician ---
ARCHICAD25/Revit2022/Rhino7/Unity2021/Solibri
MBP2019:i9Octo2.4GHz32GBVega20/BigSur+Win11
ARCHICAD-user since 1998

Oleg
Advocate
stefan wrote:
Thanks again!

Now, do I need to allocate memory myself or is that the responsability of the DecomposPgn function?

And lastly, I'm still struggling on getting access to the actual array that should be referenced by the cpoly.

Would *cpoly give me acces to it? Or do I need to cast it to a (GSHandle*) and then work through the handle?
You dont need to allocate memory, but you need to release the memory ( kill the handle ).

You can access it as (*cpoly) or to create a pointer for easy using like
long* poly = *cpoly;
and then use it just poly

PS: Actually the handle should be locked if you did the pointer like poly ( above ), but it seem it is not required for MacOSX now and I think it was never need for Win.

stefan
Booster
OK, I'm starting to see the light now...

For convex polygons, ACAPI_3D_DecomposePgon doesn't give an error, but returns the cpoly as NULL. Then I don't need it.

When cpoly != NULL I can step through the array as follows:
long n = (*cpoly)[0] * -1; // number of sub-polygons
if (n > 0)
{
	for (long poly = 0; poly < n; ++poly)
	{
		++count;
		long m = (*cpoly)[count] * -1; // number of vertices in current subpolygon
		if (m > 0)
		{
			// get indices to the vertices
			for (long vert = 0; vert < m; ++vert)
			{
				++count;
				long vertindex = (*cpoly)[count];
				// get the actual vertex
				component.header.typeID = API_VertID;
				component.header.index  = vertindex;
				err = ACAPI_3D_GetComponent (&component);
				if (err == NoError)
				{
					double xx, yy, zz;
					xx = component.vert.x;
					yy = component.vert.y;
					zz = component.vert.z;
					// transform it into world coordinates
					Geometry::TMPoint(&tranmat_struct, &xx, &yy, &zz);
					// export...
				} // end if no error getting vertex
			} // end for vert
		} // end if m > 0
	} // end for poly
} // end if n > 0
Well, one step closer to heaven 😉
--- stefan boeykens --- architect-engineer-musician ---
ARCHICAD25/Revit2022/Rhino7/Unity2021/Solibri
MBP2019:i9Octo2.4GHz32GBVega20/BigSur+Win11
ARCHICAD-user since 1998

stefan
Booster
Not quite...

The vertex-index that is retrieved from the cpoly-array is a 0-based index while ArchiCAD uses 1-based indices to get to the real component.vert !

So you have to do the following:
long vertindex = (*cpoly)[count];
vertindex +=1;
before you get the actual vertex (API_VertID)

Is this a bug? Or are they falling in their own booby-traps?
--- stefan boeykens --- architect-engineer-musician ---
ARCHICAD25/Revit2022/Rhino7/Unity2021/Solibri
MBP2019:i9Octo2.4GHz32GBVega20/BigSur+Win11
ARCHICAD-user since 1998

Still looking?

Browse more topics

Back to forum

See latest solutions

Accepted solutions

Start a new discussion!