Beispiel #1
0
        // TODO: Euler operators from http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/HalfedgeDS_ref/Class_HalfedgeDS_decorator.html#Cross_link_anchor_573

        /// <summary>
        /// Split the face across a diagonal between two vertices a and b.
        /// The returned edge has a pair of faces accessible through its
        /// Faces property.  edge.Faces.First will always be the new face
        /// instance. edge.Faces.Second will always be the original reduced
        /// face instance that was supplied as a parameter.
        /// </summary>
        /// <param name="face">The face to be split</param>
        /// <param name="a">The start of the diagonal</param>
        /// <param name="b">The end of the diagonal</param>
        /// <returns></returns>
        public TEdge SplitFace(FaceBase face, VertexBase a, VertexBase b)
        {
            // Two vertices alone are not sufficient to determine a
            // unique face, so the face is also supplied. (The two
            // vertices may lie on the same boundary between two faces.
            Half p = a.FindHalfEdge(half => (half.Face == face));
            Half q = b.FindHalfEdge(half => (half.Face == face));

            Half h = p.previous;
            Half g = q.previous;

            return(SplitFace(h, g));
        }
Beispiel #2
0
 /// <summary>
 /// Creates a face that is a copy of the supplied face.  The new face
 /// will have the same half edge as the original face, but the half-edge
 /// will not be connected to this face.  After using this constructor,
 /// this faces half edge should be reassigned.
 /// </summary>
 /// <param name="other">The face to copy</param>
 private FaceBase(FaceBase other) :
     this()
 {
     half = other.half;
 }
Beispiel #3
0
        /// <summary>
        /// Euler operator: Split the face incident to h and g into two faces with a new
        /// diagonal between the two vertices denoted by h and g respectively.
        /// The new face is to the right of the diagonal, the old face to the left.
        /// </summary>
        /// <param name="h">A half-edge indicent to a face to be split</param>
        /// <param name="g">A half-edge incident to a face to be split</param>
        /// <returns>The new diagonal</returns>
        public TEdge SplitFace(Half h, Half g)
        {
            #if DEBUG
            int euler = Euler;
            #endif

            if (h.Face != g.Face)
            {
                throw new ArgumentException();
            }

            FaceBase originalFace = h.Face;
            TFace    secondFace   = (TFace)h.Face.Clone();

            // Re-assign the half-edges to which both faces are connected
            originalFace.half = h;
            secondFace.half   = g;

            // Re-assign half-edges after h upto g inclusive to the new face
            Half begin   = h.next;
            Half current = begin;
            do
            {
                Debug.Assert(current != null);
                Debug.Assert(current.Face == originalFace);
                current.Face = secondFace;
                current      = current.next;
            }while (current != g.next);

            // Insert a new edge and half-edge pair
            // Allocate data
            TEdge edge       = new TEdge();
            Half  fromToHalf = new Half();
            Half  toFromHalf = new Half();

            // Initialize data
            edge.half = fromToHalf;

            fromToHalf.next     = h.next;
            fromToHalf.previous = g;
            fromToHalf.pair     = toFromHalf;
            fromToHalf.Source   = g.Target;
            fromToHalf.Edge     = edge;
            fromToHalf.Face     = secondFace;

            toFromHalf.next     = g.next;
            toFromHalf.previous = h;
            toFromHalf.pair     = fromToHalf;
            toFromHalf.Source   = h.Target;
            toFromHalf.Edge     = edge;
            toFromHalf.Face     = originalFace;

            h.next.previous = fromToHalf;
            h.next          = toFromHalf;

            g.next.previous = toFromHalf;
            g.next          = fromToHalf;



            edges.Add(edge);
            faces.Add(secondFace);

            #if DEBUG
            // Assert the Euler invariant
            Debug.Assert(euler == Euler);
            #endif

            return(edge);
        }