public override void SetMeshData(RawMesh mesh, int[] vertexGroup, int groupCount, TriangleGroup triangleGroup) { //Calculate average for bias. var sum = new Vector3[groupCount]; var count = new int[groupCount]; for (int i = 0; i < mesh.Vertices.Length; ++i) { var g = vertexGroup[i]; sum[g] += mesh.Vertices[i]; count[g] += 1; } //Run qf solver _results = new Vector3[groupCount]; var c = new QFCoefficient(); for (int i = 0; i < groupCount; ++i) { c.Reset(); var nFaces = 0; var vertices = Enumerable.Range(0, vertexGroup.Length).Where(ii => vertexGroup[ii] == i).ToArray(); foreach (var tt in triangleGroup.GetExternalTriangles(i)) { var v1 = mesh.Vertices[mesh.Triangles[tt].Va]; var v2 = mesh.Vertices[mesh.Triangles[tt].Vb]; var v3 = mesh.Vertices[mesh.Triangles[tt].Vc]; var n = Vector3.Normalize(Vector3.Cross(v2 - v1, v3 - v1)); c.AddPlane(v1, n); nFaces += 1; } c.AddBias(sum[i] / count[i], nFaces * 0.01f + 0.01f); _results[i] = QFSolver.Solve(c); } }
private static Vector3 SolveQF(QFCoefficient coefficient) { const float constraint = 0.9f; const float constraintMax = 1 + constraint, constraintMin = 1 - constraint; var p = QFSolver.Solve(coefficient); var dx = Math.Abs(p.X - 1); var dy = Math.Abs(p.Y - 1); var dz = Math.Abs(p.Z - 1); var maxd = Math.Max(dx, Math.Max(dy, dz)); if (maxd <= constraint) { return(p); } Vector3 ret = new Vector3(); float val = float.PositiveInfinity; if (dx > constraint) { var nco = coefficient.Clone(); nco.EliminateDimension(0, p.X > 1 ? constraintMax : constraintMin); var np = SolveQF(nco); np.X = p.X > 1 ? constraintMax : constraintMin; var nval = nco.Evaluate(np); if (val > nval) { ret = np; val = nval; } } if (dy > constraint) { var nco = coefficient.Clone(); nco.EliminateDimension(1, p.Y > 1 ? constraintMax : constraintMin); var np = SolveQF(nco); np.Y = p.Y > 1 ? constraintMax : constraintMin; var nval = nco.Evaluate(np); if (val > nval) { ret = np; val = nval; } } if (dz > constraint) { var nco = coefficient.Clone(); nco.EliminateDimension(2, p.Z > 1 ? constraintMax : constraintMin); var np = SolveQF(nco); np.Z = p.Z > 1 ? constraintMax : constraintMin; var nval = nco.Evaluate(np); if (val > nval) { ret = np; val = nval; } } return(ret); }