public void EndPolygon()
{
RequireState(ProcessingState.InPolygon);
processingState = ProcessingState.Dormant;
if (this.mesh == null)
{
if (!this.EdgeCallBackSet && this.callMesh == null)
{
/* Try some special code to make the easy cases go quickly
* (eg. convex polygons). This code does NOT handle multiple contours,
* intersections, edge flags, and of course it does not generate
* an explicit mesh either.
*/
if (RenderCache())
{
return;
}
}
EmptyCache(); /* could've used a label*/
}
/* Determine the polygon normal and project vertices onto the plane
* of the polygon.
*/
ProjectPolygon();
/* __gl_computeInterior( this ) computes the planar arrangement specified
* by the given contours, and further subdivides this arrangement
* into regions. Each region is marked "inside" if it belongs
* to the polygon, according to the rule given by this.windingRule.
* Each interior region is guaranteed to be monotone.
*/
ActiveRegion.ComputeInterior(this);
bool rc = true;
/* If the user wants only the boundary contours, we throw away all edges
* except those which separate the interior from the exterior.
* Otherwise we tessellate all the regions marked "inside".
*/
if (this.boundaryOnly)
{
rc = this.mesh.SetWindingNumber(1, true);
}
else
{
rc = this.mesh.TessellateInterior();
}
this.mesh.CheckMesh();
if (this.callBegin != null || this.callEnd != null
|| this.callVertex != null || this.callEdgeFlag != null)
{
if (this.boundaryOnly)
{
RenderBoundary(mesh); /* output boundary contours */
}
else
{
RenderMesh(mesh); /* output strips and fans */
}
}
if (this.callMesh != null)
{
/* Throw away the exterior faces, so that all faces are interior.
* This way the user doesn't have to check the "inside" flag,
* and we don't need to even reveal its existence. It also leaves
* the freedom for an implementation to not generate the exterior
* faces in the first place.
*/
mesh.DiscardExterior();
callMesh(mesh); /* user wants the mesh itself */
this.mesh = null;
return;
}
this.mesh = null;
}