// return point that minimizes quadric error for edge [ea,eb] Vector3d OptimalPoint(QuadricError q, int ea, int eb) { if (MinimizeQuadricPositionError == false) { return((mesh.GetVertex(ea) + mesh.GetVertex(eb)) * 0.5); } else { try { return(q.OptimalPoint()); } catch { // degenerate matrix, evaluate quadric at edge end and midpoints // (could do line search here...) Vector3d va = mesh.GetVertex(ea); Vector3d vb = mesh.GetVertex(eb); Vector3d c = (va + vb) * 0.5; double fa = q.Evaluate(va); double fb = q.Evaluate(vb); double fc = q.Evaluate(c); double m = MathUtil.Min(fa, fb, fc); if (m == fa) { return(va); } else if (m == fb) { return(vb); } return(c); } } }
// return point that minimizes quadric error for edge [ea,eb] protected Vector3d OptimalPoint(int eid, ref QuadricError q, int ea, int eb) { // if we would like to preserve boundary, we need to know that here // so that we properly score these edges if (HaveBoundary && PreserveBoundaryShape) { if (mesh.IsBoundaryEdge(eid)) { return((mesh.GetVertex(ea) + mesh.GetVertex(eb)) * 0.5); } else { if (IsBoundaryV(ea)) { return(mesh.GetVertex(ea)); } else if (IsBoundaryV(eb)) { return(mesh.GetVertex(eb)); } } } // [TODO] if we have constraints, we should apply them here, for same reason as bdry above... if (MinimizeQuadricPositionError == false) { return(project((mesh.GetVertex(ea) + mesh.GetVertex(eb)) * 0.5)); } else { Vector3d result = Vector3d.Zero; if (q.OptimalPoint(ref result)) { return(project(result)); } // degenerate matrix, evaluate quadric at edge end and midpoints // (could do line search here...) Vector3d va = mesh.GetVertex(ea); Vector3d vb = mesh.GetVertex(eb); Vector3d c = project((va + vb) * 0.5); double fa = q.Evaluate(ref va); double fb = q.Evaluate(ref vb); double fc = q.Evaluate(ref c); double m = MathUtil.Min(fa, fb, fc); if (m == fa) { return(va); } else if (m == fb) { return(vb); } return(c); } }