Пример #1
0
        public static void TransformationRotation(List <TriMesh.Vertex> vertice, Vector3D rotation, bool local)
        {
            Vector3D center = Vector3D.Zero;
            Matrix4D m      = Matrix4D.Identity();

            if (local)
            {
                center = TriMeshUtil.GetCenter(vertice);

                Matrix4D moveC = ComputeMatrixMove(ref center);
                center.Negate();
                Matrix4D moveCReverse = ComputeMatrixMove(ref center);
                Matrix4D r            = ComputeMatrixRotation(rotation);
                m = moveCReverse * r * moveC;
            }
            else
            {
                m = ComputeMatrixRotation(rotation);
            }
            TransformationVertex(vertice, m);
        }
Пример #2
0
        protected Vector3D GetPos1(TriMesh.HalfEdge hf)
        {
            Vector3D from = hf.FromVertex.Traits.Position;
            Vector3D to   = hf.ToVertex.Traits.Position;
            Vector3D l    = to - from;

            Vector3D[] vi = this.GetV(hf);
            Vector3D[] vj = this.GetV(hf.Opposite);
            Vector3D   c1 = Vector3D.Zero;
            Vector3D   c2 = Vector3D.Zero;

            for (int i = 0; i < vi.Length - 1; i++)
            {
                c1 += (vi[i] - from).Cross(vi[i + 1] - from);
            }
            for (int i = 0; i < vj.Length - 1; i++)
            {
                c2 += (vj[i + 1] - to).Cross(vj[i] - to);
            }
            Matrix4D m = Matrix4D.ZeroMatrix;

            m.Row1 = new Vector4D(c1 - c2, to.Dot(c2) - from.Dot(c1));
            m.Row2 = new Vector4D(l.y, -l.x, 0d, to.y * l.x - to.x * l.y);
            m.Row3 = new Vector4D(l.z, 0d, -l.x, to.z * l.x - to.x * l.z);
            m.Row4 = new Vector4D(0d, 0d, 0d, 1d);

            Vector3D pos = Vector3D.Zero;
            double   det = Util.Solve(ref m, ref pos);

            if (det == 0)
            {
                pos = TriMeshUtil.GetMidPoint(hf.Edge);
            }
            else
            {
                double vo1 = c1.Dot(pos - from);
                double vo2 = c2.Dot(pos - to);
            }
            return(pos);
        }
Пример #3
0
        public double[] SetColor(string item, TriMesh mesh, CriteriaInfo criteriaInfo)
        {
            TriMeshUtil.ClearMeshColor(mesh);

            double[] value = null;

            if (item == "DehidraAngleMin")
            {
                value = ColorEdgeByDihedralAngle(mesh, criteriaInfo.DehidraAngleMin, criteriaInfo.DehidraAngleMax);
            }

            if (item == "DehidraAngleMax")
            {
                value = ColorEdgeByDihedralAngle(mesh, criteriaInfo.DehidraAngleMin, criteriaInfo.DehidraAngleMax);
            }


            if (item == "GaussinMin")
            {
                value = ColorVertexByGaussin(mesh, criteriaInfo.GaussinMin, criteriaInfo.GaussinMax);
            }

            if (item == "GaussinMax")
            {
                value = ColorVertexByGaussin(mesh, criteriaInfo.GaussinMin, criteriaInfo.GaussinMax);
            }

            if (item == "MeanCurvatureMax")
            {
                value = ColorVertexByMeanCurvature(mesh, criteriaInfo.MeanCurvatureMin, criteriaInfo.MeanCurvatureMax);
            }

            if (item == "MeanCurvatureMin")
            {
                value = ColorVertexByMeanCurvature(mesh, criteriaInfo.MeanCurvatureMin, criteriaInfo.MeanCurvatureMax);
            }

            return(value);
        }
Пример #4
0
        public SparseMatrix BuildMatrixMeanCurvature(TriMesh mesh)
        {
            int          n = mesh.Vertices.Count;
            SparseMatrix L = BuildLaplaceMatrixCotBasic(mesh);

            double[] voronoiArea = TriMeshUtil.ComputeAreaVoronoi(mesh);
            for (int i = 0; i < n; i++)
            {
                double sum = 0;
                foreach (SparseMatrix.Element e in L.Rows[i])
                {
                    e.value = e.value / (voronoiArea[e.i] * 4);
                }
                foreach (SparseMatrix.Element e in L.Rows[i])
                {
                    sum += e.value;
                }
                L.AddValueTo(i, i, -sum);
            }
            L.SortElement();
            return(L);
        }
Пример #5
0
        public CurvaturePG07(TriMesh mesh)
        {
            this.mesh = mesh;

            this.K             = new Vector3D[this.mesh.Vertices.Count];
            this.Mean          = new double[this.mesh.Vertices.Count];
            this.Normal        = new Vector3D[this.mesh.Vertices.Count];
            this.PrincipalCurv = new PrincipalCurvature[this.mesh.Vertices.Count];

            foreach (var v in this.mesh.Vertices)
            {
                double mixedArea = TriMeshUtil.ComputeAreaMixed(v);
                this.K[v.Index]      = ComputeK(v, mixedArea);
                this.Mean[v.Index]   = ComputeMeanCurvature(this.K[v.Index]);
                this.Normal[v.Index] = ComputeNormal(this.K[v.Index]);
            }

            foreach (var v in this.mesh.Vertices)
            {
                this.PrincipalCurv[v.Index] = this.ComputePrincipalCurvature(v);
            }
        }
Пример #6
0
        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);
        }
Пример #7
0
        private void InitCurvatureInfoGrid()
        {
            this.dataGridViewCurvature.Rows.Clear();
            double[] curvature = TriMeshUtil.ComputeGaussianCurvature(Mesh);

            double[]             meanCurv = TriMeshUtil.ComputeMeanCurvature(Mesh);
            PrincipalCurvature[] basic    = TriMeshUtil.ComputePricipalCurvature(Mesh);

            PrincipalCurvature[] pg = TriMeshUtil.ComputePricipalCurvaturePG07(Mesh);
            CurvatureLib.Init(Mesh);
            PrincipalCurvature[] ccc = CurvatureLib.ComputeCurvature();

            for (int i = 0; i < curvature.Length; i++)
            {
                this.dataGridViewCurvature.Rows.Add(i,
                                                    curvature[i],
                                                    meanCurv[i],
                                                    ccc[i].max,
                                                    ccc[i].min,
                                                    pg[i].max,
                                                    pg[i].min);
            }
        }
Пример #8
0
        public void Cut(Plane plane)
        {
            this.plane    = plane;
            this.list     = new List <Triangle>();
            this.cutPoint = new Dictionary <int, CutPoint>();

            foreach (var hf in this.mesh.HalfEdges)
            {
                this.CutHalfEdge(hf);
            }

            foreach (var face in this.mesh.Faces)
            {
                this.CutFace(face);
            }

            List <TriMesh.Edge> edges = new List <HalfEdgeMesh.Edge>();

            foreach (var hf in this.mesh.HalfEdges)
            {
                if (this.cutPoint.ContainsKey(hf.Index))
                {
                    edges.Add(hf.Edge);
                }
            }
            foreach (var item in edges)
            {
                TriMeshModify.RemoveEdge(item);
            }

            foreach (var item in this.list)
            {
                this.mesh.Faces.AddTriangles(item.V1, item.V2, item.V3);
            }
            TriMeshUtil.FixIndex(mesh);
            TriMeshUtil.SetUpNormalVertex(mesh);
        }
Пример #9
0
        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);
        }
Пример #10
0
        public void DrawFaceNormal(TriMesh mesh)
        {
            OpenGLManager.Instance.SetColor(GlobalSetting.DisplaySetting.NormalColor);
            double avgLength = TriMeshUtil.ComputeEdgeAvgLength(mesh);

            avgLength *= GlobalSetting.DisplaySetting.NormalLength;
            foreach (TriMesh.Face item in mesh.Faces)
            {
                double x = (item.GetVertex(0).Traits.Position.x +
                            item.GetVertex(1).Traits.Position.x +
                            item.GetVertex(2).Traits.Position.x) / 3;
                double y = (item.GetVertex(0).Traits.Position.y +
                            item.GetVertex(1).Traits.Position.y +
                            item.GetVertex(2).Traits.Position.y) / 3;
                double z = (item.GetVertex(0).Traits.Position.z +
                            item.GetVertex(1).Traits.Position.z +
                            item.GetVertex(2).Traits.Position.z) / 3;
                Vector3D normal = item.Traits.Normal.Normalize() * avgLength;
                GL.Begin(BeginMode.Lines);
                GL.Vertex3(x, y, z);
                GL.Vertex3(x + normal.x, y + normal.y, z + normal.z);
                GL.End();
            }
        }
Пример #11
0
        public TriMesh AddSelectionEdge(TriMesh mesh, int index)
        {
            List <TriMesh> sel = new List <TriMesh>();

            for (int i = 0; i < mesh.Edges.Count; i++)
            {
                if (mesh.Edges[i].Traits.SelectedFlag == index)
                {
                    TriMesh selV = TriMeshIO.FromObjFile(ConfigShape.Instance.EdgeFile);
                    TriMeshUtil.ScaleToUnit(selV, 1);
                    TriMeshUtil.ScaleToUnit(selV, ConfigShape.Instance.Scale);
                    Vector3D direction = mesh.Edges[i].Vertex1.Traits.Position - mesh.Edges[i].Vertex0.Traits.Position;
                    Vector3D loc       = (mesh.Edges[i].Vertex1.Traits.Position + mesh.Edges[i].Vertex0.Traits.Position) / 2;

                    Matrix4D scale = TriMeshUtil.ComputeMatrixScale(direction.Length() / ConfigShape.Instance.Scale, 1d, 1d);


                    //  TriMeshUtil.TransformationRotation(selV, direction);

                    TriMeshUtil.TransformationScale(selV, scale);
                    TriMeshUtil.TransformRoatationV(selV, direction, Vector3D.UnitX);
                    //TriMeshUtil.TransformRotationX(selV, direction.x);
                    //TriMeshUtil.TransformRotationY(selV, direction.y);
                    //TriMeshUtil.TransformRotationZ(selV, direction.z);
                    TriMeshUtil.TransformationMove(selV, loc);
                    sel.Add(selV);
                }
            }

            TriMesh result = TriMeshUtil.Combine(sel);

            result.FileName = Path.GetFileNameWithoutExtension(mesh.FileName) + "-E-" + index.ToString();

            TriMeshUtil.SetUpVertexNormal(result, EnumNormal.AreaWeight);
            return(result);
        }
Пример #12
0
        public DenseMatrixDouble InitWithTrivalHolonmy(SparseMatrixDouble Laplace, TriMesh mesh)
        {
            DenseMatrixDouble b = new DenseMatrixDouble(mesh.Vertices.Count, 1);

            double[] tempSingularities = new double[mesh.Vertices.Count];
            for (int i = 0; i < tempSingularities.Length; i++)
            {
                tempSingularities[i] = 0;
            }

            foreach (KeyValuePair <TriMesh.Vertex, double> pair in Singularities)
            {
                int    index = pair.Key.Index;
                double value = pair.Value;

                tempSingularities[index] = value;
            }

            double[] GuassianCurvs = TriMeshUtil.ComputeGaussianCurvatureIntegrated(mesh);

            foreach (TriMesh.Vertex v in mesh.Vertices)
            {
                double value = 0;
                if (!v.OnBoundary)
                {
                    value -= GuassianCurvs[v.Index];
                    value += 2 * Math.PI * tempSingularities[v.Index];
                }

                b[v.Index, 0] = value;
            }

            DenseMatrixDouble u = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref Laplace, ref b);

            return(u);
        }
Пример #13
0
        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
            });
        }
Пример #14
0
        public static Dictionary <string, string> BuildMeshInfo(TriMesh mesh)
        {
            Dictionary <string, string> meshinfo = new Dictionary <string, string>();

            meshinfo.Add("Verties", mesh.Vertices.Count.ToString());
            meshinfo.Add("Edges", mesh.Edges.Count.ToString());
            meshinfo.Add("Faces", mesh.Faces.Count.ToString());

            meshinfo.Add("Elur Formula For Genus=0", "V-E+F = 2");
            meshinfo.Add("General Elur Formula on Genus !=0", "V-E+F=2(C-G)-B, C is Component Number,G is Genus Number,B is boundary Number");
            meshinfo.Add("Elur Characteristic is ", "2(C-G)-B or V-E+F");
            meshinfo.Add("Elur Characteristic on Current Mesh",
                         "V-E+F = " +
                         mesh.Vertices.Count.ToString() + " - " +
                         mesh.Edges.Count.ToString() + " + " +
                         mesh.Faces.Count.ToString() + " = " +
                         CountEulerCharacteristic(mesh).ToString());
            meshinfo.Add("Component", CountComponents(mesh, false).ToString());
            meshinfo.Add("Boundary Number", TriMeshUtil.CountBoundary(mesh).ToString());
            meshinfo.Add("Genus", "G=-((V-E+F)+B)/2+C");

            meshinfo.Add("Genus on Current mesh", CountGenus(mesh).ToString());
            meshinfo.Add("Total Gaussian Curvature is ", TriMeshUtil.ComputeTotalGaussianCurvarture(mesh).ToString());
            meshinfo.Add("Gaussian-Bonnet Theroem", "2*PI*(V-E+F) = SUM(Gaussian Curvature)");
            meshinfo.Add("Current Gaussian-Bonnet Theroem",
                         "2*PI*(V-E+F)=" +
                         "2 x 3.1415 x " + CountEulerCharacteristic(mesh).ToString() + " = " +
                         (Math.PI * 2 * CountEulerCharacteristic(mesh))
                         + " ??=  " + TriMeshUtil.ComputeTotalGaussianCurvarture(mesh)
                         );
            meshinfo.Add("Average Area", TriMeshUtil.ComputeAreaAverage(mesh).ToString());
            meshinfo.Add("Volume", TriMeshUtil.ComputeVolume(mesh).ToString());
            meshinfo.Add("Total Area", TriMeshUtil.ComputeAreaTotal(mesh).ToString());

            return(meshinfo);
        }
Пример #15
0
        public static void BoundaryExpand(TriMesh mesh)
        {
            double length = TriMeshUtil.ComputeEdgeAvgLength(mesh);
            List <List <TriMesh.HalfEdge> > holes = TriMeshUtil.RetrieveBoundaryEdgeAll(mesh);

            foreach (var hole in holes)
            {
                TriMesh.Vertex[] arr = new HalfEdgeMesh.Vertex[hole.Count];
                for (int i = 0; i < hole.Count; i++)
                {
                    Vector3D normal = Vector3D.UnitX;
                    if (hole[i].Opposite.Face != null)
                    {
                        normal = TriMeshUtil.ComputeNormalFace(hole[i].Opposite.Face);
                    }
                    Vector3D toPos   = hole[i].ToVertex.Traits.Position;
                    Vector3D fromPos = hole[i].FromVertex.Traits.Position;
                    Vector3D hfDir   = toPos - fromPos;
                    Vector3D hfMid   = (toPos + fromPos) / 2;
                    Vector3D pos     = hfMid + normal.Cross(hfDir).Normalize() * length;
                    arr[i] = mesh.Vertices.Add(new VertexTraits(pos));
                }
                for (int i = 0; i < hole.Count; i++)
                {
                    int          next = (i + 1) % hole.Count;
                    TriMesh.Face face = mesh.Faces.Add(arr[i],
                                                       hole[i].ToVertex,
                                                       hole[next].ToVertex);
                    face.Traits.SelectedFlag = 1;
                    face = mesh.Faces.Add(arr[i],
                                          hole[next].ToVertex,
                                          arr[next]);
                    face.Traits.SelectedFlag = 1;
                }
            }
        }
Пример #16
0
        public void DrawTreeCotree(List <TriMesh.Edge> treeMarks, List <TriMesh.Edge> cotreeMarks)
        {
            OpenGLManager.Instance.SetColor(System.Drawing.Color.Green);
            //Draw Tree
            foreach (TriMesh.Edge item in treeMarks)
            {
                GL.Begin(BeginMode.Lines);
                Vector3D a = item.Vertex0.Traits.Position;
                Vector3D b = item.Vertex1.Traits.Position;


                GL.Vertex3(a.x, a.y, a.z);
                GL.Vertex3(b.x, b.y, b.z);
                GL.End();
            }

            OpenGLManager.Instance.SetColor(System.Drawing.Color.Red);
            //Draw CoTree
            foreach (TriMesh.Edge item in cotreeMarks)
            {
                Vector3D a            = TriMeshUtil.GetMidPoint(item.Face0);
                Vector3D b            = TriMeshUtil.GetMidPoint(item.Face1);
                Vector3D centerOfEdge = (item.Vertex0.Traits.Position + item.Vertex1.Traits.Position) / 2;


                GL.Begin(BeginMode.Lines);
                GL.Vertex3(a.x, a.y, a.z);
                GL.Vertex3(centerOfEdge.x, centerOfEdge.y, centerOfEdge.z);
                GL.End();

                GL.Begin(BeginMode.Lines);
                GL.Vertex3(centerOfEdge.x, centerOfEdge.y, centerOfEdge.z);
                GL.Vertex3(b.x, b.y, b.z);
                GL.End();
            }
        }
Пример #17
0
        protected Vector3D[] ComputeVectorField(DenseMatrixDouble u, TriMesh mesh)
        {
            Vector3D[] vectors = new Vector3D[mesh.Faces.Count];

            foreach (TriMesh.Face f in mesh.Faces)
            {
                if (f.OnBoundary)
                {
                    continue;
                }

                TriMesh.HalfEdge hij = f.HalfEdge;
                TriMesh.HalfEdge hjk = hij.Next;
                TriMesh.HalfEdge hki = hjk.Next;

                TriMesh.Vertex vi = hij.FromVertex;
                TriMesh.Vertex vj = hjk.FromVertex;
                TriMesh.Vertex vk = hki.FromVertex;

                double ui = u[vi.Index, 0];
                double uj = u[vj.Index, 0];
                double uk = u[vk.Index, 0];

                Vector3D eijL = RotatedEdge(hij);
                Vector3D ejkL = RotatedEdge(hjk);
                Vector3D ekiL = RotatedEdge(hki);

                double area = TriMeshUtil.ComputeAreaFaceTwo(f);

                Vector3D x = 0.5 * (ui * ejkL + uj * ekiL + uk * eijL) / area;

                vectors[f.Index] = -x.Normalize();
            }

            return(vectors);
        }
Пример #18
0
 public void Run()
 {
     TriMeshUtil.TransformationRotation(GlobalData.Instance.TriMesh, new Vector3D(0, 0, 0.001d));
 }
Пример #19
0
 private void scaleToUnitToolStripMenuItem_Click(object sender, EventArgs e)
 {
     TriMeshUtil.ScaleToUnit(Mesh, 0.9);
     OnChanged(EventArgs.Empty);
 }
Пример #20
0
 private void moveToCenterToolStripMenuItem_Click(object sender, EventArgs e)
 {
     TriMeshUtil.MoveToCenter(Mesh);
     OnChanged(EventArgs.Empty);
 }
Пример #21
0
 private void reverseToolStripMenuItem_Click(object sender, EventArgs e)
 {
     TriMeshUtil.SelectedVertexReverse(Mesh);
     TriMeshUtil.GroupVertice(Mesh);
     OnChanged(EventArgs.Empty);
 }
Пример #22
0
 private void randomToolStripMenuItem_Click(object sender, EventArgs e)
 {
     TriMeshUtil.SelectedVertexRandom(Mesh, ConfigMeshOP.Instance.RandomSelect);
     OnChanged(EventArgs.Empty);
 }
Пример #23
0
 protected double GetValue(TriMesh.Vertex v)
 {
     return(TriMeshUtil.ComputeGaussianCurvature(v));
 }
Пример #24
0
        public static void RepairComplexHole(TriMesh mesh)
        {
            List <TriMesh.Vertex> hole = new List <TriMesh.Vertex>();

            TriMesh.Vertex[] faceVertices = new TriMesh.Vertex[3];



            while (true)//此循环只限单洞修补
            {
                //计算边界边的平均值
                #region 计算边界边的平均值
                hole = TriMeshUtil.RetrieveBoundarySingle(mesh);
                double   aver_l     = 0;
                double[] edgeLength = new double[hole.Count];
                for (int i = 0; i < hole.Count; i++)
                {
                    if (i == hole.Count - 1)
                    {
                        edgeLength[i] = Math.Sqrt(Math.Pow(hole[i].Traits.Position.x - hole[0].Traits.Position.x, 2) + Math.Pow(hole[i].Traits.Position.y - hole[0].Traits.Position.y, 2) + Math.Pow(hole[i].Traits.Position.z - hole[0].Traits.Position.z, 2));
                        break;
                    }
                    edgeLength[i] = Math.Sqrt(Math.Pow(hole[i].Traits.Position.x - hole[i + 1].Traits.Position.x, 2) + Math.Pow(hole[i].Traits.Position.y - hole[i + 1].Traits.Position.y, 2) + Math.Pow(hole[i].Traits.Position.z - hole[i + 1].Traits.Position.z, 2));
                }
                for (int i = 0; i < hole.Count; i++)
                {
                    aver_l += edgeLength[i];
                }
                aver_l = aver_l / hole.Count;
                #endregion

                hole = TriMeshUtil.RetrieveBoundarySingle(mesh);

                //计算角度值
                #region 计算角度值
                double[] angle = new double[hole.Count];
                double   a = 0, b = 0, c = 0;
                for (int i = 0; i < hole.Count; i++)
                {
                    if (i == 0)
                    {
                        a        = Math.Sqrt(Math.Pow(hole[hole.Count - 1].Traits.Position.x - hole[i + 1].Traits.Position.x, 2) + Math.Pow(hole[hole.Count - 1].Traits.Position.y - hole[i + 1].Traits.Position.y, 2) + Math.Pow(hole[hole.Count - 1].Traits.Position.z - hole[i + 1].Traits.Position.z, 2));
                        b        = Math.Sqrt(Math.Pow(hole[i].Traits.Position.x - hole[i + 1].Traits.Position.x, 2) + Math.Pow(hole[i].Traits.Position.y - hole[i + 1].Traits.Position.y, 2) + Math.Pow(hole[i].Traits.Position.z - hole[i + 1].Traits.Position.z, 2));
                        c        = Math.Sqrt(Math.Pow(hole[hole.Count - 1].Traits.Position.x - hole[i].Traits.Position.x, 2) + Math.Pow(hole[hole.Count - 1].Traits.Position.y - hole[i].Traits.Position.y, 2) + Math.Pow(hole[hole.Count - 1].Traits.Position.z - hole[i].Traits.Position.z, 2));
                        angle[i] = Math.Acos((b * b + c * c - a * a) / (2 * b * c));
                    }
                    else if (i == hole.Count - 1)
                    {
                        a        = Math.Sqrt(Math.Pow(hole[i - 1].Traits.Position.x - hole[0].Traits.Position.x, 2) + Math.Pow(hole[i - 1].Traits.Position.y - hole[0].Traits.Position.y, 2) + Math.Pow(hole[i - 1].Traits.Position.z - hole[0].Traits.Position.z, 2));
                        b        = Math.Sqrt(Math.Pow(hole[i].Traits.Position.x - hole[0].Traits.Position.x, 2) + Math.Pow(hole[i].Traits.Position.y - hole[0].Traits.Position.y, 2) + Math.Pow(hole[i].Traits.Position.z - hole[0].Traits.Position.z, 2));
                        c        = Math.Sqrt(Math.Pow(hole[i - 1].Traits.Position.x - hole[i].Traits.Position.x, 2) + Math.Pow(hole[i - 1].Traits.Position.y - hole[i].Traits.Position.y, 2) + Math.Pow(hole[i - 1].Traits.Position.z - hole[i].Traits.Position.z, 2));
                        angle[i] = Math.Acos((b * b + c * c - a * a) / (2 * b * c));
                    }
                    else
                    {
                        a        = Math.Sqrt(Math.Pow(hole[i - 1].Traits.Position.x - hole[i + 1].Traits.Position.x, 2) + Math.Pow(hole[i - 1].Traits.Position.y - hole[i + 1].Traits.Position.y, 2) + Math.Pow(hole[i - 1].Traits.Position.z - hole[i + 1].Traits.Position.z, 2));
                        b        = Math.Sqrt(Math.Pow(hole[i].Traits.Position.x - hole[i + 1].Traits.Position.x, 2) + Math.Pow(hole[i].Traits.Position.y - hole[i + 1].Traits.Position.y, 2) + Math.Pow(hole[i].Traits.Position.z - hole[i + 1].Traits.Position.z, 2));
                        c        = Math.Sqrt(Math.Pow(hole[i - 1].Traits.Position.x - hole[i].Traits.Position.x, 2) + Math.Pow(hole[i - 1].Traits.Position.y - hole[i].Traits.Position.y, 2) + Math.Pow(hole[i - 1].Traits.Position.z - hole[i].Traits.Position.z, 2));
                        angle[i] = Math.Acos((b * b + c * c - a * a) / (2 * b * c));
                    }
                }
                #endregion


                //取得最小的角度
                #region 取得最小的角度
                int min = 0;
                for (int i = 0; i < hole.Count - 1; i++)
                {
                    if (angle[i] < angle[i + 1])
                    {
                        min = i;
                    }
                    else
                    {
                        min = i + 1;
                    }
                }
                #endregion


                //求最小角度对应的边长
                #region 求最小角度对应的边长
                double temp = 0;
                if (min == hole.Count - 1)
                {
                    temp = Math.Sqrt(Math.Pow(hole[min - 1].Traits.Position.x - hole[0].Traits.Position.x, 2) + Math.Pow(hole[min - 1].Traits.Position.y - hole[0].Traits.Position.y, 2) + Math.Pow(hole[min - 1].Traits.Position.z - hole[0].Traits.Position.z, 2));
                }
                else if (min == 0)
                {
                    temp = Math.Sqrt(Math.Pow(hole[hole.Count - 1].Traits.Position.x - hole[min + 1].Traits.Position.x, 2) + Math.Pow(hole[hole.Count - 1].Traits.Position.y - hole[min + 1].Traits.Position.y, 2) + Math.Pow(hole[hole.Count - 1].Traits.Position.z - hole[min + 1].Traits.Position.z, 2));
                }
                else
                {
                    temp = Math.Sqrt(Math.Pow(hole[min - 1].Traits.Position.x - hole[min + 1].Traits.Position.x, 2) + Math.Pow(hole[min - 1].Traits.Position.y - hole[min + 1].Traits.Position.y, 2) + Math.Pow(hole[min - 1].Traits.Position.z - hole[min + 1].Traits.Position.z, 2));
                }
                #endregion


                //判断最小角对应的边与平均边界边长,并进行修补
                #region 判断最小角对应的边与平均边界边长,并进行修补
                if (temp > aver_l)
                {
                    if (min == hole.Count - 1)
                    {
                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[hole[0].Index];
                        faceVertices[2] = mesh.Vertices[hole[min - 1].Index];
                        mesh.Faces.AddTriangles(faceVertices);
                    }
                    else if (min == 0)
                    {
                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[hole[min + 1].Index];
                        faceVertices[2] = mesh.Vertices[hole[hole.Count - 1].Index];
                        mesh.Faces.AddTriangles(faceVertices);
                    }
                    else
                    {
                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[hole[min + 1].Index];
                        faceVertices[2] = mesh.Vertices[hole[min - 1].Index];
                        mesh.Faces.AddTriangles(faceVertices);
                    }
                }

                else
                {
                    if (min == hole.Count - 1)
                    {
                        Vector3D midPosition;
                        midPosition = (hole[min - 1].Traits.Position + hole[0].Traits.Position) / 2;
                        mesh.Vertices.Add(new VertexTraits(midPosition.x, midPosition.y, midPosition.z));

                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[mesh.Vertices.Count - 1];
                        faceVertices[2] = mesh.Vertices[hole[min - 1].Index];
                        mesh.Faces.AddTriangles(faceVertices);

                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[hole[0].Index];
                        faceVertices[2] = mesh.Vertices[mesh.Vertices.Count - 1];
                        mesh.Faces.AddTriangles(faceVertices);
                    }
                    else if (min == 0)
                    {
                        Vector3D midPosition;
                        midPosition = (hole[hole.Count - 1].Traits.Position + hole[min + 1].Traits.Position) / 2;
                        mesh.Vertices.Add(new VertexTraits(midPosition.x, midPosition.y, midPosition.z));

                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[mesh.Vertices.Count - 1];
                        faceVertices[2] = mesh.Vertices[hole[hole.Count - 1].Index];
                        mesh.Faces.AddTriangles(faceVertices);

                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[hole[min + 1].Index];
                        faceVertices[2] = mesh.Vertices[mesh.Vertices.Count - 1];
                        mesh.Faces.AddTriangles(faceVertices);
                    }
                    else
                    {
                        Vector3D midPosition;
                        midPosition = (hole[min - 1].Traits.Position + hole[min + 1].Traits.Position) / 2;
                        mesh.Vertices.Add(new VertexTraits(midPosition.x, midPosition.y, midPosition.z));

                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[mesh.Vertices.Count - 1];
                        faceVertices[2] = mesh.Vertices[hole[min - 1].Index];
                        mesh.Faces.AddTriangles(faceVertices);

                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[hole[min + 1].Index];
                        faceVertices[2] = mesh.Vertices[mesh.Vertices.Count - 1];
                        mesh.Faces.AddTriangles(faceVertices);
                    }
                }
                #endregion


                //更新边界点,并判断空洞是否完整
                #region 更新边界点,并判断空洞是否完整

                TriMeshUtil.FixIndex(mesh);
                hole = TriMeshUtil.RetrieveBoundarySingle(mesh);
                if (hole.Count < 3)
                {
                    break;
                }
                #endregion
            }
        }
Пример #25
0
        public static double ComputePerimeter(TriMesh.Face face)
        {
            Triple <Vector3D> t = TriMeshUtil.GetHalfEdgesVector(face);

            return(t.T0.Length() + t.T1.Length() + t.T2.Length());
        }
Пример #26
0
        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);
        }
Пример #27
0
        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);
            }
        }
Пример #28
0
 private void faceBySplitLineToolStripMenuItem_Click(object sender, EventArgs e)
 {
     TriMeshUtil.ShowMeshPatchColor(Mesh);
     OnChanged(EventArgs.Empty);
 }
Пример #29
0
        public static EdgeContext Merge(TriMesh.Edge edge)
        {
            Vector3D position = TriMeshUtil.GetMidPoint(edge);

            return(Merge(edge, position));
        }
Пример #30
0
        public void Run()
        {
            Stopwatch clock = new Stopwatch();

            clock.Start();

            double step = 0.01;

            DECMeshDouble      decMesh = new DECMeshDouble(mesh);
            SparseMatrixDouble laplace = decMesh.Laplace;

            SparseMatrixDouble star0 = decMesh.HodgeStar0Form;

            SparseMatrixDouble star1 = decMesh.HodgeStar1Form;

            SparseMatrixDouble d0 = decMesh.ExteriorDerivative0Form;

            SparseMatrixDouble L = d0.Transpose() * star1 * d0;


            SparseMatrixDouble A = star0 + step * L;

            A.WriteToFile("A.ma");

            double[] xs = new double[mesh.Vertices.Count];
            double[] ys = new double[mesh.Vertices.Count];
            double[] zs = new double[mesh.Vertices.Count];

            foreach (TriMesh.Vertex v in mesh.Vertices)
            {
                xs[v.Index] = v.Traits.Position.x;
                ys[v.Index] = v.Traits.Position.y;
                zs[v.Index] = v.Traits.Position.z;
            }

            double[] rhs1 = star0 * xs;
            double[] rhs2 = star0 * ys;
            double[] rhs3 = star0 * zs;


            //SparseMatrix.WriteVectorToFile("xs.ve", rhs1);
            //SparseMatrix.WriteVectorToFile("ys.ve", rhs2);
            //SparseMatrix.WriteVectorToFile("zs.ve", rhs3);

            DenseMatrixDouble rhsx = new DenseMatrixDouble(mesh.Vertices.Count, 1);
            DenseMatrixDouble rhsy = new DenseMatrixDouble(mesh.Vertices.Count, 1);
            DenseMatrixDouble rhsz = new DenseMatrixDouble(mesh.Vertices.Count, 1);

            for (int i = 0; i < mesh.Vertices.Count; i++)
            {
                rhsx[i, 0] = rhs1[i];
                rhsy[i, 0] = rhs2[i];
                rhsz[i, 0] = rhs3[i];
            }

            DenseMatrixDouble newX = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref A, ref rhsx);
            DenseMatrixDouble newY = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref A, ref rhsy);
            DenseMatrixDouble newZ = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref A, ref rhsz);

            foreach (TriMesh.Vertex v in mesh.Vertices)
            {
                v.Traits.Position.x = newX[v.Index, 0];
                v.Traits.Position.y = newY[v.Index, 0];
                v.Traits.Position.z = newZ[v.Index, 0];
            }

            TriMeshUtil.ScaleToUnit(mesh, 1.0f);
            TriMeshUtil.MoveToCenter(mesh);

            clock.Stop();

            decimal micro = clock.Elapsed.Ticks / 10m;

            Console.WriteLine("Total time cost:{0}", micro);
        }