Patch Interpolator Example

The following is source code for a triangular and quadrilateral patch interpolator

// Triangular patch interpolator
Point3 Patch::interp(PatchMesh *pMesh, float pu, float pv, float pw)
{
   // It had better be a triangular patch!
   assert(type == PATCH_TRI);
   Point3 p;
   PatchVert *vp = pMesh->verts;
   PatchVec *vecp = pMesh->vecs;
   float pu2 = pu * pu;
   float pu3 = pu2 * pu;
   float pu4 = pu3 * pu;
   float pv2 = pv * pv;
   float pv3 = pv2 * pv;
   float pv4 = pv3 * pv;
   float pw2 = pw * pw;
   float pw3 = pw2 * pw;
   float pw4 = pw3 * pw;
  
   // Hold on to your hats -- Here it comes!
   p = vp[v[0]].p * pw4 +
   aux[0] * 4.0f * pu * pw3 +
   aux[1] * 6.0f * pu2 * pw2 +
   aux[2] * 4.0f * pu3 * pw +
   vp[v[1]].p * pu4 +
   aux[3] * 4.0f * pv * pu3 +
   aux[4] * 6.0f * pu2 * pv2 +
   aux[5] * 4.0f * pv3 * pu +
   vp[v[2]].p * pv4 +
   aux[6] * 4.0f * pw * pv3 +
   aux[7] * 6.0f * pv2 * pw2 +
   aux[8] * 4.0f * pw3 * pv +
   vecp[interior[0]].p * 12.0f * pu * pv * pw2 +
   vecp[interior[1]].p * 12.0f * pu2 * pv * pw +
   vecp[interior[2]].p * 12.0f * pu * pv2 * pw;
   return p;
}
 
// Quadrilateral patch interpolator
Point3 Patch::interp(PatchMesh *pMesh, float pu, float pv)
{
   // It had better be a quad patch!
   assert(type == PATCH_QUAD);
   Point3 p;
   PatchVert *vp = pMesh->verts;
   PatchVec *vecp = pMesh->vecs;
   float pu2 = pu * pu;
   float pu1 = 1.0f - pu;
   float pu12 = pu1 * pu1;
   float u0 = pu12 * pu1;
   float u1 = 3.0f * pu * pu12;
   float u2 = 3.0f * pu2 * pu1;
   float u3 = pu2 * pu;
   float pv2 = pv * pv;
   float pv1 = 1.0f - pv;
   float pv12 = pv1 * pv1;
   float v0 = pv12 * pv1;
   float v1 = 3.0f * pv * pv12;
   float v2 = 3.0f * pv2 * pv1;
   float v3 = pv2 * pv;
  
   // Hold on to your hats -- Here it comes!
   p = vp[v[0]].p * u0 * v0 +
   vecp[vec[7]].p * u1 * v0 +
   vecp[vec[6]].p * u2 * v0 +
   vp[v[3]].p * u3 * v0 +
   vecp[vec[0]].p * u0 * v1 +
   vecp[interior[0]].p * u1 * v1 +
   vecp[interior[3]].p * u2 * v1 +
   vecp[vec[5]].p * u3 * v1 +
   vecp[vec[1]].p * u0 * v2 +
   vecp[interior[1]].p * u1 * v2 +
   vecp[interior[2]].p * u2 * v2 +
   vecp[vec[4]].p * u3 * v2 +
   vp[v[1]].p * u0 * v3 +
   vecp[vec[2]].p * u1 * v3 +
   vecp[vec[3]].p * u2 * v3 +
   vp[v[2]].p * u3 * v3;
   return p;
}

Building the vertices are just a matter of looping through your patches and then running through each patches UV space to get the corresponding point on the surface. Below is a sample showing the basics.

float fpd = (float)patchDivs;
for(px = 0; px < numPatches; ++px)
{
   Patch &p = patches[px];
   switch(p.type)
   {
     case PATCH_TRI:
     {
      for(intax = patchDivs - 1; ax > 0; --ax)
       {
         for(int bx = 1; bx < ax; ++bx)
         {
          float u = (float)bx / fpd;
          float v = (float)(patchDivs - ax) / fpd;
          float w = 1.0f - u - v; // Barycentric validity guaranteed!
          mesh.setVert(vert++, p.interp(this, u, v, w));
         }
       }
     }
     break;
     case PATCH_QUAD:
     {
      for(intu = 1; u < patchDivs; ++u)
       {
         float fu = (float)u / fpd;
         for(int v = 1; v < patchDivs; ++v)
         {
          float fv = (float)v / fpd;
          mesh.setVert(vert++, p.interp(this, fu, fv));
         }
       }
     }
     break;
   }
}