private void ApplyHarmonicSolver_Cholmod()
        {
            // --- build up lefthand side matrix A
            int vn = mesh.VertexCount;
            int fn = mesh.FaceCount;
            int bn = this.sourceVertices.Count + this.sinkVertices.Count;
            int m = vn+bn;

            if (this.sparseSolver != null) this.sparseSolver.Release();
            this.sparseSolver = new CholmodSolver();

            this.sparseSolver.InitializeMatrixA(m, vn);
            for (int i = 0, j = 0; i < fn; i++, j += 3)
            {
                int c1 = mesh.FaceIndex[j];
                int c2 = mesh.FaceIndex[j + 1];
                int c3 = mesh.FaceIndex[j + 2];
                Vector3d v1 = new Vector3d(mesh.VertexPos, c1 * 3);
                Vector3d v2 = new Vector3d(mesh.VertexPos, c2 * 3);
                Vector3d v3 = new Vector3d(mesh.VertexPos, c3 * 3);
                double cot1 = (v2 - v1).Dot(v3 - v1) / (v2 - v1).Cross(v3 - v1).Length();
                double cot2 = (v3 - v2).Dot(v1 - v2) / (v3 - v2).Cross(v1 - v2).Length();
                double cot3 = (v1 - v3).Dot(v2 - v3) / (v1 - v3).Cross(v2 - v3).Length();
                sparseSolver.Add_Coef(c2, c2, -cot1); sparseSolver.Add_Coef(c2, c3, cot1);
                sparseSolver.Add_Coef(c3, c3, -cot1); sparseSolver.Add_Coef(c3, c2, cot1);
                sparseSolver.Add_Coef(c3, c3, -cot2); sparseSolver.Add_Coef(c3, c1, cot2);
                sparseSolver.Add_Coef(c1, c1, -cot2); sparseSolver.Add_Coef(c1, c3, cot2);
                sparseSolver.Add_Coef(c1, c1, -cot3); sparseSolver.Add_Coef(c1, c2, cot3);
                sparseSolver.Add_Coef(c2, c2, -cot3); sparseSolver.Add_Coef(c2, c1, cot3);
            }

            // add positional weights
            int index = 0;
            foreach (int v in sourceVertices)
            {
                sparseSolver.Add_Coef(vn + index, v, 1.0 * ConstantWeight);
                ++index;
            }
            foreach (int v in sinkVertices)
            {
                sparseSolver.Add_Coef(vn + index, v, 1.0 * ConstantWeight);
                ++index;
            }

            if (!opt.UseAtb) m = vn;

            double[] b = new double[m];
            double[] x = new double[vn];

            // -- assign values to the right hand side b,-- Ax=b
            if (opt.UseAtb)
            {
                for (int j = 0; j < b.Length; j++) b[j] = 0;
                int count = 0;
                for (int j = 0; j < sourceVertices.Count; ++j, ++count)
                    b[vn + j] = 1.0 * ConstantWeight;
                for (int j = 0; j < sinkVertices.Count; ++j)
                    b[vn + count + j] = 0.0;
            }
            else // set by user..
            {
                foreach (int v in this.sourceVertices)
                    b[v] = 1.0 * ConstantWeight * ConstantWeight;
            }

            fixed (double* _b = b)
            {
                sparseSolver.InitializeMatrixB(_b, m, 1);
            }
            sparseSolver.InitializeSolver();
            sparseSolver.SetFinalPack(0);
            sparseSolver.Factorize();

            fixed (double* _x = x)
            {
                sparseSolver.Linear_Solve(_x, !opt.UseAtb);
            }

            this.harmonicField = x;
        }
Exemple #2
0
        // main function
        private void ComputeBezierControlPoints()
        {
            CholmodSolver cholmodSolver = new CholmodSolver();

            int n = numOfPoints - 2;

            cholmodSolver.InitializeMatrixA(n, n);
            for (int i = 0; i < n; ++i)
            {
                if (i == 0)
                {
                    cholmodSolver.Add_Coef(i, i, 4);
                    cholmodSolver.Add_Coef(i, i + 1, 1);
                }
                else if (i == n - 1)
                {
                    cholmodSolver.Add_Coef(i, i, 4);
                    cholmodSolver.Add_Coef(i, i - 1, 1);
                }
                else
                {
                    cholmodSolver.Add_Coef(i, i - 1, 1);
                    cholmodSolver.Add_Coef(i, i, 4);
                    cholmodSolver.Add_Coef(i, i + 1, 1);
                }
            }

            // factorize
            cholmodSolver.InitializeSolver();
            cholmodSolver.SetFinalPack(0);
            cholmodSolver.Factorize();

            // rhs
            double[] b = new double[n]; double[] x = new double[n];
            for (int k = 0; k < dimension; ++k)
            {
                for (int i = 0; i < n; ++i)
                {
                    double   r = 6.0;
                    Vector2d pt;
                    if (i == 0)
                    {
                        pt = r * inputPoints[1] - inputPoints[0];
                    }
                    else if (i == n - 1)
                    {
                        pt = r * inputPoints[i + 1] - inputPoints[i + 2];
                    }
                    else
                    {
                        pt = r * inputPoints[i + 1];
                    }
                    switch (k)
                    {
                    case 0:
                        b[i] = pt.x;                                // (inputPoints[t].x - inputPoints[s].x);
                        break;

                    case 1:
                        b[i] = pt.y;                                //(inputPoints[t].y - inputPoints[s].y);
                        break;
                    }
                }

                // solve
                fixed(double *_b = b)
                {
                    cholmodSolver.InitializeMatrixB(_b, n, 1);
                }

                fixed(double *_x = x)
                {
                    cholmodSolver.Linear_Solve(_x, false);
                }

                // assign
                for (int i = 0; i < n; ++i)
                {
                    int tt = i + 1;
                    switch (k)
                    {
                    case 0:
                        this.B[tt].x = x[i];
                        break;

                    case 1:
                        this.B[tt].y = x[i];
                        break;
                    }
                }
            }
            B[0]            = inputPoints[0];
            B[B.Length - 1] = inputPoints[inputPoints.Length - 1];

            cholmodSolver.Release();
        }