public static void Init(TriMesh mesh) { nv = mesh.Vertices.Count; TriMeshIO.WriteToObjFile(FileName, mesh); FromObjFile(mesh.FileName); }
public TriMesh AddSelectionVertex(TriMesh mesh, int index) { List<TriMesh> sel = new List<TriMesh>(); for(int i=0;i<mesh.Vertices.Count;i++) { if (mesh.Vertices[i].Traits.SelectedFlag == index) { TriMesh selV = TriMeshIO.FromObjFile(ConfigShape.Instance.VertexFile); for (int j = 0; j < selV.Vertices.Count;j++ ) { selV.Vertices[j].Traits.SelectedFlag =(byte)index; } TriMeshUtil.ScaleToUnit(selV, ConfigShape.Instance.Scale); TriMeshUtil.TransformationMove(selV, mesh.Vertices[i].Traits.Position); sel.Add(selV); } } TriMesh result= TriMeshUtil.Combine(sel); result.FileName = Path.GetFileNameWithoutExtension(mesh.FileName) + "-V-" + index.ToString(); TriMeshUtil.SetUpVertexNormal(result, EnumNormal.AreaWeight); return result; }
public MorseComplex(TriMesh mesh) { this.mesh = mesh; morseVertice = RetrieveMorseVertice(mesh); }
public static void GrowByFaceAngle(TriMesh mesh) { Queue<TriMesh.Face> queue = new Queue<HalfEdgeMesh.Face>(); Vector3D[] normal = TriMeshUtil.ComputeNormalFace(mesh); foreach (var face in mesh.Faces) { if (face.Traits.SelectedFlag != 0) { queue.Enqueue(face); } } double k = 0.449; while (queue.Count != 0) { TriMesh.Face center = queue.Dequeue(); foreach (var round in center.Faces) { if (round.Traits.SelectedFlag == 0) { if (normal[center.Index].Dot(normal[round.Index]) > k) { round.Traits.SelectedFlag = center.Traits.SelectedFlag; queue.Enqueue(round); } } } } }
public PrincipalCurvature ComputePrincipalCurvature(TriMesh.Vertex v) { Vector3D sum = Vector3D.Zero; Vector3D mid = v.Traits.Position; foreach (var hf in v.HalfEdges) { Vector3D buttom = hf.ToVertex.Traits.Position; Vector3D left = hf.Opposite.Next.ToVertex.Traits.Position; Vector3D right = hf.Next.ToVertex.Traits.Position; double cota = (mid - left).Dot(buttom - left) / (mid - left).Cross(buttom - left).Length(); double cotb = (mid - right).Dot(buttom - right) / (mid - right).Cross(buttom - right).Length(); sum += (cota + cotb) * (this.Normal[v.Index] - this.Normal[hf.ToVertex.Index]); } double mixedArea = TriMeshUtil.ComputeAreaMixed(v); Vector3D laplace = sum / mixedArea / 2d; double square = -laplace.Dot(this.Normal[v.Index]); double k = this.K[v.Index].Length(); double delta = -k * k + 2d * square; if (delta < 0d) { delta = 0d; } PrincipalCurvature pc = new PrincipalCurvature(); pc.max = (k + Math.Pow(delta, 0.5)) / 2d; pc.min = (k - Math.Pow(delta, 0.5)) / 2d; return pc; }
private Vector3D ComputeModifiedButterflyTraits(double tension, TriMesh.Edge edge) { List<TriMesh.HalfEdge> left = new List<HalfEdgeMesh.HalfEdge>(); List<TriMesh.HalfEdge> right = new List<HalfEdgeMesh.HalfEdge>(); edge.Vertex0.HalfEdge = edge.HalfEdge1; edge.Vertex1.HalfEdge = edge.HalfEdge0; foreach (var hf in edge.Vertex0.HalfEdges) { left.Add(hf); } foreach (var hf in edge.Vertex1.HalfEdges) { right.Add(hf); } if (!edge.OnBoundary) { if (left.Count == 6 && right.Count == 6) { double[] weight = new double[6]; weight[0] = (1f / 2f) - (double)tension; weight[1] = weight[5] = (1f / 8f) + 2 * (double)tension; weight[2] = weight[4] = -(1f / 16f) - (double)tension; weight[3] = (double)tension; Vector3D sum = Vector3D.Zero; for (int i = 0; i < 6; i++) { sum += weight[i] * left[i].ToVertex.Traits.Position; sum += weight[i] * right[i].ToVertex.Traits.Position; } double weightSum = weight[0] + 2 * weight[1] + 2 * weight[2] + weight[3]; return sum / weightSum / 2; } else if (left.Count == 6) { return ComputeSingularPoint(right); } else if (right.Count == 6) { return ComputeSingularPoint(left); } else { return (ComputeSingularPoint(left) + ComputeSingularPoint(right)) / 2; } } else { double[] weight = new double[]{9f / 16f,-1f / 16f}; Vector3D sum = Vector3D.Zero; for (int i = 0; i < 2; i++) { sum += weight[i] * left[i].ToVertex.Traits.Position; sum += weight[i] * right[i].ToVertex.Traits.Position; } return sum; } }
public void PlaneCut(TriMesh.HalfEdge above, Vector3D normal, double maxAngle) { Plane plane = new Plane(above.Next.ToVertex.Traits.Position, normal); Nullable<Vector3D> point = this.Intersect(plane, above.Edge); double angle = this.GetAngle(plane, above); while (point != null && angle > maxAngle) { TriMesh.Vertex left = above.FromVertex; TriMesh.Vertex right = above.ToVertex; TriMesh.Vertex buttom = above.Opposite.Next.ToVertex; this.Cut(above, point.Value); if (above.Opposite.OnBoundary) { break; } TriMesh.HalfEdge[] below = new[] { left.FindHalfedgeTo(buttom), buttom.FindHalfedgeTo(right) }; foreach (var hf in below) { point = this.Intersect(plane, hf.Edge); if (point != null) { angle = this.GetAngle(plane, hf); above = hf; break; } } } }
private ErrorPair GetErrorPair(TriMesh.Face face) { Matrix4D m1 = this.GetVolumeMatrix(face); if (m1[1] != m1[4] || m1[2] != m1[8] || m1[6] != m1[9] || m1[3] != m1[12] || m1[7] != m1[13] || m1[11] != m1[14] ) throw new Exception("Matrix m1 is not symmetric"); Matrix4D m2 = Matrix4D.ZeroMatrix; for (int i = 0; i <= 11; i++) { m2[i] = m1[i]; } m2[12] = 0; m2[13] = 0; m2[14] = 0; m2[15] = 1; Vector3D newPos = Vector3D.Zero; double det = Util.Solve(ref m2, ref newPos); if (det == 0) { newPos = TriMeshUtil.GetMidPoint(face); } double error = this.GetError(m1, newPos); return new ErrorPair() { Pos = newPos, Error = error }; }
public static TriMesh Clone(TriMesh mesh) { TriMesh newMesh = new TriMesh(); for (int i = 0; i < mesh.Vertices.Count; i++) { VertexTraits traits = new VertexTraits(mesh.Vertices[i].Traits.Position.x, mesh.Vertices[i].Traits.Position.y, mesh.Vertices[i].Traits.Position.z); newMesh.Vertices.Add(traits); } TriMesh.Vertex[] faceVetices = new TriMesh.Vertex[3]; for (int i = 0; i < mesh.Faces.Count; i++) { int faceVertexIndex1 = mesh.Faces[i].GetVertex(0).Index; int faceVertexIndex2 = mesh.Faces[i].GetVertex(1).Index; int faceVertexIndex3 = mesh.Faces[i].GetVertex(2).Index; faceVetices[0] = newMesh.Vertices[faceVertexIndex1]; faceVetices[1] = newMesh.Vertices[faceVertexIndex2]; faceVetices[2] = newMesh.Vertices[faceVertexIndex3]; newMesh.Faces.AddTriangles(faceVetices); } newMesh.TrimExcess(); return newMesh; }
public static void KMean(TriMesh mesh) { Dictionary<int, Cluster> dict = new Dictionary<int, Cluster>(); Queue<TriMesh.Face> queue = new Queue<HalfEdgeMesh.Face>(); foreach (var face in mesh.Faces) { if (face.Traits.SelectedFlag != 0) { dict[face.Traits.SelectedFlag] = new Cluster(); dict[face.Traits.SelectedFlag].Add(TriMeshUtil.GetMidPoint(face)); queue.Enqueue(face); } } while (queue.Count != 0) { TriMesh.Face center = queue.Dequeue(); foreach (var round in center.Faces) { if (round.Traits.SelectedFlag == 0) { int index = GetNearest(round, dict); dict[index].Add(TriMeshUtil.GetMidPoint(round)); round.Traits.SelectedFlag = (byte)index; queue.Enqueue(round); } } } }
public static void InverseFace(TriMesh mesh) { List<TriMesh.Vertex[]> faces = new List<HalfEdgeMesh.Vertex[]>(); foreach (TriMesh.Face face in mesh.Faces) { TriMesh.HalfEdge hf = face.HalfEdge; TriMesh.Vertex[] arr = new TriMesh.Vertex[]{ hf.Next.ToVertex, hf.ToVertex, hf.FromVertex }; faces.Add(arr); } TriMesh.Vertex[] vertices = new TriMesh.Vertex[mesh.Vertices.Count]; for (int i = 0; i < mesh.Vertices.Count; i++) { vertices[i] = mesh.Vertices[i]; vertices[i].HalfEdge = null; } mesh.Clear(); foreach (var v in vertices) { mesh.AppendToVertexList(v); } foreach (var face in faces) { mesh.Faces.AddTriangles(face); } }
public static void Move(TriMesh mesh, Vector3D vec) { foreach (var v in mesh.Vertices) { v.Traits.Position += vec; } }
public override void MouseMove(Vector2D mouseMovePos, EnumMouseButton button) { base.MouseMove(mouseMovePos,button); switch (ParameterCurve.Instance.currentCurve) { case EnumCurveComplex.FourPointBezier : curve = ParameterCurve.Instance.CreateFourBezierCurve(mesh); break; case EnumCurveComplex.ThreePointBezier: curve = ParameterCurve.Instance.CreateThreeBezierCurve(mesh); break; case EnumCurveComplex.NPointBezier: curve = ParameterCurve.Instance.CreateNBezierCurve(mesh); break; case EnumCurveComplex.FourPointBSpline: curve = ParameterCurve.Instance.CreateFourPointBSplineCurve(mesh); break; case EnumCurveComplex.NPointBSpline: curve = ParameterCurve.Instance.CreateNBsplineCurve(mesh); break; case EnumCurveComplex.NURBS: curve = ParameterCurve.Instance.CreateNURBS(mesh); break; case EnumCurveComplex.NURBSCicle: curve = ParameterCurve.Instance.CreateNURBSCicle(mesh); break; case EnumCurveComplex.NURBSEllipse: curve = ParameterCurve.Instance.CreateNURBSEllipse(mesh); break; } }
/// <summary> /// Loads an OBJ file from a stream. /// </summary> /// <param name="stream">A stream with OBJ file data.</param> private static TriMesh LoadObjStream(Stream stream) { TriMesh mesh = new TriMesh(); mesh.Traits.HasFaceVertexNormals = true; mesh.Traits.HasTextureCoordinates = true; StreamReader sr = new StreamReader(stream); ObjFileProcessorState state = new ObjFileProcessorState(); string line; while ((line = sr.ReadLine()) != null) { ProcessObjLine(mesh, line, state); } if (state.VertexTextureCoords.Count == mesh.Vertices.Count) { for (int i = 0; i < mesh.Vertices.Count; i++) { mesh.Vertices[i].Traits.UV = state.VertexTextureCoords[i]; } } mesh.TrimExcess(); return mesh; }
private static void DrawMultiTextureUV(TriMesh mesh) { GL.Begin(BeginMode.Triangles); for (int i = 0; i < mesh.Faces.Count; i++) { foreach (TriMesh.Vertex vertex in mesh.Faces[i].Vertices) { GL.Normal3(vertex.Traits.Normal.x, vertex.Traits.Normal.y, vertex.Traits.Normal.z); GL.MultiTexCoord2(TextureUnit.Texture0, vertex.Traits.UV[0], vertex.Traits.UV[1]); GL.MultiTexCoord2(TextureUnit.Texture1, vertex.Traits.UV[0], vertex.Traits.UV[1]); GL.Vertex3(vertex.Traits.Position.x, vertex.Traits.Position.y, vertex.Traits.Position.z); } } GL.End(); }
private TriMesh ChangeTopologyInit(TriMesh sourceMesh) { TriMesh mesh = new TriMesh(); vMap = new HalfEdgeMesh.Vertex[sourceMesh.Vertices.Count]; faceMap = new HalfEdgeMesh.Vertex[sourceMesh.Faces.Count]; foreach (var face in sourceMesh.Faces) { faceMap[face.Index] = mesh.Vertices.Add( new VertexTraits(TriMeshUtil.GetMidPoint(face))); } foreach (var v in sourceMesh.Vertices) { vMap[v.Index] = mesh.Vertices.Add(new VertexTraits(v.Traits.Position)); foreach (var hf in v.HalfEdges) { if (hf.Face != null && hf.Opposite.Face != null) { mesh.Faces.AddTriangles(faceMap[hf.Face.Index], vMap[v.Index], faceMap[hf.Opposite.Face.Index]); } } } foreach (var hf in sourceMesh.HalfEdges) { if (hf.Face == null) { mesh.Faces.AddTriangles(vMap[hf.ToVertex.Index], vMap[hf.FromVertex.Index], faceMap[hf.Opposite.Face.Index]); } } return mesh; }
public void UpdateHodgeStar(TriMesh mesh) { foreach (TriMesh.Edge edge in mesh.Edges) { double sum = 0; TriMesh.HalfEdge currentHe = edge.HalfEdge0; do { Vector3D a = currentHe.FromVertex.Traits.Position; Vector3D b = currentHe.Next.FromVertex.Traits.Position; Vector3D c = currentHe.Next.Next.FromVertex.Traits.Position; Vector3D u = a - c; Vector3D v = b - c; double cotTheta = (u.Dot(v)) / u.Cross(v).Length(); sum += 0.5 * cotTheta; } while (currentHe != edge.HalfEdge0); EdgeHodgeStar1[edge.Index] = Math.Max(sum, 0); } }
public void DrawColor(TriMesh mesh) { GL.Enable(EnableCap.ColorMaterial); GL.ShadeModel(ShadingModel.Smooth); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); GL.Enable(EnableCap.Normalize); GL.Begin(BeginMode.Triangles); for (int i = 0; i < mesh.Faces.Count; i++) { foreach (TriMesh.Vertex vertex in mesh.Faces[i].Vertices) { GL.Color3(vertex.Traits.Color.R, vertex.Traits.Color.G, vertex.Traits.Color.B); GL.Normal3(vertex.Traits.Normal.x, vertex.Traits.Normal.y, vertex.Traits.Normal.z); GL.Vertex3(vertex.Traits.Position.x, vertex.Traits.Position.y, vertex.Traits.Position.z); } } GL.End(); }
public double[] ComputeFunction(TriMesh mesh) { SparseMatrix sparse = BuildMatrixA(mesh); double[] rightB = BuildRightB(mesh); double[] unknownX = LinearSystem.Instance.SolveSystem(ref sparse, ref rightB, mesh.FileName); return unknownX; }
public void DrawColorVis(TriMesh mesh) { if (GlobalData.Instance.ColorVis == null) return; if (GlobalData.Instance.ColorVis.Length != mesh.Vertices.Count) return; GL.ShadeModel(ShadingModel.Smooth); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); GL.Enable(EnableCap.Normalize); GL.Begin(BeginMode.Triangles); for (int i = 0; i < mesh.Faces.Count; i++) { foreach (TriMesh.Vertex vertex in mesh.Faces[i].Vertices) { float alpha = (float)GlobalData.Instance.ColorVis[vertex.Index]; GL.Color4(alpha, alpha, alpha, alpha); GL.Normal3(vertex.Traits.Normal.x, vertex.Traits.Normal.y, vertex.Traits.Normal.z); GL.Vertex3(vertex.Traits.Position.x, vertex.Traits.Position.y, vertex.Traits.Position.z); } } GL.End(); }
public TriMesh CreateFourPointBSplineCurve(TriMesh mesh) { TriMesh FourPointBSplineCurve = new TriMesh(); double x = 0; double y = 0; double z = 0; for (int t = 0; t <= VerticesNum; t++) { double tt = (double)t / (double)VerticesNum; x = (double)1 / 6 * ((-Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) - 3 * tt + 1)) * mesh.Vertices[0].Traits.Position.x + (double)1 / 6 * ((3 * Math.Pow(tt, 3) - 6 * Math.Pow(tt, 2) + 4)) * mesh.Vertices[1].Traits.Position.x + (double)1 / 6 * ((-3 * Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) + 3 * tt + 1)) * mesh.Vertices[2].Traits.Position.x + (double)1 / 6 * Math.Pow(tt, 3) * mesh.Vertices[3].Traits.Position.x; y = (double)1 / 6 * ((-Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) - 3 * tt + 1)) * mesh.Vertices[0].Traits.Position.y + (double)1 / 6 * ((3 * Math.Pow(tt, 3) - 6 * Math.Pow(tt, 2) + 4)) * mesh.Vertices[1].Traits.Position.y + (double)1 / 6 * ((-3 * Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) + 3 * tt + 1)) * mesh.Vertices[2].Traits.Position.y + (double)1 / 6 * Math.Pow(tt, 3) * mesh.Vertices[3].Traits.Position.y; FourPointBSplineCurve.Vertices.Add(new VertexTraits(x, y, z)); } return FourPointBSplineCurve; }
public static void GrowByVertexArea(TriMesh mesh) { Queue<TriMesh.Vertex> queue = new Queue<HalfEdgeMesh.Vertex>(); double[] avgArea = new double[mesh.Vertices.Count]; foreach (var v in mesh.Vertices) { avgArea[v.Index] = TriMeshUtil.ComputeAreaOneRing(v); if (v.Traits.SelectedFlag != 0) { queue.Enqueue(v); } } double k = 0.896; while (queue.Count != 0) { TriMesh.Vertex center = queue.Dequeue(); foreach (var round in center.Vertices) { if (round.Traits.SelectedFlag == 0) { if (Math.Abs(avgArea[center.Index] - avgArea[round.Index]) < k * avgArea[center.Index]) { round.Traits.SelectedFlag = center.Traits.SelectedFlag; queue.Enqueue(round); } } } } }
public void DrawConnectionVector(TriMesh m) { for (int i = 0; i < m.Faces.Count; i++) { GL.Color3(0.0f, 0.0f, 1.0f); Vector3D faceCenter = new Vector3D(); //Get Face center point faceCenter.x = (m.Faces[i].GetVertex(0).Traits.Position.x + m.Faces[i].GetVertex(1).Traits.Position.x + m.Faces[i].GetVertex(2).Traits.Position.x) / 3; faceCenter.y = (m.Faces[i].GetVertex(0).Traits.Position.y + m.Faces[i].GetVertex(1).Traits.Position.y + m.Faces[i].GetVertex(2).Traits.Position.y) / 3; faceCenter.z = (m.Faces[i].GetVertex(0).Traits.Position.z + m.Faces[i].GetVertex(1).Traits.Position.z + m.Faces[i].GetVertex(2).Traits.Position.z) / 3; //Face Normal Vector // Vector3D vector = m.Faces[i].faceVector.Normalize(); GL.Begin(BeginMode.Lines); GL.Color3(Color.Black); GL.Vertex3(faceCenter.x, faceCenter.y, faceCenter.z); // GL.Vertex3(faceCenter.x - 0.2 * vector.x, faceCenter.y - 0.2 * vector.y, faceCenter.z - 0.2 * vector.z); GL.End(); } }
public static TriMesh.Vertex MergeEdge(TriMesh.Edge edge, Vector3D position) { TriMesh mesh = (TriMesh)edge.Mesh; TriMesh.Vertex v0 = edge.Vertex0; TriMesh.Vertex v1 = edge.Vertex1; TriMesh.HalfEdge hf0 = edge.HalfEdge0; TriMesh.HalfEdge hf1 = edge.HalfEdge1; v0.Traits.Position = position; foreach (var item in v1.HalfEdges) { //if (item.ToVertex != v0) { item.Opposite.ToVertex = v0; } } MergeOneSide(hf0); MergeOneSide(hf1); mesh.RemoveVertex(v1); mesh.RemoveEdge(edge); v1.HalfEdge = null; edge.HalfEdge0 = null; return v0; }
public static Vector3D[] ComputeNormalVertex(TriMesh mesh, EnumNormal type) { if (type == null) { type=EnumNormal.UniformWeight ; } Vector3D[] normal = null; switch (type) { case EnumNormal.AreaWeight: normal= ComputeNormalAreaWeight(mesh); break; case EnumNormal.SphereInscribed: normal = ComputeNormalSphereInscribed(mesh); break; case EnumNormal.TipAngleWeight: normal = ComputeNormalTipAngleWeight(mesh); break; case EnumNormal.UniformWeight: normal = ComputeNormalUniformWeight(mesh); break; } return normal; }
public TriMesh CreateNBsplineCurve(TriMesh mesh) { TriMesh BezierCurve = new TriMesh(); double x = 0; double y = 0; double z = 0; for (int i = 0; i < Point - 2; i++) { for (int t = 0; t <= VerticesNum; t++) { double tt = (double)t / (double)VerticesNum; //x = (double)1 / 6 * ((-Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) - 3 * tt + 1)) * mesh.Vertices[0].Traits.Position.x // + (double)1 / 6 * ((3 * Math.Pow(tt, 3) - 6 * Math.Pow(tt, 2) + 4)) * mesh.Vertices[1].Traits.Position.x // + (double)1 / 6 * ((-3 * Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) + 3 * tt + 1)) * mesh.Vertices[2].Traits.Position.x // + (double)1 / 6 * Math.Pow(tt, 3) * mesh.Vertices[3].Traits.Position.x; //y = (double)1 / 6 * ((-Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) - 3 * tt + 1)) * mesh.Vertices[0].Traits.Position.y // + (double)1 / 6 * ((3 * Math.Pow(tt, 3) - 6 * Math.Pow(tt, 2) + 4)) * mesh.Vertices[1].Traits.Position.y // + (double)1 / 6 * ((-3 * Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) + 3 * tt + 1)) * mesh.Vertices[2].Traits.Position.y // + (double)1 / 6 * Math.Pow(tt, 3) * mesh.Vertices[3].Traits.Position.y; x = (double)1 / 6 * ((-Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) - 3 * tt + 1)) * mesh.Vertices[i].Traits.Position.x + (double)1 / 6 * ((3 * Math.Pow(tt, 3) - 6 * Math.Pow(tt, 2) + 4)) * mesh.Vertices[i + 1].Traits.Position.x + (double)1 / 6 * ((-3 * Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) + 3 * tt + 1)) * mesh.Vertices[i + 2].Traits.Position.x + (double)1 / 6 * Math.Pow(tt, 3) * mesh.Vertices[i + 3].Traits.Position.x; y = (double)1 / 6 * ((-Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) - 3 * tt + 1)) * mesh.Vertices[i].Traits.Position.y + (double)1 / 6 * ((3 * Math.Pow(tt, 3) - 6 * Math.Pow(tt, 2) + 4)) * mesh.Vertices[i + 1].Traits.Position.y + (double)1 / 6 * ((-3 * Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) + 3 * tt + 1)) * mesh.Vertices[i + 2].Traits.Position.y + (double)1 / 6 * Math.Pow(tt, 3) * mesh.Vertices[i + 3].Traits.Position.y; BezierCurve.Vertices.Add(new VertexTraits(x, y, z)); x = 0; y = 0; } } return BezierCurve; }
public static void SmoothTaubin(TriMesh Mesh) { double weight = ConfigMeshOP.Instance.SmoothTaubinLamda; int iterative = ConfigMeshOP.Instance.SmoothTaubinIterative; bool cot=ConfigMeshOP.Instance.SmoothTaubinCot; int n = Mesh.Vertices.Count; double[][] lap =null; for (int j = 0; j < iterative; j++) { if (cot) { lap = LaplaceManager.Instance.ComputeLaplacianCotNormalize(Mesh); } else { lap = LaplaceManager.Instance.ComputeLaplacianUniform(Mesh); } for (int i = 0; i < n; i++) { Mesh.Vertices[i].Traits.Position.x += lap[0][i] * weight; Mesh.Vertices[i].Traits.Position.y += lap[1][i] * weight; Mesh.Vertices[i].Traits.Position.z += lap[2][i] * weight; } } }
public Dictionary<TriMesh.Vertex, int> GetVertices(TriMesh mesh) { Dictionary<TriMesh.Vertex, int> vertexDict = new Dictionary<HalfEdgeMesh.Vertex, int>(); foreach (var v in mesh.Vertices) { int count = 0; foreach (var edge in v.Edges) { if (edge.Traits.SelectedFlag != 0) { count++; } } if (count > 2) { vertexDict[v] = 2; } } foreach (var v in morseVertice.MinList) { vertexDict[v] = 0; } foreach (var v in morseVertice.SaddleList) { if (v.Traits.SelectedFlag > 3) { vertexDict[v] = 1; } } return vertexDict; }
public SparseMatrixComplex cBuildExteriorDerivative1Form(TriMesh mesh) { SparseMatrixComplex d1 = new SparseMatrixComplex(mesh.Faces.Count, mesh.Edges.Count); foreach (TriMesh.Face face in mesh.Faces) { foreach (TriMesh.HalfEdge hf in face.Halfedges) { double s = 0; if (hf.Edge.HalfEdge0 == hf) { s = -1; } else { s = 1; } d1[face.Index, hf.Edge.Index] = new Complex(s, 0); } } return d1; }
public static void Split(TriMesh mesh, EdgeContext ctx) { TriMesh.Vertex left = null; TriMesh.Vertex top = null; TriMesh.Vertex bottom = null; foreach (var v in mesh.Vertices) { if (v.Index == ctx.Left) { left = v; } else if (v.Index == ctx.Top) { top = v; } else if (v.Index == ctx.Bottom) { bottom = v; } } TriMesh.Vertex right = TriMeshModify.VertexSplit(left, top, bottom, ctx.LeftPos, ctx.RightPos); TriMesh.HalfEdge hf = left.FindHalfedgeTo(right); right.Index = ctx.Right; hf.Next.ToVertex.Index = ctx.Top; hf.Opposite.Next.ToVertex.Index = ctx.Bottom; }
public static List <List <TriMesh.Face> > RetrieveFacePatchBySelectedEdge(TriMesh mesh) { bool[] faceFlag = new bool[mesh.Faces.Count]; bool[] hfFlag = new bool[mesh.HalfEdges.Count]; List <List <TriMesh.Face> > all = new List <List <TriMesh.Face> >(); foreach (TriMesh.HalfEdge hf in mesh.HalfEdges) { if (!hfFlag[hf.Index]) { List <TriMesh.Face> list = new List <HalfEdgeMesh.Face>(); Stack <TriMesh.HalfEdge> stack = new Stack <HalfEdgeMesh.HalfEdge>(); stack.Push(hf); while (stack.Count != 0) { TriMesh.HalfEdge cur = stack.Pop(); hfFlag[cur.Index] = true; if (!faceFlag[cur.Face.Index]) { list.Add(cur.Face); faceFlag[cur.Face.Index] = true; } TriMesh.HalfEdge[] arr = new HalfEdgeMesh.HalfEdge[] { cur.Opposite, cur.Next, cur.Previous }; foreach (var item in arr) { if (!hfFlag[item.Index] && item.Face != null && item.Edge.Traits.SelectedFlag == 0) { stack.Push(item); } } } if (list.Count != 0) { all.Add(list); } } } return(all); }
// Long_short public TriMesh CreateLong() { float a = 5f, b = 7f, c = 2.2f; TriMesh long_short = new TriMesh(); for (int t = 0; t < VerticesNum; t++) { int theta = 360 * t * 10; double x = (a - b) * Math.Cos(theta) + c * Math.Cos((a / b - 1) * theta); double y = (a - b) * Math.Sin(theta) - c * Math.Sin((a / b - 1) * theta); long_short.Vertices.Add(new VertexTraits(x, y, 0)); } return(long_short); }
public TriMesh CreateJk() { TriMesh Jk = new TriMesh(); double r, pi; double ang; pi = 3.14; r = 20; for (int t = 0; t < VerticesNum; t++) { ang = 360 * t; Jk.Vertices.Add(new VertexTraits(r * Math.Cos(ang) + 2 * pi * r * t * Math.Sin(ang), r * Math.Sin(ang) - 2 * pi * r * t * Math.Cos(ang), 0)); } return(Jk); }
//epicycloid 外摆线 public TriMesh CreateEpicycloid( ) { float a = 5, b = 8; TriMesh epicycloid = new TriMesh(); for (int t = 0; t < VerticesNum; t++) { int theta = t * 720 * 5; double x = (a + b) * Math.Cos(theta) - b * Math.Cos((a / b + 1) * theta); double y = y = (a + b) * Math.Sin(theta) - b * Math.Sin((a / b + 1) * theta); epicycloid.Vertices.Add(new VertexTraits(x, y, 0)); } return(epicycloid); }
public SparseMatrix BuildAdjacentMatrixFV(TriMesh mesh) { SparseMatrix m = new SparseMatrix(mesh.Faces.Count, mesh.Vertices.Count); foreach (var face in mesh.Faces) { foreach (var v in face.Vertices) { m.AddElementIfNotExist(face.Index, v.Index, 1.0); } } m.SortElement(); return(m); }
//private bool IsContainVertex(TriMesh.Face face, int vIndex) //{ // int v1 = face.GetVertex(0).Index; // int v2 = face.GetVertex(1).Index; // int v3 = face.GetVertex(2).Index; // return (v1 == vIndex) || (v2 == vIndex) || (v3 == vIndex); //} public SparseMatrix BuildAdjacentMatrixVE(TriMesh mesh) { SparseMatrix m = new SparseMatrix(mesh.Vertices.Count, mesh.Edges.Count); foreach (var v in mesh.Vertices) { foreach (var edge in v.Edges) { m.AddElementIfNotExist(v.Index, edge.Index, 1.0); } } m.SortElement(); return(m); }
public TriMesh CreateNBezierControlPoint() { TriMesh cPoint = new TriMesh(); Random r = new Random(); cPoint.Vertices.Add(new VertexTraits(0, 0, 0)); for (int t = 0; t < controlPoint; t++) { int x = r.Next(1, 10); cPoint.Vertices.Add(new VertexTraits(t * 0.1 + x * 0.01, x * 0.1, 0)); } return(cPoint); }
public SparseMatrix BuildAdjacentMatrixFF(TriMesh mesh) { SparseMatrix m = new SparseMatrix(mesh.Faces.Count, mesh.Faces.Count); foreach (var center in mesh.Faces) { foreach (var round in center.Faces) { m.AddElementIfNotExist(center.Index, round.Index, 1.0); } } m.SortElement(); return(m); }
static TriMesh CreateSphere() { TriMesh sphere = TriMeshIO.ReadFile("sphere.obj"); TriMeshUtil.ScaleToUnit(sphere, 0.4); TriMeshUtil.MoveToCenter(sphere); Vector3D move = new Vector3D(-0.2, -0.1, -0.1); foreach (var v in sphere.Vertices) { v.Traits.Position -= move; } TriMeshUtil.SetUpNormalVertex(sphere); return(sphere); }
static TriMesh CreateCube() { TriMesh cube = TriMeshIO.ReadFile("cube.obj"); TriMeshUtil.ScaleToUnit(cube, 0.2); TriMeshUtil.MoveToCenter(cube); Vector3D move = new Vector3D(0.2, 0.1, -0.3); foreach (var v in cube.Vertices) { v.Traits.Position -= move; } TriMeshUtil.SetUpNormalVertex(cube); return(cube); }
public SparseMatrix BuildLaplaceCotArea(TriMesh mesh) { double[] areas = TriMeshUtil.ComputeAreaMixed(mesh); SparseMatrix cot = BuildLaplaceCot(mesh); int n = mesh.Vertices.Count; for (int i = 0; i < n; i++) { foreach (SparseMatrix.Element e in cot.Rows[i]) { e.value = e.value * (1 / areas[i]); } } return(cot); }
public SparseMatrix BuildMatrixCombinatorialGraph(TriMesh mesh) { int n = mesh.Vertices.Count; SparseMatrix W = BuildAdjacentMatrixVV(mesh); SparseMatrix D = new SparseMatrix(n, n); for (int i = 0; i < n; i++) { double sum = W.Rows[i].Count; D.AddValueTo(i, i, sum); } SparseMatrix K = W.Minus(D); return(K); }
public static void SetUpCurvature(TriMesh mesh) { PrincipalCurvature[] PrincipalCurv = TriMeshUtil.ComputePricipalCurvature(mesh); foreach (var v in mesh.Vertices) { PrincipalCurvature pc = PrincipalCurv[v.Index]; v.Traits.MaxCurvature = pc.max; v.Traits.MaxCurvatureDirection = pc.maxDir; v.Traits.MinCurvature = pc.min; v.Traits.MinCurvatureDirection = pc.minDir; v.Traits.MeanCurvature = (pc.max + pc.min) / 2d; v.Traits.GaussianCurvature = pc.max * pc.min; } }
public static void AddNoise(TriMesh Mesh, double threshold) { Random random = new Random(); double avglength = TriMeshUtil.ComputeEdgeAvgLength(Mesh); threshold *= avglength; foreach (TriMesh.Vertex item in Mesh.Vertices) { Vector3D normal = item.Traits.Normal.Normalize(); double scale = threshold * (random.NextDouble() - 0.5f); item.Traits.Position.x += normal.x * scale; item.Traits.Position.y += normal.y * scale; item.Traits.Position.z += normal.z * scale; } }
public static List <TriMesh.Vertex> RetrieveBoundarySingle(TriMesh mesh) { List <TriMesh.Vertex> boundary = new List <TriMesh.Vertex>(); foreach (TriMesh.Vertex vertex in mesh.Vertices) { if (vertex.OnBoundary) { boundary.Add(vertex); break; } } RetrieveBoundarySingle(boundary); return(boundary); }
public TriMesh CreateMeshSin() { TriMesh circle = new TriMesh(); for (int i = 0; i <= VerticesNum; i++) { double ang1 = i * 2 * pi; double ang2 = i * 2 * pi * 20; double x = ang1 * 2 * pi / 360; double y = Math.Sin(ang1) * 5 + Math.Cos(ang2); double z = Math.Sin(ang2); circle.Vertices.Add(new VertexTraits(x, y, z)); } return(circle); }
public static void RemoveTwoRingOfVertex(TriMesh.Vertex vertex) { TriMesh mesh = (TriMesh)vertex.Mesh; List <TriMesh.Vertex> neighbors = new List <TriMesh.Vertex>(); foreach (TriMesh.Vertex neighbor in vertex.Vertices) { neighbors.Add(neighbor); } RemoveVertex(vertex); for (int i = 0; i < neighbors.Count; i++) { RemoveVertex(neighbors[i]); } }
public SparseMatrixComplex cBuildExteriorDerivative0Form(TriMesh mesh) { SparseMatrixComplex d0 = new SparseMatrixComplex(mesh.Edges.Count, mesh.Vertices.Count); foreach (TriMesh.Edge edge in mesh.Edges) { int ci = edge.HalfEdge0.FromVertex.Index; int cj = edge.HalfEdge0.ToVertex.Index; d0[edge.Index, ci] = new Complex(1, 0); d0[edge.Index, cj] = new Complex(-1, 0); } return(d0); }
public void DrawAccum(TriMesh mesh, Vector3D move) { GL.Begin(BeginMode.Triangles); foreach (var face in mesh.Faces) { foreach (var v in face.Vertices) { GL.Normal3(v.Traits.Normal.ToArray()); GL.Vertex3((v.Traits.Position + move).ToArray()); } } GL.End(); }
public string BuildMorseTheory(TriMesh mesh, double[] function) { morseVertice = ComputeMorseVertice(mesh, function); string morseinfo = " Vertices - Edges + Faces= "; morseinfo += TriMeshUtil.CountEulerCharacteristic(mesh) + "\r\n"; morseinfo += " Saddle: " + morseVertice.SaddleList.Count + "\r\n"; morseinfo += " Maxima: " + morseVertice.MaxList.Count + "\r\n"; morseinfo += " Minima: " + morseVertice.MinList.Count + "\r\n"; morseinfo += " Minima - Saddle + Maxima = "; morseinfo += morseVertice.MinList.Count - morseVertice.SaddleList.Count + morseVertice.MaxList.Count + "\r\n"; return(morseinfo); }
public static void TransformationWorldPosition(TriMesh mesh, Vector3D worldX, Vector3D worldY, Vector3D worldZ) //按照新世界坐标轴进行变换 { Matrix4D m = Matrix4D.Identity(); //清空 m[0, 0] = worldX.x; m[0, 1] = worldX.y; m[0, 2] = worldX.z; m[1, 0] = worldY.x; m[1, 1] = worldY.y; m[1, 2] = worldY.z; m[2, 0] = worldZ.x; m[2, 1] = worldZ.y; m[2, 2] = worldZ.z; TransformationTriMesh(mesh, m); }
public NonManifoldMesh DualCreateMesh(TriMesh mesh) { NonManifoldMesh dualMesh = new NonManifoldMesh(); dualMesh.VertexPos = mesh.DualCreateVertexPosition(); dualMesh.FaceIndex = mesh.DualCreateFaceIndex(); dualMesh.VertexCount = mesh.Faces.Count; dualMesh.FaceCount = dualMesh.FaceIndex.Length / 3; dualMesh.ScaleToUnitBox(); dualMesh.MoveToCenter(); dualMesh.ComputeFaceNormal(); dualMesh.ComputeVertexNormal(); return(dualMesh); }
public static void WriteSelection(string filePath, TriMesh mesh) { FileStream fs = new FileStream(filePath, FileMode.Create); StreamWriter sw = new StreamWriter(fs); //sw.WriteLine("#Vertices:" + mesh.Vertices.Count); //sw.WriteLine("#Edges:" + mesh.Faces.Count); //sw.WriteLine("#Faces:" + mesh.Faces.Count); foreach (TriMesh.Vertex item in mesh.Vertices) { if (item.Traits.SelectedFlag > 0) { sw.WriteLine("{0} {1} {2}", item.Traits.Position.x, item.Traits.Position.y, item.Traits.Position.z); } } sw.WriteLine(); foreach (TriMesh.Edge item in mesh.Edges) { if (item.Traits.SelectedFlag > 0) { Vector3D v1 = item.Vertex0.Traits.Position; Vector3D v2 = item.Vertex1.Traits.Position; sw.WriteLine("{0} {1} {2} {3} {4} {5} ", v1.x, v1.y, v1.z, v2.x, v2.y, v2.z); } } sw.WriteLine(); foreach (TriMesh.Face item in mesh.Faces) { if (item.Traits.SelectedFlag > 0) { Vector3D v1 = item.GetVertex(0).Traits.Position; Vector3D v2 = item.GetVertex(1).Traits.Position; Vector3D v3 = item.GetVertex(2).Traits.Position; sw.WriteLine("{0} {1} {2} {3} {4} {5} {6} {7} {8}", v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, v3.x, v3.y, v3.z); } } sw.WriteLine(); sw.Close(); fs.Close(); }
public void DrawSaddleToMax(TriMesh mesh, double[] function) { MorseVertice morseVertice = ComputeMorseVertice(mesh, function); foreach (TriMesh.Vertex saddle in morseVertice.SaddleList) { foreach (TriMesh.HalfEdge[] path in FindPath(saddle, true)) { foreach (TriMesh.HalfEdge hf in path) { hf.Edge.Traits.SelectedFlag = 1; hf.Edge.Traits.Color = Color4.Purple; } } } }
public SparseMatrixDouble BuildExteriorDerivative0Form(TriMesh mesh) { SparseMatrixDouble d0 = new SparseMatrixDouble(mesh.Edges.Count, mesh.Vertices.Count); foreach (TriMesh.Edge edge in mesh.Edges) { int ci = edge.HalfEdge0.FromVertex.Index; int cj = edge.HalfEdge0.ToVertex.Index; d0[edge.Index, ci] = 1; d0[edge.Index, cj] = -1; } D0 = d0; return(d0); }
public SparseMatrixDouble BuildHodgeStar1Form(TriMesh mesh) { SparseMatrixDouble star1 = new SparseMatrixDouble(mesh.Edges.Count, mesh.Edges.Count); foreach (TriMesh.Edge edge in mesh.Edges) { double cotAlpha = ComputeTan(edge.HalfEdge0); double cotBeta = ComputeTan(edge.HalfEdge1); star1[edge.Index, edge.Index] = (cotAlpha + cotBeta) / 2; } this.Star1 = star1; return(star1); }
private void ChangeGeometrySqrt3(TriMesh sourceMesh, TriMesh targetMesh) { for (int i = 0; i < sourceMesh.Vertices.Count; i++) { int n = sourceMesh.Vertices[i].VertexCount; Vector3D position = sourceMesh.Vertices[i].Traits.Position; Vector3D neighborsum = new Vector3D(0, 0, 0); double alpha = Sqrt3ComputeAlpha(n); foreach (TriMesh.Vertex neighbor in sourceMesh.Vertices[i].Vertices) { neighborsum += neighbor.Traits.Position; } vMap[i].Traits.Position = (1 - alpha) * position + (alpha / n) * neighborsum; } }
public static PrincipalCurvature[] ComputePricipalCurvature(TriMesh mesh) { double[] mean = ComputeMeanCurvature(mesh); double[] gauss = ComputeGaussianCurvatureIntegrated(mesh); int n = mesh.Vertices.Count; PrincipalCurvature[] pricipal = new PrincipalCurvature[n]; for (int i = 0; i < n; i++) { pricipal[i] = ComputePricipalCurvature(mean[i], gauss[i]); } return(pricipal); }
public double[,] CoverteFace(TriMesh mesh) { int nv = mesh.Faces.Count; double[,] data = new double[nv, 3]; for (int i = 0; i < nv; i++) { int index = 0; foreach (TriMesh.HalfEdge hf in mesh.Faces[i].Halfedges) { data[i, index] = hf.ToVertex.Index + 1; index++; } } return(data); }
public static double[] ComputeDistanceADF(TriMesh mesh, double parameterT, Eigen eigens) { double[] adfValues = new double[mesh.Vertices.Count]; for (int j = 1; j < eigens.Count; j++) { List <double> group = eigens.SortedEigens[j].EigenVector; for (int i = 0; i < group.Count; i++) { adfValues[i] += Math.Exp(-parameterT * (eigens.SortedEigens[j].EigenValue / eigens.SortedEigens[1].EigenValue)) * (group[i] * group[i]); } } return(adfValues); }