FaceCount MaximumStrip(HalfEdge eOrig)
{
/* Here we are looking for a maximal strip that contains the vertices
* eOrig.Org, eOrig.Dst, eOrig.Lnext.Dst (in that order or the
* reverse, such that all triangles are oriented CCW).
*
* Again we walk forward and backward as far as possible. However for
* strips there is a twist: to get CCW orientations, there must be
* an *even* number of triangles in the strip on one side of eOrig.
* We walk the strip starting on a side with an even number of triangles;
* if both side have an odd number, we are forced to shorten one side.
*/
FaceCount newFace = new FaceCount(0, null, RenderStrip);
int headSize = 0, tailSize = 0;
Face trail = null;
HalfEdge e, eTail, eHead;
for (e = eOrig; !e.leftFace.Marked(); ++tailSize, e = e.nextEdgeCCWAroundOrigin)
{
Face.AddToTrail(ref e.leftFace, ref trail);
++tailSize;
e = e.Dprev;
if (e.leftFace.Marked()) break;
Face.AddToTrail(ref e.leftFace, ref trail);
}
eTail = e;
for (e = eOrig; !e.rightFace.Marked(); ++headSize, e = e.Dnext)
{
Face f = e.rightFace;
Face.AddToTrail(ref f, ref trail);
e.rightFace = f;
++headSize;
e = e.Oprev;
if (e.rightFace.Marked()) break;
f = e.rightFace;
Face.AddToTrail(ref f, ref trail);
e.rightFace = f;
}
eHead = e;
newFace.size = tailSize + headSize;
if (IsEven(tailSize))
{
newFace.eStart = eTail.otherHalfOfThisEdge;
}
else if (IsEven(headSize))
{
newFace.eStart = eHead;
}
else
{
/* Both sides have odd length, we must shorten one of them. In fact,
* we must start from eHead to guarantee inclusion of eOrig.Lface.
*/
--newFace.size;
newFace.eStart = eHead.nextEdgeCCWAroundOrigin;
}
Face.FreeTrail(ref trail);
return newFace;
}