예제 #1
0
        public MeshResult FlipEdge(int vA, int vB, out EdgeFlipInfo flip)
        {
            int eid = find_edge(vA, vB);

            if (eid == InvalidID)
            {
                flip = new EdgeFlipInfo();
                return(MeshResult.Failed_NotAnEdge);
            }
            return(FlipEdge(eid, out flip));
        }
예제 #2
0
        public MeshResult FlipEdge(int eab, out EdgeFlipInfo flip)
        {
            flip = new EdgeFlipInfo();
            if (!IsEdge(eab))
            {
                return(MeshResult.Failed_NotAnEdge);
            }
            if (edge_is_boundary(eab))
            {
                return(MeshResult.Failed_IsBoundaryEdge);
            }

            // find oriented edge [a,b], tris t0,t1, and other verts c in t0, d in t1
            int eab_i = 4 * eab;
            int a = edges[eab_i], b = edges[eab_i + 1];
            int t0 = edges[eab_i + 2], t1 = edges[eab_i + 3];

            int[] T0tv = GetTriangle(t0).array;
            int[] T1tv = GetTriangle(t1).array;
            int   c    = IndexUtil.orient_tri_edge_and_find_other_vtx(ref a, ref b, T0tv);
            int   d    = IndexUtil.find_tri_other_vtx(a, b, T1tv);

            if (c == InvalidID || d == InvalidID)
            {
                return(MeshResult.Failed_BrokenTopology);
            }

            int flipped = find_edge(c, d);

            if (flipped != InvalidID)
            {
                return(MeshResult.Failed_FlippedEdgeExists);
            }

            // find edges bc, ca, ad, db
            int ebc = find_tri_neighbour_edge(t0, b, c);
            int eca = find_tri_neighbour_edge(t0, c, a);
            int ead = find_tri_neighbour_edge(t1, a, d);
            int edb = find_tri_neighbour_edge(t1, d, b);

            // update triangles
            set_triangle(t0, c, d, b);
            set_triangle(t1, d, c, a);

            // update edge AB, which becomes flipped edge CD
            set_edge_vertices(eab, c, d);
            set_edge_triangles(eab, t0, t1);
            int ecd = eab;

            // update the two other edges whose triangle nbrs have changed
            if (replace_edge_triangle(eca, t0, t1) == -1)
            {
                throw new ArgumentException("DMesh3.FlipEdge: first replace_edge_triangle failed");
            }
            if (replace_edge_triangle(edb, t1, t0) == -1)
            {
                throw new ArgumentException("DMesh3.FlipEdge: second replace_edge_triangle failed");
            }

            // update triangle nbr lists (these are edges)
            set_triangle_edges(t0, ecd, edb, ebc);
            set_triangle_edges(t1, ecd, eca, ead);

            // remove old eab from verts a and b, and decrement ref counts
            if (vertex_edges[a].Remove(eab) == false)
            {
                throw new ArgumentException("DMesh3.FlipEdge: first vertex_edges remove failed");
            }
            if (vertex_edges[b].Remove(eab) == false)
            {
                throw new ArgumentException("DMesh3.FlipEdge: second vertex_edges remove failed");
            }
            vertices_refcount.decrement(a);
            vertices_refcount.decrement(b);
            if (IsVertex(a) == false || IsVertex(b) == false)
            {
                throw new ArgumentException("DMesh3.FlipEdge: either a or b is not a vertex?");
            }

            // add new edge ecd to verts c and d, and increment ref counts
            vertex_edges[c].Add(ecd);
            vertex_edges[d].Add(ecd);
            vertices_refcount.increment(c);
            vertices_refcount.increment(d);

            // success! collect up results
            flip.eID = eab;
            flip.v0  = a; flip.v1 = b;
            flip.ov0 = c; flip.ov1 = d;
            flip.t0  = t0; flip.t1 = t1;

            updateTimeStamp(true);
            return(MeshResult.Ok);
        }