/// <summary> /// Optimizes edge target. /// </summary> /// <param name="v1">The source edge vertex.</param> /// <param name="v2">The target edge vertex.</param> /// <param name="edge">The edge additional params.</param> /// <param name="policy">The used policy.</param> private void OptimizeEdgeTarget(ref Vertex v1, ref Vertex v2, ref Triangle.Edge edge, WeightPolicy policy) { ErrorMetric Q = (ErrorMetric)edge.Tag; double min_cost = double.MaxValue; Vector3 best; if (policy.HasFlag(WeightPolicy.Optmized) && Q.Optimize(out best)) { Q.ProposedPoint = best; min_cost = Q.VertexError(best); } else { double min1 = Q.VertexError(v1.Position); double min2 = Q.VertexError(v2.Position); if (min1 < min2) { min_cost = min1; best = v1.Position; } else { min_cost = min2; best = v2.Position; } if (policy.HasFlag(WeightPolicy.MiddlePoint)) { Vector3 middle = Vector3Extension.Mean(v1.Position, v2.Position); double cost_middle = Q.VertexError(middle); if (cost_middle < min_cost) { min_cost = cost_middle; best = middle; } } } if (policy.HasFlag(WeightPolicy.AverageTriangleArea)) { min_cost /= Q.Area; } edge.Cost = -min_cost; Q.ProposedPoint = best; edge.Tag = (object)Q; }
/// <summary> /// Tries to search best candidate for remeshing. /// </summary> /// <param name="mesh">The mesh.</param> /// <param name="v1">The source vertex.</param> /// <param name="v2">The source vertex.</param> /// <param name="edge">The edge additional informations.</param> /// <returns>true when successful, false otherwise.</returns> private bool SearchBestCandidate(ref Mesh mesh, out Vertex v1, out Vertex v2, out Triangle.Edge edge) { var min = mesh.Triangles.Min(); if (min != null) { if (min.Edge12.Cost < min.Edge23.Cost) { if (min.Edge12.Cost < min.Edge31.Cost) { v1 = min.Vertex1; v2 = min.Vertex2; edge = min.Edge12; } else { v1 = min.Vertex3; v2 = min.Vertex1; edge = min.Edge31; } } else { if (min.Edge23.Cost < min.Edge31.Cost) { v1 = min.Vertex2; v2 = min.Vertex3; edge = min.Edge23; } else { v1 = min.Vertex3; v2 = min.Vertex1; edge = min.Edge31; } } return(true); } v1 = null; v2 = null; edge = null; return(false); }