/******************************************************************************
* Poly_cln.c - Clean polygonal data.					      *
*******************************************************************************
* (C) Gershon Elber, Technion, Israel Institute of Technology                 *
*******************************************************************************
* Written by Gershon Elber, June 1993.					      *
******************************************************************************/

#include "irit_sm.h"
#include "allocate.h"
#include "iritprsr.h"
#include "poly_cln.h"

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Routine to clean up polygons - delete zero length edges, and polygons    M
* with less than 3 vertices.						     M
*                                                                            *
* PARAMETERS:                                                                M
*   PPolygons:    List of polygons to clean, in place.                       M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   CleanUpPolygonList, zero length edges, cleaning                          M
*****************************************************************************/
void CleanUpPolygonList(IPPolygonStruct **PPolygons)
{
    IPPolygonStruct *PPHead, *PPLast;
    IPVertexStruct *PVHead, *PVTemp, *PVNext;

    PPLast = PPHead = *PPolygons;

    while (PPHead != NULL) {
	PVHead = PVTemp = PPHead -> PVertex;
	/* Look for zero length edges (V == V -> Pnext): */
	do {
	    PVNext = PVTemp -> Pnext;
	    if (PT_APX_EQ(PVTemp -> Coord, PVNext -> Coord)) { /* Del PVNext.*/
		PVTemp -> Pnext = PVTemp -> Pnext -> Pnext;
		PVNext -> Pnext = NULL;			/* Free only PVNext. */
		if (PVHead == PVNext) {	      /* If we actually kill header. */
		    PPHead -> PVertex = PVHead = PVTemp;
		    break;
		}
		IPFreeVertexList(PVNext);
	    }
	    else
		PVTemp = PVTemp -> Pnext;
	}
	while (PVTemp != NULL && PVTemp != PVHead);

	/* Now test if at list 3 vertices in polygon, otherwise delete it:   */
	if (PVHead == PVHead -> Pnext ||		 /* One vertex only. */
	    PVHead == PVHead -> Pnext -> Pnext) {      /* Two vertices only. */
	    if (PPHead == *PPolygons) {
		*PPolygons = (*PPolygons) -> Pnext;
		IPFreePolygon(PPHead);
		PPHead = (*PPolygons);
	    }
	    else {
		PPLast -> Pnext = PPHead -> Pnext;
		IPFreePolygon(PPHead);
		PPHead = PPLast -> Pnext;
	    }
	}
	else {
	    PPLast = PPHead;
	    PPHead = PPHead -> Pnext;
	}
    }
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Routine to clean up polylines of zero length.			     M
*                                                                            *
* PARAMETERS:                                                                M
*   PPolylines:    List of polylines to clean, in place.                     M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   CleanUpPolylineList, zero length polyline, cleaning                      M
*****************************************************************************/
void CleanUpPolylineList(IPPolygonStruct **PPolylines)
{
    IPPolygonStruct
	*Poly = *PPolylines;

    /* Remove empty sized polylines. */
    while (Poly != NULL &&
	   (Poly -> PVertex == NULL ||
	    Poly -> PVertex -> Pnext == NULL)) {
	*PPolylines = (*PPolylines) -> Pnext;
	IPFreePolygon(Poly);
	Poly = *PPolylines;
    }

    if (Poly && Poly -> Pnext) {
	while (Poly -> Pnext != NULL) {
	    if (Poly -> Pnext -> PVertex == NULL ||
		Poly -> Pnext -> PVertex -> Pnext == NULL) {
		IPPolygonStruct
		    *TmpPoly = Poly -> Pnext;

		Poly -> Pnext = TmpPoly -> Pnext;
		IPFreePolygon(TmpPoly);
	    }
	    else
		Poly = Poly ->Pnext;
	}
    }
}
