Exemplo n.º 1
0
        /// <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);
        }