public void AreaGrowByFace() { List <TriMesh.Face> selectedFaces = new List <TriMesh.Face>(); for (int i = 0; i < this.mesh.Faces.Count; i++) { if (this.mesh.Faces[i].Traits.SelectedFlag > 0) { selectedFaces.Add(this.mesh.Faces[i]); } } for (int i = 0; i < selectedFaces.Count; i++) { foreach (TriMesh.Face face in selectedFaces[i].Faces) { if (face.Traits.SelectedFlag == 0) { double temp1 = 0, temp2 = 0, temp = 0, area = 0; temp1 = TriMeshUtil.ComputeAreaFace(face); temp2 = TriMeshUtil.ComputeAreaFace(selectedFaces[i]); temp = Math.Abs(temp1 - temp2); for (int j = 0; j < selectedFaces[i].FaceCount; j++) { area += TriMeshUtil.ComputeAreaFace(selectedFaces[i].GetFace(j)); } area = area / selectedFaces[i].FaceCount; if (temp < 0.916 * area) { face.Traits.SelectedFlag = selectedFaces[i].Traits.SelectedFlag; } } } } }
//vertex area public static double ComputeAreaOneRing(TriMesh.Vertex vertex) { double area = 0; foreach (TriMesh.Face face in vertex.Faces) { area += TriMeshUtil.ComputeAreaFace(face); } return(area); }
public SparseMatrixDouble BuildHodgeStar2Form(TriMesh mesh) { SparseMatrixDouble star2 = new SparseMatrixDouble(mesh.Faces.Count, mesh.Faces.Count); foreach (TriMesh.Face face in mesh.Faces) { star2[face.Index, face.Index] = 1 / TriMeshUtil.ComputeAreaFace(face); } Star2 = star2; return(star2); }
public SparseMatrixComplex cBuildHodgeStar2Form(TriMesh mesh) { SparseMatrixComplex star2 = new SparseMatrixComplex(mesh.Faces.Count, mesh.Faces.Count); foreach (TriMesh.Face face in mesh.Faces) { Complex value = new Complex(1 / TriMeshUtil.ComputeAreaFace(face), 0); star2[face.Index, face.Index] = value; } return(star2); }
//public static void PreserveVolume(TriMesh mesh) //{ // double oldVolume = TriMeshUtil.ComputeVolume(Mesh); // double newVolume = TriMeshUtil.ComputeVolume(Mesh); // for (int i = 0; i < n; i++) // { // Mesh.Vertices[i].Traits.Position.x *= Math.Pow(oldVolume / newVolume, 1 / 3); // Mesh.Vertices[i].Traits.Position.y *= Math.Pow(oldVolume / newVolume, 1 / 3); // Mesh.Vertices[i].Traits.Position.z *= Math.Pow(oldVolume / newVolume, 1 / 3); // } //} public static void PreModifiyGeometry(TriMesh mesh) { double ModifyVertexScale = 100; int n = mesh.Vertices.Count; for (int j = 0; j < 10; j++) { bool updated = false; TriMeshUtil.SetUpNormalVertex(mesh); for (int i = 0; i < n; i++) { // build matrix U Matrix3D U = new Matrix3D(); Vector3D u1 = mesh.Vertices[i].Traits.Position; foreach (TriMesh.Vertex neighbor in mesh.Vertices[i].Vertices) { Vector3D u21 = neighbor.Traits.Position - u1; U += u21.OuterCross(u21); } // Test for degenerated Matrix3D invU = U.InverseSVD(); if (Matrix3D.lastSVDIsFullRank == false) { Vector3D normal = mesh.Vertices[i].Traits.Normal; double area = 0; foreach (TriMesh.Face face in mesh.Vertices[i].Faces) { area += TriMeshUtil.ComputeAreaFace(face); } Vector3D newU1 = u1 + normal.Normalize() * Math.Sqrt(area / 3.0) / ModifyVertexScale; mesh.Vertices[i].Traits.Position = newU1; updated = true; } } if (!updated) { break; } } }
SparseMatrixQuaternion BuildEigenValueProblem(double[] rho) { int nV = mesh.Vertices.Count; SparseMatrixQuaternion E = new SparseMatrixQuaternion(nV, nV); int[] Indices = new int[3]; foreach (TriMesh.Face face in mesh.Faces) { double A = TriMeshUtil.ComputeAreaFace(face); double a = -1 / (4 * A); double b = rho[face.Index] / 6; double c = A * rho[face.Index] * rho[face.Index] / 9; Indices[0] = face.GetVertex(0).Index; Indices[1] = face.GetVertex(1).Index; Indices[2] = face.GetVertex(2).Index; Quaternion[] e = new Quaternion[3]; for (int i = 0; i < 3; i++) { Vector3D eV = mesh.Vertices[Indices[(i + 2) % 3]].Traits.Position - mesh.Vertices[Indices[(i + 1) % 3]].Traits.Position; e[i] = new Quaternion(eV, 0); } for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { Quaternion q = a * e[i] * e[j] + b * (e[j] - e[i]) + c; E[Indices[i], Indices[j]] += q; } } } return(E); }
public SparseMatrix BuildMatrixMass(TriMesh mesh) { int n = mesh.Vertices.Count; SparseMatrix L = new SparseMatrix(n, n); for (int i = 0; i < mesh.Edges.Count; i++) { double face0area = 0; double face1area = 0; if (mesh.Edges[i].Face0 != null) { face0area = TriMeshUtil.ComputeAreaFace(mesh.Edges[i].Face0); } if (mesh.Edges[i].Face1 != null) { face1area = TriMeshUtil.ComputeAreaFace(mesh.Edges[i].Face1); } L.AddValueTo(mesh.Edges[i].Vertex0.Index, mesh.Edges[i].Vertex1.Index, (face0area + face1area) / 12); L.AddValueTo(mesh.Edges[i].Vertex1.Index, mesh.Edges[i].Vertex0.Index, (face0area + face1area) / 12); } for (int i = 0; i < n; i++) { double sum = 0; foreach (SparseMatrix.Element e in L.Rows[i]) { sum += e.value; } L.AddValueTo(i, i, sum); } L.SortElement(); return(L); }
public static void RegionGrow(TriMesh mesh) { Vector3D[] normal = TriMeshUtil.ComputeNormalFace(mesh); double[] area = TriMeshUtil.ComputeAreaFace(mesh); SortedList <double, TriMesh.Face> sort = new SortedList <double, HalfEdgeMesh.Face>(); foreach (var center in mesh.Faces) { List <double> list = new List <double>(); double sum = 0; foreach (var round in center.Faces) { double l = (normal[round.Index] - normal[center.Index]).Length();// * area[round.Index]); sum += l; list.Add(l); } sum /= list.Count; double d = 0; foreach (var item in list) { d += Math.Pow(item - sum, 2); } d /= list.Count; if (sum < 1 && d < 0.1) { sort.Add(sum, center); } } Stack <TriMesh.Face> stack = new Stack <HalfEdgeMesh.Face>(); Dictionary <int, Cluster> dict = new Dictionary <int, Cluster>(); double k = 1; int flag = 0; do { if (stack.Count == 0) { bool run = false; if (flag > 100) { return; } for (int i = flag; i < sort.Count; i++) { TriMesh.Face next = sort.Values[i]; if (next.Traits.SelectedFlag == 0) { flag++; next.Traits.SelectedFlag = (byte)flag; stack.Push(next); dict[flag] = new Cluster(); dict[flag].Add(normal[sort.Values[i].Index]); run = true; break; } } if (!run) { return; } } TriMesh.Face center = stack.Pop(); foreach (var round in center.Faces) { if (round.Traits.SelectedFlag == 0 && (normal[round.Index] - normal[center.Index]).Length() < k && (normal[round.Index] - dict[flag].Center).Length() < k) { dict[flag].Add(normal[round.Index]); round.Traits.SelectedFlag = (byte)flag; stack.Push(round); } } } while (true); }
private void InitVertexInfo() { this.dataGridViewVertex.Rows.Clear(); foreach (TriMesh.Vertex vertex in Mesh.Vertices) { this.dataGridViewVertex.Rows.Add(vertex.Index, vertex.Traits.Position.x, vertex.Traits.Position.y, vertex.Traits.Position.z); } foreach (TriMesh.Face face in Mesh.Faces) { this.dataGridViewFace.Rows.Add(face.Index, face.GetVertex(0).Index, face.GetVertex(1).Index, face.GetVertex(2).Index, TriMeshUtil.ComputeAreaFace(face)); } foreach (TriMesh.Edge edge in Mesh.Edges) { string face0 = "null"; string face1 = "null"; if (edge.Face0 != null) { face0 = edge.Face0.Index.ToString(); } if (edge.Face1 != null) { face1 = edge.Face1.Index.ToString(); } this.dataGridViewEdge.Rows.Add(edge.Index, edge.Vertex0.Index, edge.Vertex1.Index, face0, face1, TriMeshUtil.ComputeEdgeLength(edge), TriMeshUtil.ComputeDihedralAngle(edge) / 3.14 * 180); } }
protected override double GetValue(HalfEdgeMesh.Face target) { return(TriMeshUtil.ComputeAreaFace(target)); }
public static void ComputeCornerArea(TriMesh mesh, out double[] CornerArea, out double[] PointArea) { CornerArea = new double[mesh.HalfEdges.Count]; PointArea = new double[mesh.Vertices.Count]; foreach (var face in mesh.Faces) { double area = TriMeshUtil.ComputeAreaFace(face); TriMesh.HalfEdge[] hf = new HalfEdgeMesh.HalfEdge[] { face.HalfEdge, face.HalfEdge.Next, face.HalfEdge.Previous }; int[] index = new int[3]; for (int i = 0; i < 3; i++) { index[i] = hf[i].Index; } Vector3D[] e = new Vector3D[3]; for (int i = 0; i < 3; i++) { e[i] = TriMeshUtil.GetHalfEdgeVector(hf[i].Previous); } double[] l2 = new double[3]; for (int i = 0; i < 3; i++) { l2[i] = e[i].LengthSquared; } double[] ew = new double[3]; for (int i = 0; i < 3; i++) { ew[i] = l2[i] * (l2[(i + 1) % 3] + l2[(i + 2) % 3] - l2[i]); } bool flag = false; for (int i = 0; i < 3; i++) { if (ew[i] < 0d) { int a = (i + 1) % 3; int b = (i + 2) % 3; CornerArea[index[a]] = -0.25d * l2[b] * area / e[i].Dot(e[b]); CornerArea[index[b]] = -0.25d * l2[a] * area / e[i].Dot(e[a]); CornerArea[index[i]] = area - CornerArea[index[a]] - CornerArea[index[b]]; flag = true; } } if (!flag) { double ewscale = 0.5d * area / (ew[0] + ew[1] + ew[2]); for (int i = 0; i < 3; i++) { CornerArea[index[i]] = ewscale * (ew[(i + 1) % 3] + ew[(i + 2) % 3]); } } for (int i = 0; i < 3; i++) { PointArea[hf[i].ToVertex.Index] += CornerArea[index[i]]; } } }