/*****************************************************************************
*   Default curve drawing routine common to graphics drivers.		     *
******************************************************************************
* (C) Gershon Elber, Technion, Israel Institute of Technology                *
******************************************************************************
* Written by:  Gershon Elber				Ver 0.1, June 1993.  *
*****************************************************************************/

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

/*****************************************************************************
* DESCRIPTION:                                                               M
* Draw a single Curve object using current modes and transformations.	     M
*   Curve must be with either E3 or P3 point type and must be a NURB curve.  M
*   Piecewise linear approximation is cashed under "_isoline" and "_ctlpoly" M
* attributes of PObj.							     M
*                                                                            *
* PARAMETERS:                                                                M
*   PObj:     A curve object to draw.                                        M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   IGDrawCurve                                                              M
*****************************************************************************/
void IGDrawCurve(IPObjectStruct *PObj)
{
    IPObjectStruct *PObjPolylines, *PObjCtlPolys;

    if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_isoline")) == NULL) {
	CagdCrvStruct *Crv,
	    *Crvs = PObj -> U.Crvs;
	IPPolygonStruct *PPolyline;

	PObjPolylines = IPAllocObject("", IP_OBJ_POLY, NULL);
	PObjPolylines -> Attrs = AttrCopyAttributes(PObj -> Attrs);
	IP_SET_POLYLINE_OBJ(PObjPolylines);
	for (Crv = Crvs; Crv != NULL; Crv = Crv -> Pnext) {
	    PPolyline = IritCurve2Polylines(Crv, IGGlblSamplesPerCurve,
					    IGGlblPolylineOptiApprox);

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

    if (PObjPolylines != NULL) {
	IGDrawPoly(PObjPolylines);

	if (!IGGlblCacheGeom)
	    IPFreeObject(PObjPolylines);
    }

    if (IGGlblDrawSurfaceMesh) {
	if ((PObjCtlPolys = AttrGetObjectObjAttrib(PObj, "_ctlpoly"))
								== NULL) {
	    CagdCrvStruct *Crv,
		*Crvs = PObj -> U.Crvs;
	    IPPolygonStruct *PCtlPoly;

	    PObjCtlPolys = IPAllocObject("", IP_OBJ_POLY, NULL);
	    PObjCtlPolys -> Attrs = AttrCopyAttributes(PObj -> Attrs);
	    IP_SET_POLYLINE_OBJ(PObjCtlPolys);
	    for (Crv = Crvs; Crv != NULL; Crv = Crv -> Pnext) {
		PCtlPoly = IritCurve2CtlPoly(Crv);

		PCtlPoly -> Pnext = PObjCtlPolys -> U.Pl;
		PObjCtlPolys -> U.Pl = PCtlPoly;
	    }
	    if (IGGlblCacheGeom)
		AttrSetObjectObjAttrib(PObj, "_ctlpoly", PObjCtlPolys, FALSE);
	}

	if (PObjCtlPolys != NULL) {
	    IGDrawPoly(PObjCtlPolys);

	    if (!IGGlblCacheGeom)
		IPFreeObject(PObjCtlPolys);
	}
    }
}
