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); }
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); }
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); }
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); }
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); }
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); }
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); }
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; }