/*****************************************************************************
*   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 "ip_cnvrt.h"
#include "iritgrap.h"

/****************************************************************************
* Draw a single Surface object using current modes and transformations.	    *
*   Surface must be with either E3 or P3 point type and must be NURB.	    *
*   Control points in SGI's format must be found in "_ctlpoints" attribute. *
****************************************************************************/
void IGDrawSurface(IPObjectStruct *PObj)
{
    IPObjectStruct *PObjPolylines, *PObjCtlMesh, *PObjPolygons;
    IPPolygonStruct *PPolylines, *PCtlMesh, *PPolygons, *PPolygonTemp;

    if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_isoline")) == NULL) {
	CagdSrfStruct *Srf,
	    *Srfs = PObj -> U.Srfs;

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

	    NumOfIso[0] = -IGGlblNumOfIsolines;
	    NumOfIso[1] = -IGGlblNumOfIsolines;
	    PPolylines = IritSurface2Polylines(Srf, NumOfIso,
					       IGGlblSamplesPerCurve);

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

    if (IGGlblDrawSurfacePoly || IGGlblDrawSolid) {
	if ((PObjPolygons = AttrGetObjectObjAttrib(PObj, "_polygons"))
								    == NULL) {
	    CagdSrfStruct *Srf,
	        *Srfs = PObj -> U.Srfs;

	    PObjPolygons = IPAllocObject("", IP_OBJ_POLY, NULL);
	    PObjPolygons -> Attrs = AttrCopyAttributes(PObj -> Attrs);
	    IP_SET_POLYGON_OBJ(PObjPolygons);

	    for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
		PPolygons = IritSurface2Polygons(Srf, IGGlblFourPerFlat,
						 1 << IGGlblFineNess, FALSE);

		if (PPolygons) {
		    for (PPolygonTemp = PPolygons;
			 PPolygonTemp -> Pnext;
			 PPolygonTemp = PPolygonTemp -> Pnext);
		    PPolygonTemp -> Pnext = PObjPolygons -> U.Pl;
		    PObjPolygons -> U.Pl = PPolygons;
		}
	    }
	    AttrSetObjectObjAttrib(PObj, "_polygons", PObjPolygons);
	}

	IGDrawPoly(PObjPolygons);
    }
    else
        IGDrawPoly(PObjPolylines);

    if (IGGlblDrawSurfaceMesh) {
	if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_ctlmesh"))
								== NULL) {
	    CagdSrfStruct *Srf,
		*Srfs = PObj -> U.Srfs;

	    PObjCtlMesh = IPAllocObject("", IP_OBJ_POLY, NULL);
	    PObjCtlMesh -> Attrs = AttrCopyAttributes(PObj -> Attrs);
	    IP_SET_POLYLINE_OBJ(PObjCtlMesh);
	    for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
		PCtlMesh = IritSurface2CtlMesh(Srf);

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

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