Here’s a little method for getting the cotan weights at any vertex of a mesh from part of the script I posted in this thread. It takes a Plankton mesh but I think could be converted to use a normal Rhino mesh.
Though as you both point out, if the mesh quality is good, the difference between using this and just the uniform weighted Laplacian is very small, so it’s often not really needed.
{
int[] neighbours = P.Vertices.GetVertexNeighbours(i);
Point3d vert = P.Vertices[i].ToPoint3d();
int valence = P.Vertices.GetValence(i);
Point3d[] neighbourPts = new Point3d[valence];
Vector3d[] radial = new Vector3d[valence];
Vector3d[] around = new Vector3d[valence];
double[] cotWeight = new double[valence];
double weightSum = 0;
for (int j = 0; j < valence; j++)
{
neighbourPts[j] = P.Vertices[neighbours[j]].ToPoint3d();
radial[j] = neighbourPts[j] - vert;
}
for (int j = 0; j < valence; j++)
{
around[j] = neighbourPts[(j + 1) % valence] - neighbourPts[j];
}
for (int j = 0; j < neighbours.Length; j++)
{
int previous = (j + valence - 1) % valence;
Vector3d cross1 = Vector3d.CrossProduct(radial[previous], around[previous]);
double dot1 = radial[previous] * around[previous];
int next = (j + 1) % valence;
Vector3d cross2 = Vector3d.CrossProduct(radial[next], around[j]);
double dot2 = radial[next] * around[j];
cotWeight[j] = Math.Abs(dot1 / cross1.Length) + Math.Abs(dot2 / cross2.Length);
weightSum += cotWeight[j];
}
for (int j = 0; j < cotWeight.Length; j++) cotWeight[j] /= weightSum;
return cotWeight;
}