Exemplo n.º 1
0
        // v1 and v2 successive vertices must be along a boundary, with the Halfedge from v1 to v2 having no face (on the left).
        // Then we create a new vertex 'outside' the boundary, create new edges and a face
        //   \  /        /
        //    \/  old e / old edge
        //  v2 o <-----o v1
        //      \ new /
        //   new \ f / new edge
        //  edge  \ /    no face here...
        //         o v3
        public Face CreateTriangle(Vertex v1,
                                   Vertex v2,
                                   TVertexTraits vt3 = default(TVertexTraits),
                                   TFaceTraits ft    = default(TFaceTraits))
        {
            Halfedge e12 = v1.HalfedgeTo(v2);
            Halfedge e21 = e12.Opposite;

            // Checks adjacency condition
            if (e12 == null)
            {
                throw new InvalidOperationException("v1 and v2 must be neighbors - but no Halfedge found!");
            }
            if (e12.Face != null)
            {
                throw new InvalidOperationException("Halfedge from v1 to v2 must be a boundary - but a face was found for the Halfedge!");
            }

            var v3 = CreateVertex(vt3);

            var e23 = CreateEdgeInvalid(v2, v3);
            var e32 = e23.Opposite;
            var e31 = CreateEdgeInvalid(v3, v1);
            var e13 = e31.Opposite;

            // New vertex won't have an Outgoing yet - e32 is good - it will be a boundary Halfedge
            v3.Outgoing = e32;
            // Fix v1 Outgoing to maintain Vertex boundary condition
            v1.Outgoing = e13;

            // This is the tricky part - updating the Halfedge adjacencies
            e32.Next          = e12.Next;
            e13.Previous      = e12.Previous;
            e12.Previous.Next = e13;
            e12.Next.Previous = e32;

            e12.Next     = e23;
            e12.Previous = e31;

            e32.Previous = e13;
            e13.Next     = e32;

            e23.Previous = e12;
            e23.Next     = e31;

            e31.Previous = e23;
            e31.Next     = e12;

            // This will go around fixing up the faces along the ring of halfedges.
            var f = CreateFace(e12, ft);

            e12.AssertValid();
            e21.AssertValid();
            e23.AssertValid();
            e32.AssertValid();
            e31.AssertValid();
            e13.AssertValid();
            AssertValid();

            return(f);
        }