/// <summary> /// Computes edge cost for triangle. /// </summary> /// <param name="t">The triangle.</param> private void ComputeEdgeCost(Triangle t) { ErrorMetric E12 = (ErrorMetric)t.m_Edge12.Tag; ErrorMetric E23 = (ErrorMetric)t.m_Edge23.Tag; ErrorMetric E31 = (ErrorMetric)t.m_Edge31.Tag; Vector3 V1; Vector3 V2; Vector3 V3; ErrorMetric.ComputeNewPosition(ref E12, out V1); ErrorMetric.ComputeNewPosition(ref E23, out V2); ErrorMetric.ComputeNewPosition(ref E31, out V3); E12.ProposedPoint = V1; E23.ProposedPoint = V2; E31.ProposedPoint = V3; WeightPolicy policy = (WeightPolicy.MiddlePoint | WeightPolicy.AverageTriangleArea | WeightPolicy.Optmized); OptimizeEdgeTarget(ref t.m_Vertex1, ref t.m_Vertex2, ref t.m_Edge12, policy); OptimizeEdgeTarget(ref t.m_Vertex2, ref t.m_Vertex3, ref t.m_Edge23, policy); OptimizeEdgeTarget(ref t.m_Vertex3, ref t.m_Vertex1, ref t.m_Edge31, policy); t.Cost = Math.Min(t.Edge12.Cost, Math.Min(t.Edge23.Cost, t.Edge31.Cost)); }
/// <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 = 0.0; Vector3 best; if (policy.HasFlag(WeightPolicy.Optmized) && Q.Optimize(out best)) { best = Q.ProposedPoint; min_cost = Q.Evaluate(best); } else { double min1 = Q.Evaluate(v1.Position); double min2 = Q.Evaluate(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.Evaluate(middle); if (cost_middle < min_cost) { min_cost = cost_middle; best = middle; } } } if (policy.HasFlag(WeightPolicy.AverageTriangleArea)) { min_cost /= Q.Area; } edge.Cost = 1.0/min_cost; Q.ProposedPoint = best; edge.Tag = (object)Q; }
/// <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> /// Computes edge cost for triangle. /// </summary> /// <param name="t">The triangle.</param> private void ComputeEdgeCost(Triangle t) { #if false Vector3 P1 = E12.ComputePosition(); Vector3 P2 = E23.ComputePosition(); Vector3 P3 = E31.ComputePosition(); #if !DISABLE_QEM_COMPUTING double C12 = E12.Evaluate(P1); double C23 = E23.Evaluate(P2); double C31 = E31.Evaluate(P3); if (double.IsNaN(C12)) { #if DISABLE_MEAN_POINT E12.ProposedPoint = t.Vertex1.Position; #else E12.ProposedPoint = Vector3Extension.Mean( t.Vertex1.Position, t.Vertex2.Position); #endif C12 = E12.Evaluate(E12.ProposedPoint); } else { E12.ProposedPoint = P1; } if (double.IsNaN(C23)) { #if DISABLE_MEAN_POINT E23.ProposedPoint = t.Vertex2.Position; #else E23.ProposedPoint = Vector3Extension.Mean( t.Vertex2.Position, t.Vertex3.Position); C23 = E23.Evaluate(E23.ProposedPoint); #endif } else { E23.ProposedPoint = P2; } if (double.IsNaN(C31)) { #if DISABLE_MEAN_POINT E31.ProposedPoint = t.Vertex3.Position; #else E31.ProposedPoint = Vector3Extension.Mean( t.Vertex3.Position, t.Vertex1.Position); C31 = E31.Evaluate(E31.ProposedPoint); #endif } else { E31.ProposedPoint = P3; } #else double C12 = E12.Evaluate(t.Vertex1.Position); double C23 = E23.Evaluate(t.Vertex2.Position); double C31 = E31.Evaluate(t.Vertex3.Position); #endif t.Edge12.Cost = C12; t.Edge23.Cost = C23; t.Edge31.Cost = C31; #else WeightPolicy policy = (WeightPolicy.Optmized | WeightPolicy.AverageTriangleArea); OptimizeEdgeTarget(ref t.m_Vertex1, ref t.m_Vertex2, ref t.m_Edge12, policy); OptimizeEdgeTarget(ref t.m_Vertex2, ref t.m_Vertex3, ref t.m_Edge23, policy); OptimizeEdgeTarget(ref t.m_Vertex3, ref t.m_Vertex1, ref t.m_Edge31, policy); #endif t.Cost = Math.Min(t.Edge12.Cost, Math.Min(t.Edge23.Cost, t.Edge31.Cost)); }