**THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED**

*On 16/07/2004 at 09:25, ***xxxxxxxx** wrote:

Actually, I found it simpler to cut the n-gon into quads, being left with a triangle in odd number cases. C4D's approach is rather nerve-wracking. Whereas the polygon vertices are straightforward indices into a vertex array, the UVWs are store as a polygon directly, without indices, but actual data. Therefore, I have to set indices for geometry (easy enough) and fill vectors for UVWs. Very disconcerting. ;/

So, here's what I do (and I've done this before, but, for the life of me, cannot find the 'triangulation' code that I worked out in the past) :

In the first pass, count all of the vertices in each polygon and determine the number of C4D polygons to result with:

fnum += ((n + (n % 2)) / 2) - 1;

where 'n' is the number of vertex indices for the polygon and 'fnum' is a running total of polygons for the object. This works for triangles, quads, and n-gons.

Next, I retrieve the first point (v/vt) for use during subdivision. Subdivision proceeds as standard:

0 1 2 3 [P = 3]

0 3 4 5 [P = 5]

0 5 6 7 [P = 7]

...

0 P P+1 P+2 (triangle; 0 P P+1 P+1)

```
// Parse facet vertex indices -- NOTE: 5+ sided polygons will be subdivided
newFacet = FALSE;
// Get First v/vt indices
if ((token = tokenreader->GetToken(NULL, DELIM_SPACES)) != NULL)
{
strcpy(point, token);
v0 = (LONG)atol(subreader->GetToken(point, DELIM_FACET));
if (v0 > 0) v0--;
else v0 = vnum + v0;
*polyindx = v0;
polyindx++;
if ((token = subreader->GetToken(NULL, DELIM_FACET)) != NULL)
{
vt0 = (LONG)atol(token);
if (vt0 > 0) vt0--;
else vt0 = vtnum + vt0;
uvws->x = UVWs[vt0].x;
uvws->y = UVWs[vt0].y;
uvws->z = UVWs[vt0].z;
uvws++;
}
}
while ((token = tokenreader->GetToken(NULL, DELIM_SPACES)) != NULL)
{
// preprocess subdivided n-gon
if (newFacet)
{
*polyindx = v0;
polyindx++;
*polyindx = vN;
polyindx++;
uvws->x = UVWs[vt0].x;
uvws->y = UVWs[vt0].y;
uvws->z = UVWs[vt0].z;
uvws++;
uvws->x = UVWs[vtN].x;
uvws->y = UVWs[vtN].y;
uvws->z = UVWs[vtN].z;
uvws++;
newFacet = FALSE;
}
strcpy(point, token);
*polyindx = (LONG)atol(subreader->GetToken(point, DELIM_FACET));
if (*polyindx > 0) (*polyindx)--;
else *polyindx = vnum + *polyindx;
if ((token = subreader->GetToken(NULL, DELIM_FACET)) != NULL)
{
p = (LONG)atol(token);
if (p > 0) p--;
else p = vtnum + p;
uvws->x = UVWs
.x;
uvws->y = UVWs
.y;
uvws->z = UVWs
.z;
if (uvws == &(uvwstruct.d))
{
// Add UV polygon
uvwTag->Set(fnum, uvwstruct);
uvws = &(uvwstruct.a);
vtN = p;
}
else uvws++;
}
if (polyindx == &(polygon->d))
{
// Add polygon to Group SelectionTag
gmtG->AddPolygon(fnum);
// Add polygon to Material SelectionTag
gmtM->AddPolygon(fnum);
vN = *polyindx;
fnum++;
polygon++;
polyindx = &(polygon->a);
newFacet = TRUE;
}
else polyindx++;
}
// Handle [Final] Triangles
if (polyindx == &(polygon->d))
{
polygon->d = polygon->c;
uvwstruct.d.x = uvwstruct.c.x;
uvwstruct.d.y = uvwstruct.c.y;
uvwstruct.d.z = uvwstruct.c.z;
// Add polygon to Group SelectionTag
gmtG->AddPolygon(fnum);
// Add polygon to Material SelectionTag
gmtM->AddPolygon(fnum);
// Add UV polygon
uvwTag->Set(fnum, uvwstruct);
// update indices
uvws = &(uvwstruct.a);
polygon++;
polyindx = &(polygon->a);
fnum++;
}
```

Kuroyume