Example #1
0
        public SparseMatrixComplex BuildEnergy()
        {
            //Build Laplace matrix
            SparseMatrixDouble d0    = DECDouble.Instance.BuildExteriorDerivative0Form(mesh);;
            SparseMatrixDouble star1 = DECDouble.Instance.BuildHodgeStar1Form(mesh);
            SparseMatrixDouble L     = d0.Transpose() * star1 * d0;

            SparseMatrixComplex A = SparseMatrixComplex.Copy(ref L);

            //Iterate faces
            foreach (TriMesh.Face face in mesh.Faces)
            {
                //Iterate each halfedge in face
                foreach (TriMesh.HalfEdge hf in face.Halfedges)
                {
                    int i = hf.ToVertex.Index;
                    int j = hf.FromVertex.Index;

                    Complex value = 0.5 * DDGConstant;

                    A[i, j] -= value;
                    A[j, i] += value;
                }
            }


            return(A);
        }
Example #2
0
        public SparseMatrixDouble BuildLaplaceWithNeumannBoundary(TriMesh mesh)
        {
            SparseMatrixDouble d0 = this.BuildExteriorDerivative0Form(mesh);

            D0 = d0;

            SparseMatrixDouble star1 = this.BuildHodgeStar1Form(mesh);

            Star1 = star1;

            SparseMatrixDouble star0 = this.BuildHodgeStar0Form(mesh);

            Star0 = star0;

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

            delta += (1.0e-8) * star0;

            Laplace = delta;
            return(delta);
        }
Example #3
0
        protected DenseMatrixDouble ComputeTrivaialConnection(SparseMatrixDouble d0, SparseMatrixDouble d1, double[] Guassian)
        {
            DenseMatrixDouble b = CholmodConverter.dConvertArrayToDenseMatrix(ref Guassian, Guassian.Length, 1);

            double[] singularValues = new double[Singularities.Count];

            //Init with avg of 2
            double avgValue = 2.0f / (double)Singularities.Count;

            int j = 0;

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

                b[index, 0] = Guassian[index] - 2 * Math.PI * value;
                j++;
            }

            for (int i = 0; i < Guassian.Length; i++)
            {
                b[i, 0] = -b[i, 0];
            }

            SparseMatrixDouble A = d0.Transpose();

            DenseMatrixDouble x = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref A, ref b);

            SparseMatrixDouble d1T     = d1.Transpose();
            SparseMatrixDouble Laplace = d1 * d1T;
            DenseMatrixDouble  rhs     = d1 * x;

            DenseMatrixDouble y = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref Laplace, ref rhs);

            x = x - d1T * y;

            return(x);
        }
Example #4
0
        public Vector3D[] Process()
        {
            //Build laplace
            SparseMatrixDouble star0 = DECDouble.Instance.Star0;

            if (star0 == null)
            {
                star0 = DECDouble.Instance.BuildHodgeStar0Form(mesh);
            }

            SparseMatrixDouble star1 = DECDouble.Instance.Star1;

            if (star1 == null)
            {
                star1 = DECDouble.Instance.BuildHodgeStar1Form(mesh);
            }

            SparseMatrixDouble d0 = DECDouble.Instance.D0;

            if (d0 == null)
            {
                d0 = DECDouble.Instance.BuildExteriorDerivative0Form(mesh);
            }

            SparseMatrixDouble d1 = DECDouble.Instance.D1;

            if (d1 == null)
            {
                d1 = DECDouble.Instance.BuildExteriorDerivative1Form(mesh);
            }

            if (Singularities == null)
            {
                Singularities = new List <KeyValuePair <HalfEdgeMesh.Vertex, double> >();
            }

            if (Singularities.Count == 0)
            {
                int count = 0;
                foreach (TriMesh.Vertex v in mesh.Vertices)
                {
                    if (v.Traits.selectedFlag > 0)
                    {
                        count++;
                    }
                }

                double avg = 2 / (double)count;

                int item = 0;
                foreach (TriMesh.Vertex V in mesh.Vertices)
                {
                    if (V.Traits.selectedFlag > 0)
                    {
                        if (item % 2 == 0) //2
                        {
                            Singularities.Add(new KeyValuePair <HalfEdgeMesh.Vertex, double>(V, -1));
                        }

                        if (item % 2 == 1) //2
                        {
                            Singularities.Add(new KeyValuePair <HalfEdgeMesh.Vertex, double>(V, 1));
                        }
                    }
                }
            }

            Laplace = d0.Transpose() * star1 * d0;

            Laplace = Laplace + (1.0e-8) * star0;


            InitProcess(this.mesh);
            GenerateFaceNormals();
            Vector3D[] VectorFields = ComputeVectorField(0);

            return(VectorFields);
        }
Example #5
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);
        }
Example #6
0
        public List <double>[] BuildHarmonicBasis(List <List <TriMesh.HalfEdge> > generators)
        {
            List <double>[] HarmonicBasis;

            HarmonicBasis = new List <double> [mesh.HalfEdges.Count];

            SparseMatrixDouble laplace = DECDouble.Instance.BuildLaplaceWithNeumannBoundary(mesh);
            SparseMatrixDouble star1   = DECDouble.Instance.Star1;

            if (star1 == null)
            {
                star1 = DECDouble.Instance.BuildHodgeStar1Form(mesh);
            }

            SparseMatrixDouble d0 = DECDouble.Instance.D0;

            if (d0 == null)
            {
                d0 = DECDouble.Instance.BuildExteriorDerivative0Form(mesh);
            }

            SparseMatrixDouble d1 = DECDouble.Instance.D1;

            if (d1 == null)
            {
                d1 = DECDouble.Instance.BuildExteriorDerivative1Form(mesh);
            }


            SparseMatrixDouble div = d0.Transpose() * star1;

            bool skipBoundary = true;

            foreach (List <TriMesh.HalfEdge> loopItem in generators)
            {
                if (skipBoundary && treeCoTree.IsBoundaryGenerator(loopItem))
                {
                    skipBoundary = false;
                    continue;
                }

                DenseMatrixDouble W    = BuildClosedPrimalOneForm(mesh, loopItem);
                DenseMatrixDouble divW = div * W;

                DenseMatrixDouble u = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref laplace, ref divW);

                DenseMatrixDouble h = star1 * (W - (d0 * u));

                //Store correspond edge
                foreach (TriMesh.Edge edge in mesh.Edges)
                {
                    double value = h[edge.Index, 0];
                    if (HarmonicBasis[edge.HalfEdge0.Index] == null)
                    {
                        HarmonicBasis[edge.HalfEdge0.Index] = new List <double>();
                    }
                    HarmonicBasis[edge.HalfEdge0.Index].Add(value);


                    if (HarmonicBasis[edge.HalfEdge1.Index] == null)
                    {
                        HarmonicBasis[edge.HalfEdge1.Index] = new List <double>();
                    }
                    HarmonicBasis[edge.HalfEdge1.Index].Add(-value);
                }
            }

            return(HarmonicBasis);
        }
Example #7
0
        public double[] Process(double dt, TriMesh mesh, out Vector3D[] vectorFields, out double maxDistance)
        {
            DenseMatrixDouble x = null;
            int nb = BuildImpulseSingal(mesh, out x);

            vectorFields = null;
            maxDistance  = 0;
            if (nb == 0)
            {
                return(null);
            }

            SparseMatrixDouble star0 = DECDouble.Instance.Star0;

            if (star0 == null)
            {
                star0 = DECDouble.Instance.BuildHodgeStar0Form(mesh);
            }

            SparseMatrixDouble star1 = DECDouble.Instance.Star1;

            if (star1 == null)
            {
                star1 = DECDouble.Instance.BuildHodgeStar1Form(mesh);
            }

            SparseMatrixDouble d0 = DECDouble.Instance.D0;

            if (d0 == null)
            {
                d0 = DECDouble.Instance.BuildExteriorDerivative0Form(mesh);
            }


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

            L += 1.0e-8 * star0;

            //Heat flow:
            //[TO DO] edgeLength

            double edgelength = MeanEdgeLength(mesh);

            dt *= Math.Sqrt(edgelength);
            SparseMatrixDouble A = star0 + dt * L;

            DenseMatrixDouble u = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref A, ref x);

            //Extract geodesic
            vectorFields = ComputeVectorField(u, mesh);

            DenseMatrixDouble div = ComputeDivergence(mesh, vectorFields);

            DenseMatrixDouble phi = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref L, ref div);

            SetMinToZero(phi);


            double[] VertexDistances = AssignDistance(phi);

            double max = double.MinValue;

            for (int i = 0; i < VertexDistances.Length; i++)
            {
                double value = Math.Abs(VertexDistances[i]);
                if (max < value)
                {
                    max = value;
                }
            }

            maxDistance = max;

            return(VertexDistances);
        }
Example #8
0
        protected DenseMatrixDouble ComputeTrivaialConnection(SparseMatrixDouble d0, SparseMatrixDouble d1, double[] Guassian)
        {
            DenseMatrixDouble b = CholmodConverter.dConvertArrayToDenseMatrix(ref Guassian, Guassian.Length, 1);

            double[] singularValues = new double[Singularities.Count];

            //Init with avg of 2
            double avgValue = 2.0f / (double)Singularities.Count;

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

                b[index, 0] = Guassian[index] - 2 * Math.PI * value;
                j++;
            }

            for (int i = 0; i < Guassian.Length; i++)
            {
                b[i, 0] = -b[i, 0];
            }

            SparseMatrixDouble A = d0.Transpose();

            DenseMatrixDouble x = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref A, ref b);

            SparseMatrixDouble d1T = d1.Transpose();
            SparseMatrixDouble Laplace = d1 * d1T;
            DenseMatrixDouble rhs = d1 * x;

            DenseMatrixDouble y = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref Laplace, ref rhs);
            x = x - d1T * y;

            return x;
        }