/*****************************************************************************
*   Default surface drawing routine common to graphics drivers.		     *
*									     *
* Written by:  Gershon Elber				Ver 0.1, June 1993.  *
*****************************************************************************/

#include "irit_sm.h"
#include "iritprsr.h"
#include "allocate.h"
#include "attribut.h"
#include "cagd_lib.h"
#include "symb_lib.h"
#include "ip_cnvrt.h"
#include "iritgrap.h"

/*****************************************************************************
* DESCRIPTION:                                                               M
* Draw a single trimmed surface object using current modes and		     M
* transformations.							     M
*   Piecewise linear approximation is cashed under "_isoline" and "_ctlmesh" M
* attributes of PObj. Polygonal approximation is saved under "_polygons".    M
*                                                                            *
* PARAMETERS:                                                                M
*   PObj:     A trimmed surface object to draw.                              M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   IGDrawTrimSrf                                                            M
*****************************************************************************/
void IGDrawTrimSrf(IPObjectStruct *PObj)
{
    IPObjectStruct *PObjPolylines, *PObjCtlMesh, *PObjPolygons;
    IPPolygonStruct *PPolylines, *PCtlMesh, *PPolygonTemp;

    if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_isoline")) == NULL &&
	IGGlblNumOfIsolines > 0) {
	TrimSrfStruct *TrimSrf,
	    *TrimSrfs = PObj -> U.TrimSrfs;

	PObjPolylines = IPAllocObject("", IP_OBJ_POLY, NULL);
	PObjPolylines -> Attrs = AttrCopyAttributes(PObj -> Attrs);
	IP_SET_POLYLINE_OBJ(PObjPolylines);
	for (TrimSrf = TrimSrfs; TrimSrf != NULL; TrimSrf = TrimSrf -> Pnext) {
	    int NumOfIso[2];

	    NumOfIso[0] = -IGGlblNumOfIsolines;
	    NumOfIso[1] = -IGGlblNumOfIsolines;
	    PPolylines = IritTrimSrf2Polylines(TrimSrf, NumOfIso,
					       IGGlblSamplesPerCurve,
					       IGGlblPolylineOptiApprox,
					       TRUE, TRUE);

	    if (PPolylines != NULL) {
		for (PPolygonTemp = PPolylines;
		     PPolygonTemp -> Pnext;
		     PPolygonTemp = PPolygonTemp -> Pnext);
		PPolygonTemp -> Pnext = PObjPolylines -> U.Pl;
		PObjPolylines -> U.Pl = PPolylines;
	    }
	}
	AttrSetObjectObjAttrib(PObj, "_isoline", PObjPolylines, FALSE);
    }

    if (IGGlblDrawSurfacePoly || IGGlblDrawSolid) {
	if ((PObjPolygons = AttrGetObjectObjAttrib(PObj, "_polygons"))
								    == NULL) {
	    fprintf(stderr,
		    "POLYGONIZATION OF TRIMMED SURFACE IS NOT SUPPORTED\n");
	    return;
	}

	IGDrawPoly(PObjPolygons);
    }
    else if (PObjPolylines != NULL)
        IGDrawPoly(PObjPolylines);

    if (IGGlblDrawSurfaceMesh) {
	if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_ctlmesh"))
								== NULL) {
	    TrimSrfStruct *TrimSrf,
		*TrimSrfs = PObj -> U.TrimSrfs;

	    PObjCtlMesh = IPAllocObject("", IP_OBJ_POLY, NULL);
	    PObjCtlMesh -> Attrs = AttrCopyAttributes(PObj -> Attrs);
	    IP_SET_POLYLINE_OBJ(PObjCtlMesh);
	    for (TrimSrf = TrimSrfs;
		 TrimSrf != NULL;
		 TrimSrf = TrimSrf -> Pnext) {
		PCtlMesh = IritTrimSrf2CtlMesh(TrimSrf);

		for (PPolygonTemp = PCtlMesh;
		     PPolygonTemp -> Pnext;
		     PPolygonTemp = PPolygonTemp -> Pnext);
		PPolygonTemp -> Pnext = PObjCtlMesh -> U.Pl;
		PObjCtlMesh -> U.Pl = PCtlMesh;
	    }
	    AttrSetObjectObjAttrib(PObj, "_ctlmesh", PObjCtlMesh, FALSE);
	}

	IGDrawPoly(AttrGetObjectObjAttrib(PObj, "_ctlmesh"));
    }
}
