예제 #1
0
        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;
                        }
                    }
                }
            }
        }
예제 #2
0
        //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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        //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;
                }
            }
        }
예제 #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
        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);
        }
예제 #8
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);
        }
예제 #9
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);
            }
        }
예제 #10
0
 protected override double GetValue(HalfEdgeMesh.Face target)
 {
     return(TriMeshUtil.ComputeAreaFace(target));
 }
예제 #11
0
        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]];
                }
            }
        }