public static void SetUpVertexNormal(TriMesh mesh, EnumNormal type) { Vector3D[] normal = TriMeshUtil.ComputeNormalVertex(mesh, type); for (int i = 0; i < mesh.Vertices.Count; i++) { mesh.Vertices[i].Traits.Normal = normal[i]; } }
public void MappingGauss(TriMesh mesh) { for (int i = 0; i < mesh.Vertices.Count; i++) { Vector3D[] normals = TriMeshUtil.ComputeNormalVertex(mesh, EnumNormal.SphereInscribed); mesh.Vertices[i].Traits.Position = normals[i]; } TriMeshUtil.SetUpNormalVertex(mesh); }
public static PrincipalCurvature[] ComputePrincipleCurvatures(TriMesh mesh, double[] CornerArea, double[] PointArea) { Vector3D[] vertexNormal = TriMeshUtil.ComputeNormalVertex(mesh); // Add dynamic trait for principle curvature computation double[] curv = new double[mesh.Vertices.Count]; PrincipalCurvature[] pc = new PrincipalCurvature[mesh.Vertices.Count]; // Initialize a coordinate system for each vertex foreach (TriMesh.Vertex v in mesh.Vertices) { pc[v.Index] = new PrincipalCurvature(); // Vector that points from this vertex to an adjacent one pc[v.Index].maxDir = (v.HalfEdge.ToVertex.Traits.Position - v.Traits.Position).Cross(vertexNormal[v.Index]).Normalize(); // Get a vector orthogonal to this vector and the vertex normal pc[v.Index].minDir = vertexNormal[v.Index].Cross(pc[v.Index].maxDir); } TriMesh.HalfEdge[] fh = new TriMesh.HalfEdge[3]; TriMesh.Vertex[] fv = new TriMesh.Vertex[3]; Vector3D[] e = new Vector3D[3]; Vector3D t, b, dn, faceNormal; // Compute curvature for each face foreach (TriMesh.Face f in mesh.Faces) { // Get halfedges for this face fh[0] = f.HalfEdge; fh[1] = fh[0].Next; fh[2] = fh[1].Next; // Get vertices for this face fv[0] = fh[0].ToVertex; fv[1] = fh[1].ToVertex; fv[2] = fh[2].ToVertex; // Edge vectors e[0] = fv[2].Traits.Position - fv[1].Traits.Position; e[1] = fv[0].Traits.Position - fv[2].Traits.Position; e[2] = fv[1].Traits.Position - fv[0].Traits.Position; t = e[0]; t.Normalize(); faceNormal = e[0].Cross(e[1]); faceNormal.Normalize(); b = faceNormal.Cross(t); b.Normalize(); // Estimate curvature by variation of normals along edges double[] m = new double[3]; double[,] w = new double[3, 3]; for (int i = 0; i < 3; ++i) { double u = e[i].Dot(t); double v = e[i].Dot(b); w[0, 0] += u * u; w[0, 1] += u * v; w[2, 2] += v * v; dn = vertexNormal[fv[(i + 2) % 3].Index] - vertexNormal[fv[(i + 1) % 3].Index]; 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 (Transform.LdlTransposeDecomp(w, diag)) { Transform.LdlTransposeSolveInPlace(w, diag, m); // Adjust curvature for vertices of this face for (int i = 0; i < 3; ++i) { UV tb = new UV { U = t, V = b }; KUV mk = new KUV { U = m[0], UV = m[1], V = m[2] }; UV dst = new UV { U = pc[fv[i].Index].maxDir, V = pc[fv[i].Index].minDir }; KUV c = Transform.ProjectCurvature(tb, mk, dst); double weight = CornerArea[fh[i].Index] / PointArea[fv[i].Index]; pc[fv[i].Index].max += weight * c.U; curv[fv[i].Index] += weight * c.UV; pc[fv[i].Index].min += weight * c.V; } } } // Compute curvature for each vertex foreach (TriMesh.Vertex v in mesh.Vertices) { UV src = new UV { U = pc[v.Index].maxDir, V = pc[v.Index].minDir }; KUV srcK = new KUV { U = pc[v.Index].max, UV = curv[v.Index], V = pc[v.Index].min }; pc[v.Index] = Transform.DiagonalizeCurvature(src, srcK, vertexNormal[v.Index]); } return(pc); }