Choose your top Archicad wishes!

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

Getting texture coordinates... oh my.

I am working on an exporter and trying to get the texture coordinates out of mesh bodies.

I was extremely surprised to find that getting a UV depends on the 3D position of the vertex in the world !

ModelerAPI::Polygon::.GetTextureCoordinate(Vertex* positionInWorldCoordSystem, TextureCoordinate* uv)

This basically implied that textures are fixed in 3D space and infinitely tiled, and that the geometry itself slides from under the texture space, and indeed it does.

To illustrate the concept of the sliding geometry, in the image below, I've separated two pieces away from each other, creating a small gap between them (the two yellow lines represents the distance of the separation, and I've circled a little rusty blob. I would like to bring your attention to the fact that the blob remains at the exact same spot in 3D, while the geometry has moved to the right a little bit.

And that's mostly fine. In a CAD system like archicad, it's fine if textures are projected onto surfaces automatically like this, in order to not have artists perform UV mapping on the geometry. So, that's okay.

[See 1st image below]

But then in the same model, I have other objects that have textures on them (like the background on TV or computer) but these textures are not applied in world space, they appear to be fixed at the vertex (obviously, you don't want the picture of the 27-inch Mac's desktop background to be slippy-slidey depending on where the Mac is in the world (!) ).

[See 2nd image below]

But then, how would I get the texture coordinates for these types of objects (the Mac?)?

Using the ModelerAPI, the only thing I seem to have access to is a mesh body, for which I can enumerate polygons, and for which I can only get texture coordinate by passing the vertex in world space? (eg: the function I highlighted above).

And I also checked the standard API:
ACAPI_Goodies(APIAny_GetTextureCoordID, APITexCoordPars* pars, API_UVCoord* uv)

and where API_TexCoordPars = { elemIdx, bodyIdx, pgonIndex, filler_1, API_Coiord3D surfacePoint }

Which is essentially the same as what the ModelerAPI exposes.

So anyway, how do I get the correct texture coordinates for objects such as a Mac, a Lamp, a TV, etc?

Viktor Kovacs
Archicad has several ways to calculate texture coordinates for different objects, but at the end of the day you can use the same way through Modeler API to access them.

If you pass the ModelerAPI::Vertex you got from the polygon you will get the texture coordinate you want for every vertex. So basically you don't have to deal with different texture projection types, you will always get the proper texture coordinates this way.
I eventually figured this out.

What I was missing from my code was this code below in bold. Now everything lines up.

ModelerAPI::TextureCoordinate uv;
polygon.GetTextureCoordinate(&positionW, &uv);

uv.ApplyMaterialParameters(material.GetTextureRotationAngle(), texture.GetXSize(), texture.GetYSize());