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

*On 26/07/2012 at 10:54, ***xxxxxxxx** wrote:

In case it's useful, here is some code that I cobbled together from some older SDK example code...

```
//------------------------------------------------------------------------------------------------------
//******************************************************************************************************
// FrontalMapUVs() - perform a simple 'frontal' uv-mapping
//******************************************************************************************************
//------------------------------------------------------------------------------------------------------
#define SIGDIG 5.0
static Real sign(Real n)
{
if( n > 0.0 ) return 1.0;
if( n < 0.0 ) return -1.0;
return 0.0;
}
static Real TrimDecimal(Real num, Real digits)
{
Real n;
n = num * Pow((Real)10.0, digits);
n = sign(n) * Abs(Floor(n + 0.5));
return n / Pow((Real)10.0, digits);
}
Bool FrontalMapUVs(PolygonObject *op, Matrix mg)
{
if( !op ) return false;
LONG numFaces = op->GetPolygonCount();
LONG numVerts = op->GetPointCount();
Vector *pVerts = op->GetPointW();
CPolygon *pPolys = op->GetPolygonW();
UVWTag *pUVTag = (UVWTag * )op->MakeVariableTag(Tuvw, numFaces);
if( !pUVTag )
return false;
#ifdef _R12_SDK_
UVWHandle pUVHndl = pUVTag->GetDataAddressW();
if( !pUVHndl )
return false;
#elif _R11p5_SDK_
void *pUVHndl = pUVTag->GetDataAddressW();
if( !pUVHndl )
return false;
#else
void *pUVHndl = NULL;
#endif
LONG ndx;
Real lenxinv, lenyinv, lenzinv;
Vector mapCenter, mapSize, vMin, vMax;
vMin.x = 100000.0;
vMin.y = 100000.0;
vMin.z = 100000.0;
vMax.x = -100000.0;
vMax.y = -100000.0;
vMax.z = -100000.0;
for(ndx=0; ndx<numVerts; ndx++)
{
Vector pt = pVerts[ndx] * mg;
if( pt.x < vMin.x ) vMin.x = pt.x;
if( pt.x > vMax.x ) vMax.x = pt.x;
if( pt.y < vMin.y ) vMin.y = pt.y;
if( pt.y > vMax.y ) vMax.y = pt.y;
if( pt.z < vMin.z ) vMin.z = pt.z;
if( pt.z > vMax.z ) vMax.z = pt.z;
}
mapSize.x = Abs(vMax.x - vMin.x);
mapSize.y = Abs(vMax.y - vMin.y);
mapSize.z = Abs(vMax.z - vMin.z);
mapCenter.x = vMin.x+(mapSize.x*0.5);
mapCenter.y = vMin.y+(mapSize.y*0.5);
mapCenter.z = vMin.z+(mapSize.z*0.5);
if (mapSize.x!=0.0) lenxinv = 1.0/mapSize.x; else lenxinv = 0.0;
if (mapSize.y!=0.0) lenyinv = 1.0/mapSize.y; else lenyinv = 0.0;
if (mapSize.z!=0.0) lenzinv = 1.0/mapSize.z; else lenzinv = 0.0;
// Walk the list of polygons and map the UVs
for(ndx=0; ndx<numFaces; ndx++)
{
UVWStruct uvw;
cmpUVGet(pUVTag, pUVHndl, ndx, uvw);
Vector pt_a = (pVerts[pPolys[ndx].a] - mapCenter) + mg.off;
Vector pt_b = (pVerts[pPolys[ndx].b] - mapCenter) + mg.off;
Vector pt_c = (pVerts[pPolys[ndx].c] - mapCenter) + mg.off;
Vector pt_d = (pVerts[pPolys[ndx].d] - mapCenter) + mg.off;
uvw.a.x = TrimDecimal((pt_a.x*lenxinv)+0.5, SIGDIG);
uvw.a.y = TrimDecimal((-pt_a.y*lenyinv)+0.5, SIGDIG);
uvw.b.x = TrimDecimal((pt_b.x*lenxinv)+0.5, SIGDIG);
uvw.b.y = TrimDecimal((-pt_b.y*lenyinv)+0.5, SIGDIG);
uvw.c.x = TrimDecimal((pt_c.x*lenxinv)+0.5, SIGDIG);
uvw.c.y = TrimDecimal((-pt_c.y*lenyinv)+0.5, SIGDIG);
uvw.d.x = TrimDecimal((pt_d.x*lenxinv)+0.5, SIGDIG);
uvw.d.y = TrimDecimal((-pt_d.y*lenyinv)+0.5, SIGDIG);
cmpUVSet(pUVTag, pUVHndl, ndx, uvw);
}
return true;
}
```

...note that I call that routine IF the mesh is not already uv-mapped...

```
// start by grabbing the current UVWTag
UVWTag *pSrcUVs = (UVWTag* )(op->GetTag(Tuvw, 0));
if( !pSrcUVs )
{
// if not already mapped, do a simple frontal mapping
if( !FrontalMapUVs(op, op->GetMgn()) )
return NULL;
....
```

...also note that I'm just passing the mesh's global matrix, so you could remove that argument and just grab it inside that routine.

The only other note is the "cmpUVGet()/cmpUVSet()" calls... those are calls to my version-compatibility routines...

```
//-------------------------------------------------------------
// cmpUVGet()
//-------------------------------------------------------------
void cmpUVGet(UVWTag *pUVWTag, UVWHandle pUVHndl, LONG ndx, UVWStruct& uvw)
{
#ifdef _R11p5_SDK_
if( pUVWTag && pUVHndl ) pUVWTag->Get(pUVHndl, ndx, uvw);
#else
if( pUVWTag ) uvw = pUVWTag->Get(ndx);
#endif
}
//-------------------------------------------------------------
// cmpUVSet()
//-------------------------------------------------------------
void cmpUVSet(UVWTag *pUVWTag, UVWHandle pUVHndl, LONG ndx, const UVWStruct& uvw)
{
#ifdef _R11p5_SDK_
if( pUVWTag && pUVHndl ) pUVWTag->Set(pUVHndl, ndx, uvw);
#else
if( pUVWTag ) pUVWTag->Set(ndx, uvw);
#endif
}
```

...where my _Rxx_SDK_ defines are *cumulative* (ie. R11.5 is also defined in my R12 (and later) builds and R11.5 and R12 defines are also defined in my R13 (and later) builds, along with the R13 define, etc.). This is a carry-over from long, long ago... I'm in the process of changing over to a "#if API_VERSION < 13000" type system.