예제 #1
0
        public void Build(TriMesh mesh)
        {
            int nBasisCycles = basisCycles.Count;

            //Build Matrix A
            A = BuildCycleMatrix(mesh, basisCycles);
            ApplyCotanWeights(ref A);

            //Factorize
            LinearSystemGenericByLib.Instance.FactorizationQR(ref A);

            K = new DenseMatrixDouble(basisCycles.Count, 1);
            b = new DenseMatrixDouble(basisCycles.Count, 1);

            //Add constraint of angle defect
            for (int i = 0; i < nContractibleCycles; i++)
            {
                K[i, 0] = -ComputeGeneratorDefect(basisCycles[i]);
            }

            //Add constraint of Generator
            int nGenerators = dualCycles.Count;

            for (int i = nContractibleCycles; i < nGenerators + nContractibleCycles; i++)
            {
                List <TriMesh.HalfEdge> generatorCycle = basisCycles[i];

                //Boundary condition
                if (treeCotree.IsBoundaryGenerator(generatorCycle))
                {
                    K[i, 0] = -BoundaryLoopCurvature(generatorCycle);
                    GeneratorOnBoundary[i - nContractibleCycles] = true;
                }
                //None-Boundary condition
                else
                {
                    K[i, 0] = -ComputeGeneratorDefect(generatorCycle);
                    GeneratorOnBoundary[i - nContractibleCycles] = false;
                }
            }

            //Copy to b
            for (int i = 0; i < nBasisCycles; i++)
            {
                b[i, 0] = K[i, 0];
            }
        }
예제 #2
0
        public void InitProcess(TriMesh mesh)
        {
            TreeCoTree treeCotree = new TreeCoTree(mesh);

            generatorLoops = treeCotree.ExtractHonologyGenerator(mesh);

            HarmonicBasis basis = new HarmonicBasis(mesh);

            HarmonicBasis = basis.BuildHarmonicBasis(generatorLoops);
            int numberOfHarmBases = basis.NumberOfHarmonicBases(generatorLoops);

            //Still need to built
            u = InitWithTrivalHolonmy(Laplace, mesh);

            HarmonicCoffition = new double[numberOfHarmBases];


            if (numberOfHarmBases == 0)
            {
                return;
            }

            DenseMatrixDouble  b = new DenseMatrixDouble(numberOfHarmBases, 1);
            SparseMatrixDouble H = new SparseMatrixDouble(numberOfHarmBases, numberOfHarmBases);

            int row = 0;

            bool skipBoundaryLoop = true;

            for (int i = 0; i < generatorLoops.Count; i++)
            {
                List <TriMesh.HalfEdge> cycle = generatorLoops[i];

                if (skipBoundaryLoop && treeCotree.IsBoundaryGenerator(cycle))
                {
                    skipBoundaryLoop = false;
                    continue;
                }

                foreach (TriMesh.HalfEdge hf in cycle)
                {
                    for (int col = 0; col < numberOfHarmBases; col++)
                    {
                        H[row, col] += HarmonicBasis[hf.Index][col];
                    }
                }

                double value = -GeneratorHolomy(cycle, HarmonicBasis, HarmonicCoffition, u);

                b[row, 0] = value;
                row++;
            }

            DenseMatrixDouble x = null;

            if (b.F_Norm() > 1.0e-8)
            {
                x = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref H, ref b);
            }
            else
            {
                x = new DenseMatrixDouble(numberOfHarmBases, 1);
            }

            for (int i = 0; i < numberOfHarmBases; i++)
            {
                HarmonicCoffition[i] = x[i, 0];
            }
        }
예제 #3
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);
        }
예제 #4
0
        public void InitProcess(TriMesh mesh)
        {

            TreeCoTree treeCotree = new TreeCoTree(mesh);

            generatorLoops = treeCotree.ExtractHonologyGenerator(mesh);

            HarmonicBasis basis = new HarmonicBasis(mesh);
            HarmonicBasis = basis.BuildHarmonicBasis(generatorLoops);
            int numberOfHarmBases = basis.NumberOfHarmonicBases(generatorLoops);

            //Still need to built
            u = InitWithTrivalHolonmy(Laplace, mesh);

            HarmonicCoffition = new double[numberOfHarmBases];


            if (numberOfHarmBases == 0)
            {
                return;
            }

            DenseMatrixDouble b = new DenseMatrixDouble(numberOfHarmBases, 1);
            SparseMatrixDouble H = new SparseMatrixDouble(numberOfHarmBases, numberOfHarmBases);

            int row = 0;

            bool skipBoundaryLoop = true;
            for (int i = 0; i < generatorLoops.Count; i++)
            {
                List<TriMesh.HalfEdge> cycle = generatorLoops[i];

                if (skipBoundaryLoop && treeCotree.IsBoundaryGenerator(cycle))
                {
                    skipBoundaryLoop = false;
                    continue;
                }

                foreach (TriMesh.HalfEdge hf in cycle)
                {
                    for (int col = 0; col < numberOfHarmBases; col++)
                    {
                        H[row, col] += HarmonicBasis[hf.Index][col];
                    }
                }

                double value = -GeneratorHolomy(cycle, HarmonicBasis, HarmonicCoffition, u);

                b[row, 0] = value;
                row++;
            }

            DenseMatrixDouble x = null;

            if (b.F_Norm() > 1.0e-8)
            {
                x = LinearSystemGenericByLib.Instance.SolveLinerSystem(ref H, ref b);
            }
            else
            {
                x = new DenseMatrixDouble(numberOfHarmBases, 1);
            }

            for (int i = 0; i < numberOfHarmBases; i++)
            {
                HarmonicCoffition[i] = x[i, 0];
            }

        }