public double[][] SolveSystem(double[] lapWeight, double[] posWeight) { int vn = mesh.VertexCount; int fn = mesh.FaceCount; double[][] pos = new double[3][]; pos[0] = new double[vn]; pos[1] = new double[vn]; pos[2] = new double[vn]; // for (int i = 0; i < simplifiedMeshes[0].Count; i++) // { // int j = simplifiedMeshes[0][i].index; // pos[0][j] = mesh.VertexPos[j * 3]; // pos[1][j] = mesh.VertexPos[j * 3 + 1]; // pos[2][j] = mesh.VertexPos[j * 3 + 2]; // } for (int i = 0; i < vn; i++) { int j = i; pos[0][j] = mesh.VertexPos[j * 3]; pos[1][j] = mesh.VertexPos[j * 3 + 1]; pos[2][j] = mesh.VertexPos[j * 3 + 2]; } this.originalArea = new double[vn]; for (int i = 0; i < vn; i++) { originalArea[i] = 0; } 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]; double area = mesh.ComputeFaceArea(i); originalArea[c1] += area; originalArea[c2] += area; originalArea[c3] += area; } double weightAdjustment = Math.Pow((simplificationRatio), simplifiedMeshes.Count - 1); weightAdjustment = 1.0; for (int level = 0; level < simplifiedMeshes.Count; level++) { ColMatrix colA = BuildMatrixA(simplifiedMeshes[level], faceRecords[level], lapWeight, posWeight, weightAdjustment); CCSMatrix ccsATA = MultiplyATA(colA); //CCSMatrix ccsA = new CCSMatrix(A); //RowBasedMatrix rbA = new RowBasedMatrix(A); A = null; List <VertexRecord> records = simplifiedMeshes[level]; int n = records.Count; double[] x = new double[n]; double[] b = new double[n * 2]; double[] ATb = new double[n]; double[] inv = null; void * solver = null; string s = ""; s += weightAdjustment.ToString(); //weightAdjustment /= (simplificationRatio); if (level == 0) { solver = Factorization(ccsATA); if (solver == null) { throw new Exception(); } } for (int i = 0; i < 3; i++) { for (int j = 0; j < n; j++) { b[j] = 0; int k = records[j].index; b[j + n] = mesh.VertexPos[k * 3 + i] * posWeight[k] * (currentArea[j] / originalArea[k]); //b[j + n] = mesh.VertexPos[k * 3 + i] * posWeight[k]; //x[j] = mesh.VertexPos[k * 3 + i]; x[j] = pos[i][k]; } colA.PreMultiply(b, ATb); if (level == 0) { fixed(double *_x = x, _ATb = ATb) Solve(solver, _x, _ATb); } else { int iter = colA.ATACG(x, ATb, convergeRatio, n); s += " " + iter; } //if (level == 0) for (int j = 0; j < n; j++) { int k = records[j].index; pos[i][k] = x[j]; //Program.PrintText(x[j].ToString()); } } if (solver != null) { FreeSolver(solver); solver = null; } if (level < simplifiedMeshes.Count - 1) { //Program.PrintText(collapsedRecords[level].Count.ToString()); foreach (EdgeRecord rec in collapsedRecords[level]) { Vector3d p = new Vector3d(); foreach (int j in rec.adjV) { p.x += pos[0][j]; p.y += pos[1][j]; p.z += pos[2][j]; } pos[0][rec.vIndex] = p.x /= rec.adjV.Count; pos[1][rec.vIndex] = p.y /= rec.adjV.Count; pos[2][rec.vIndex] = p.z /= rec.adjV.Count; } } Program.PrintText(s); } return(pos); }
public double[][] SolveSystem(double[] lapWeight, double[] posWeight) { #region Init Variables int vn = mesh.VertexCount; int fn = mesh.FaceCount; double[][] pos = new double[3][]; pos[0] = new double[vn]; pos[1] = new double[vn]; pos[2] = new double[vn]; for (int i = 0, j = 0; i < vn; i++, j += 3) { pos[0][i] = mesh.VertexPos[j]; pos[1][i] = mesh.VertexPos[j + 1]; pos[2][i] = mesh.VertexPos[j + 2]; } #endregion for (int level = 0; level < resolutions.Count; level++) { Resolution r = resolutions[level]; // build matrix ColMatrix colA = BuildMatrixA(r, lapWeight, posWeight); CCSMatrix ccsATA = MultiplyATA(colA); string s = "#: " + r.vertexList.Length + " iter: "; // solve system int n = r.vertexList.Length; double[] x = new double[n]; double[] b = new double[n * 2]; double[] ATb = new double[n]; void * solver = null; if (level == 0) { solver = Factorization(ccsATA); } for (int i = 0; i < 3; i++) { for (int j = 0; j < n; j++) { b[j] = 0; int k = r.vertexList[j]; //b[j + n] = mesh.VertexPos[k * 3 + i] * posWeight[k] * (currentArea[j] / originalArea[k]); b[j + n] = mesh.VertexPos[k * 3 + i] * posWeight[k]; //x[j] = mesh.VertexPos[k * 3 + i]; x[j] = pos[i][k]; } colA.PreMultiply(b, ATb); if (level == 0) fixed(double *_x = x, _ATb = ATb) Solve(solver, _x, _ATb); else { int iter = colA.ATACG(x, ATb, convergeRatio, n); s += " " + iter; } //if (level == resolutions.Count-1) for (int j = 0; j < n; j++) { pos[i][r.vertexList[j]] = x[j]; } } Program.PrintText(s); // interpolation solution if (level < resolutions.Count - 1) { for (int i = 0; i < r.collapsedIndex.Length; i++) { int index = r.collapsedIndex[i]; Vector3d p = new Vector3d(); double totWeight = 0; foreach (int adj in r.weight[i].Keys) { double w = r.weight[i][adj]; p.x += pos[0][adj] * w; p.y += pos[1][adj] * w; p.z += pos[2][adj] * w; totWeight += w; } pos[0][index] = p.x /= totWeight; pos[1][index] = p.y /= totWeight; pos[2][index] = p.z /= totWeight; } } } return(pos); }