/// <summary> /// This function tries to remove vertices from loop to hit TargetVtxCount. We call this /// when polygon-insertion returns more vertices than polygon. Strategy is to try to find /// co-linear vertices, ie that can be removed without changing shape. If that fails, /// we remove vertices that result in smallest length change (probably should do proper simplification /// here instead). /// /// Basically this is to handle failures in MeshInsertUVPolyCurve.Simplify(), which sometimes /// fails to remove extra vertices because it would case triangle flips. Here we don't /// care about triangle flips. /// /// Note that if the input polygon had splits on edges, this function would remove those /// vertices. Which is not ideal. /// </summary> protected EdgeLoop simplify_loop(DMesh3 mesh, EdgeLoop loop, int TargetVtxCount) { while (loop.VertexCount > TargetVtxCount) { DCurve3 curve = loop.ToCurve(); DMesh3.EdgeCollapseInfo cinfo; int NV = loop.VertexCount; for (int k = 1; k <= NV; ++k) { int prevv = k - 1; int curv = k % NV; int nextv = (k + 1) % NV; //if (curve[prevv].Distance(curve[curv]) < 0.0001 || // curve[nextv].Distance(curve[curv]) < 0.0001) // f3.DebugUtil.Log("DEGENERATE!!"); double angle = curve.OpeningAngleDeg(curv); if (angle > 179) { MeshResult r = mesh.CollapseEdge(loop.Vertices[prevv], loop.Vertices[curv], out cinfo); mesh.SetVertex(loop.Vertices[prevv], curve[prevv]); if (r == MeshResult.Ok) { goto done_this_iter; } else { f3.DebugUtil.Log("collinear collapse failed!"); } } } f3.DebugUtil.Log("Did not find collinear vert..."); int i_shortest = -1; double shortest_len = double.MaxValue; for (int k = 1; k <= NV; ++k) { int prevv = k - 1; int curv = k % NV; int nextv = (k + 1) % NV; Vector3d pc = curve[curv] - curve[prevv]; Vector3d pn = curve[nextv] - curve[curv]; double len_sum = pc.Length + pn.Length; if (len_sum < shortest_len) { i_shortest = curv; shortest_len = len_sum; } } if (i_shortest != -1) { int curv = i_shortest; int prevv = (curv == 0) ? NV - 1 : curv - 1; int nextv = (curv + 1) % NV; Vector3d pc = curve[curv] - curve[prevv]; Vector3d pn = curve[nextv] - curve[curv]; int iWhich = (pc.Length < pn.Length) ? prevv : nextv; MeshResult r = mesh.CollapseEdge(loop.Vertices[iWhich], loop.Vertices[curv], out cinfo); if (r == MeshResult.Ok) { goto done_this_iter; } else { f3.DebugUtil.Log("shortest failed!"); } } f3.DebugUtil.Log("Did not find shortest vert..."); // if we didn't find a vert to remove yet, just arbitrarily remove first one int v0 = loop.Vertices[0], v1 = loop.Vertices[1]; MeshResult result = mesh.CollapseEdge(v1, v0, out cinfo); done_this_iter: List <int> new_verts = new List <int>(); for (int k = 0; k < loop.Vertices.Count(); ++k) { if (mesh.IsVertex(loop.Vertices[k])) { new_verts.Add(loop.Vertices[k]); } } loop = EdgeLoop.FromVertices(mesh, new_verts); } return(loop); }