private double Vrt_wij(int i, int j) { int b = i * 3, c = j * 3; Vector3d s = new Vector3d(mesh.VertexPos, b); Vector3d t = new Vector3d(mesh.VertexPos, c); Vector3d e = t-s; Vector3d ns = new Vector3d(mesh.VertexNormal, b); Vector3d nt = new Vector3d(mesh.VertexNormal, c); double w = (1 + ns.Dot(e) / e.Length()) * (1 + ns.Cross(nt).Length()); return w; }
public Vector3d Rotate(Vector3d axis, double cos, double sin) { return this * cos + (axis.Cross(this)) * sin + axis * ((1.0 - cos) * (axis.Dot(this))); }
// Compute the principle curvatures and directions, i.e. k1, k2, e1, e2. public void ObtainPerVertexPCurAndDirs() { // initialize areas. ComputePointAreas(); int nf = mesh.FaceCount, nv = mesh.VertexCount; // Set up an initial coordinate system per vertex localvu = new Vector3d[nv]; localvv = new Vector3d[nv]; for (int i = 0; i < nf; i++) { int b = i * 3; int c0 = mesh.FaceIndex[b]; int c1 = mesh.FaceIndex[b + 1]; int c2 = mesh.FaceIndex[b + 2]; Vector3d v0 = new Vector3d(mesh.VertexPos, c0 * 3); Vector3d v1 = new Vector3d(mesh.VertexPos, c1 * 3); Vector3d v2 = new Vector3d(mesh.VertexPos, c2 * 3); localvu[c0] = v1 - v0; localvu[c1] = v2 - v1; localvu[c2] = v0 - v2; } for (int i = 0; i < nv; i++) { Vector3d normali = new Vector3d(mesh.VertexNormal, i * 3); localvu[i] = (localvu[i].Cross(normali)).Normalize(); localvv[i] = normali.Cross(localvu[i]); } // Compute curvature per-face for (int i = 0; i < nf; i++) { // Edges int c = i * 3; int d0 = mesh.FaceIndex[c] * 3; int d1 = mesh.FaceIndex[c + 1] * 3; int d2 = mesh.FaceIndex[c + 2] * 3; Vector3d[] e = new Vector3d[3] { new Vector3d(mesh.VertexPos, d2) - new Vector3d(mesh.VertexPos, d1), new Vector3d(mesh.VertexPos, d0) - new Vector3d(mesh.VertexPos, d2), new Vector3d(mesh.VertexPos, d1) - new Vector3d(mesh.VertexPos, d0) }; Vector3d[] normals = new Vector3d[3] { new Vector3d(mesh.VertexNormal, d0), new Vector3d(mesh.VertexNormal, d1), new Vector3d(mesh.VertexNormal, d2) }; // N-T-B coordinate system per face Vector3d t = e[0].Normalize(); Vector3d n = e[0].Cross(e[1]); Vector3d b = n.Cross(t).Normalize(); // Estimate curvature based on variation of normals // along edges double[] m = new double[3] { 0, 0, 0 }; double[][] w = new double[3][]; for (int j = 0; j < 3; ++j) { w[j] = new double[3]; } for (int j = 0; j < 3; ++j) { double u = e[j].Dot(t); double v = e[j].Dot(b); w[0][0] += u * u; w[0][1] += u * v; w[2][2] += v * v; Vector3d dn = normals[(j + 2) % 3] - normals[(j + 1) % 3]; double dnu = dn.Dot(t); double dnv = dn.Dot(b); m[0] += dnu * u; m[1] += dnu * v + dnv * u; m[2] += dnv * v; } w[1][1] = w[0][0] + w[2][2]; w[1][2] = w[0][1]; // Least squares solution double[] diag = new double[3]; if (!ldltdc(w, diag, 3)) { System.Console.WriteLine("ldltdc failed!\n"); continue; } ldltsl(w, diag, m, ref m, 3); // Push it back out to the vertices for (int j = 0; j < 3; j++) { int vj = mesh.FaceIndex[c + j]; double c1 = 0, c12 = 0, c2 = 0; proj_curv(t, b, m[0], m[1], m[2], localvu[vj], localvv[vj], ref c1, ref c12, ref c2); double wt = cornerareas[i][j] / pointareas[vj]; curva[vj] += wt * c1; curvb[vj] += wt * c12; curvc[vj] += wt * c2; } } // Compute principal directions and curvatures at each vertex for (int i = 0; i < nv; i++) { Vector3d ni = new Vector3d(mesh.VertexNormal, i * 3); DiagonalizeCurvature(localvu[i], localvv[i], curva[i], curvb[i], curvc[i], ni, ref pDir1[i], ref pDir2[i], ref curv1[i], ref curv2[i]); } System.Console.WriteLine("Done.\n"); }
public void ObtainDualPCurAndDirs() { ComputeDualPointAreas(); // Compute curvature per-face int nf = mesh.FaceCount, nv = mesh.VertexCount; for (int i = 0; i < nf; i++) { // compute local uv coordinates for face i int cc = i * 3; int c0 = mesh.FaceIndex[cc] * 3; int c1 = mesh.FaceIndex[cc + 1] * 3; int c2 = mesh.FaceIndex[cc + 2] * 3; Vector3d[] eg = new Vector3d[3] { new Vector3d(mesh.VertexPos, c2) - new Vector3d(mesh.VertexPos, c1), new Vector3d(mesh.VertexPos, c0) - new Vector3d(mesh.VertexPos, c2), new Vector3d(mesh.VertexPos, c1) - new Vector3d(mesh.VertexPos, c0) }; // local coordinate system per face Vector3d uu = eg[0].Normalize(); Vector3d nn = new Vector3d(mesh.FaceNormal, cc); Vector3d vv = nn.Cross(uu).Normalize(); // Edges int[] c = new int[3]; for (int j = 0; j < 3; ++j) { c[j] = -1; } for (int j = 0; j < mesh.AdjFF[i].Length; ++j) { c[j] = mesh.AdjFF[i][j] * 3; } for (int j = 0; j < 3; ++j) { int d0 = cc; int d1 = c[j]; int d2 = c[(j + 1) % 3]; if (d1 < 0 || d2 < 0) { continue; } Vector3d[] e = new Vector3d[3] { new Vector3d(mesh.DualVertexPos, d2) - new Vector3d(mesh.DualVertexPos, d1), new Vector3d(mesh.DualVertexPos, d0) - new Vector3d(mesh.DualVertexPos, d2), new Vector3d(mesh.DualVertexPos, d1) - new Vector3d(mesh.DualVertexPos, d0) }; Vector3d[] normals = new Vector3d[3] { new Vector3d(mesh.FaceNormal, d0), new Vector3d(mesh.FaceNormal, d1), new Vector3d(mesh.FaceNormal, d2) }; // N-T-B coordinate system per face Vector3d t = e[0].Normalize(); Vector3d n = e[0].Cross(e[1]).Normalize(); Vector3d b = n.Cross(t).Normalize(); // Estimate curvature based on variation of normals // along edges double[] m = new double[3] { 0, 0, 0 }; double[][] w = new double[3][]; for (int k = 0; k < 3; ++k) { w[k] = new double[3]; } for (int k = 0; k < 3; ++k) { double u = e[k].Dot(t); double v = e[k].Dot(b); w[0][0] += u * u; w[0][1] += u * v; w[2][2] += v * v; Vector3d dn = normals[(k + 2) % 3] - normals[(k + 1) % 3]; double dnu = dn.Dot(t); double dnv = dn.Dot(b); m[0] += dnu * u; m[1] += dnu * v + dnv * u; m[2] += dnv * v; } w[1][1] = w[0][0] + w[2][2]; w[1][2] = w[0][1]; // Least squares solution double[] diag = new double[3]; if (!ldltdc(w, diag, 3)) { System.Console.WriteLine("ldltdc failed!\n"); continue; } ldltsl(w, diag, m, ref m, 3); // Push it back out to the dual vertices double g1 = 0, g12 = 0, g2 = 0; proj_curv(t, b, m[0], m[1], m[2], uu, vv, ref g1, ref g12, ref g2); double wt = dual_cornerareas[i][j] / dual_pointareas[i]; dual_curva[i] += wt * g1; dual_curvb[i] += wt * g12; dual_curvc[i] += wt * g2; } // Compute principal directions and curvatures at each dual vertex DiagonalizeCurvature(uu, vv, dual_curva[i], dual_curvb[i], dual_curvc[i], nn, ref fpDir1[i], ref fpDir2[i], ref fcurv1[i], ref fcurv2[i]); } System.Console.WriteLine("Done.\n"); }
// Compute the principle curvatures and directions for a specific face. public void ObtainPerFacePCurAndDirs() { // Compute curvature per-face int nf = mesh.FaceCount, nv = mesh.VertexCount; for (int i = 0; i < nf; i++) { // Edges int c = i * 3; int d0 = mesh.FaceIndex[c] * 3; int d1 = mesh.FaceIndex[c + 1] * 3; int d2 = mesh.FaceIndex[c + 2] * 3; Vector3d[] e = new Vector3d[3] { new Vector3d(mesh.VertexPos, d2) - new Vector3d(mesh.VertexPos, d1), new Vector3d(mesh.VertexPos, d0) - new Vector3d(mesh.VertexPos, d2), new Vector3d(mesh.VertexPos, d1) - new Vector3d(mesh.VertexPos, d0) }; Vector3d[] normals = new Vector3d[3] { new Vector3d(mesh.VertexNormal, d0), new Vector3d(mesh.VertexNormal, d1), new Vector3d(mesh.VertexNormal, d2) }; // N-T-B coordinate system per face Vector3d t = e[0].Normalize(); Vector3d n = e[0].Cross(e[1]); Vector3d b = n.Cross(t).Normalize(); // Estimate curvature based on variation of normals // along edges double[] m = new double[3] { 0, 0, 0 }; double[][] w = new double[3][]; for (int j = 0; j < 3; ++j) { w[j] = new double[3]; } for (int j = 0; j < 3; ++j) { double u = e[j].Dot(t); double v = e[j].Dot(b); w[0][0] += u * u; w[0][1] += u * v; w[2][2] += v * v; Vector3d dn = normals[(j + 2) % 3] - normals[(j + 1) % 3]; double dnu = dn.Dot(t); double dnv = dn.Dot(b); m[0] += dnu * u; m[1] += dnu * v + dnv * u; m[2] += dnv * v; } w[1][1] = w[0][0] + w[2][2]; w[1][2] = w[0][1]; // Least squares solution double[] diag = new double[3]; if (!ldltdc(w, diag, 3)) { System.Console.WriteLine("ldltdc failed!\n"); continue; } ldltsl(w, diag, m, ref m, 3); // compute the principle curvatures on face i. Vector3d fn = new Vector3d(mesh.FaceNormal, i * 3); DiagonalizeCurvature(t, b, m[0], m[1], m[2], fn, ref fpDir1[i], ref fpDir2[i], ref fcurv1[i], ref fcurv2[i]); } System.Console.WriteLine("Done.\n"); }
// Compute the principle curvatures and directions for a specific vertex // this is due to the sence that the vertex position may be changed on // the fly for some geometry filtering algorithms. public void ObtainCurvDirAt(int index, ref Vector3d e1, ref Vector3d e2, ref double k1, ref double k2) { // Initialize curvature tensor matrix elements. double aa = 0; double bb = 0; double cc = 0; Vector3d ni = new Vector3d(mesh.VertexNormal, index * 3); Vector3d pdir1 = localvu[index]; Vector3d pdir2 = localvv[index]; // Compute curvature per-face foreach (int f in mesh.AdjVF[index]) { // Edges int c = f * 3; int d0 = mesh.FaceIndex[c] * 3; int d1 = mesh.FaceIndex[c + 1] * 3; int d2 = mesh.FaceIndex[c + 2] * 3; Vector3d[] e = new Vector3d[3] { new Vector3d(mesh.VertexPos, d2) - new Vector3d(mesh.VertexPos, d1), new Vector3d(mesh.VertexPos, d0) - new Vector3d(mesh.VertexPos, d2), new Vector3d(mesh.VertexPos, d1) - new Vector3d(mesh.VertexPos, d0) }; Vector3d[] normals = new Vector3d[3] { new Vector3d(mesh.VertexNormal, d0), new Vector3d(mesh.VertexNormal, d1), new Vector3d(mesh.VertexNormal, d2) }; // N-T-B coordinate system per face Vector3d t = e[0].Normalize(); Vector3d n = e[0].Cross(e[1]); Vector3d b = n.Cross(t).Normalize(); // Estimate curvature based on variation of normals // along edges double[] m = new double[3] { 0, 0, 0 }; double[][] w = new double[3][]; for (int jj = 0; jj < 3; ++jj) { w[jj] = new double[3]; } for (int jj = 0; jj < 3; ++jj) { double u = e[jj].Dot(t); double v = e[jj].Dot(b); w[0][0] += u * u; w[0][1] += u * v; w[2][2] += v * v; Vector3d dn = normals[(jj + 2) % 3] - normals[(jj + 1) % 3]; double dnu = dn.Dot(t); double dnv = dn.Dot(b); m[0] += dnu * u; m[1] += dnu * v + dnv * u; m[2] += dnv * v; } w[1][1] = w[0][0] + w[2][2]; w[1][2] = w[0][1]; // Least squares solution double[] diag = new double[3]; if (!ldltdc(w, diag, 3)) { System.Console.WriteLine("ldltdc failed!\n"); continue; } ldltsl(w, diag, m, ref m, 3); // Push it back out to the vertices for (int jj = 0; jj < 3; jj++) { int pj = mesh.FaceIndex[c + jj]; if (pj != index) { continue; } double c1 = 0, c12 = 0, c2 = 0; proj_curv(t, b, m[0], m[1], m[2], pdir1, pdir2, ref c1, ref c12, ref c2); double wt = cornerareas[f][jj] / pointareas[pj]; aa += wt * c1; bb += wt * c12; cc += wt * c2; } } // Compute principal directions and curvatures at each vertex DiagonalizeCurvature(pdir1, pdir2, aa, bb, cc, ni, ref e1, ref e2, ref k1, ref k2 ); System.Console.WriteLine("Done.\n"); }