/*****************************************************************************
* Parses input files (in IRIT format) to get an object tree. It uses IRIT    *
* standard convention for parsing.                                           *
******************************************************************************
* (C) Gershon Elber, Technion, Israel Institute of Technology                *
******************************************************************************
* Written by:  Bassarab Dmitri & Plavnik Michael       Ver 0.2, Apr. 1995    *
*****************************************************************************/

#include "program.h"

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Parses input files using IRIT parser module.                             M
*                                                                            M
*                                                                            *
* PARAMETERS:                                                                M
*   argc:     IN, command line arguments number.                             M
*   argv:     IN, commnad line arguments.                                    M
*                                                                            *
* RETURN VALUE:                                                              M
*   IPObjectStruct *:  pointer to Irit objects tree created.                 M
*                                                                            *
* KEYWORDS:                                                                  M
*   ParseFiles, Irit parser                                                  M
*****************************************************************************/
IPObjectStruct *ParseFiles(int argc, char *argv[])
{
    IPObjectStruct *PObjects;

    /* Get the data files: */
    IritPrsrSetFlattenObjects(FALSE);
    if ((PObjects = IritPrsrGetDataFiles(argv, argc, TRUE, FALSE)) == NULL)
	exit(1);
    PObjects = IritPrsrResolveInstances(PObjects);

    /* Do we have animation time flag? */
    if (Options.HasTime)
        AnimEvalAnimation(Options.Time, PObjects);

    IritPrsrFlattenInvisibleObjects(FALSE);
    PObjects = IritPrsrFlattenForrest(PObjects);

    return PObjects;
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Reads free form description from the Irit data file and dessimates it    M
*   to the polygons.                                                         M
*                                                                            *
* PARAMETERS:                                                                M
*   FreeForms: pointer to the free form descritption objects.                M
*                                                                            *
* RETURN VALUE:                                                              M
*   IPObjectStruct *:  Processed free form objects.                          M
*                                                                            *
* KEYWORDS:                                                                  M
*   IritPrsrProcessFreeForm                                                  M
*****************************************************************************/
IPObjectStruct *IritPrsrProcessFreeForm(IritPrsrFreeFormStruct *FreeForms)
{
    IPObjectStruct *Object;
    IPPolygonStruct *Poly;

    for (Object = FreeForms -> CrvObjs;
	 Object != NULL;
	 Object = Object -> Pnext) {
	CagdCrvStruct *Curves, *Curve;

        Curves = Object -> U.Crvs;
        Object -> U.Pl = NULL;
        Object -> ObjType = IP_OBJ_POLY;
        IP_SET_POLYLINE_OBJ(Object);
        for (Curve = Curves; Curve != NULL; Curve = Curve -> Pnext) {
            Poly = IritCurve2Polylines(Curve,
				       Options.Crv2PllSamples,
				       Options.Crv2PllMethod);
	    if (Poly != NULL) {
		IritPrsrGetLastPoly(Poly) -> Pnext = Object -> U.Pl;
		Object -> U.Pl = Poly;
	    }
        }
        CagdCrvFreeList(Curves);
    }

    for (Object = FreeForms -> SrfObjs;
	 Object != NULL;
	 Object = Object -> Pnext) {
	RealType RelativeFineNess;
	CagdSrfStruct *Surfaces, *Surface;

	if ((RelativeFineNess = AttrGetObjectRealAttrib(Object,
                                           "resolution")) > IP_ATTR_BAD_REAL)
	    RelativeFineNess = 1.0;

        Surfaces = Object -> U.Srfs;
        Object -> U.Pl = NULL;
        Object -> ObjType = IP_OBJ_POLY;
        IP_SET_POLYGON_OBJ(Object);
        for (Surface = Surfaces; Surface != NULL; Surface = Surface -> Pnext) {
	    RealType t;

	    if ((t = AttrGetObjectRealAttrib(Object, "u_resolution"))
							    < IP_ATTR_BAD_REAL)
	        AttrSetRealAttrib(&Surface -> Attr, "u_resolution", t);
	    if ((t = AttrGetObjectRealAttrib(Object, "v_resolution"))
							    < IP_ATTR_BAD_REAL)
	        AttrSetRealAttrib(&Surface -> Attr, "v_resolution", t);

            Poly = IritSurface2Polygons(Surface,
					FALSE,
					RelativeFineNess *
					    Options.Srf2PlgFineness,
                                        TRUE,
                                        TRUE,
					Options.Srf2PlgOptimal);
	    if (Poly != NULL) {
		IritPrsrGetLastPoly(Poly) -> Pnext = Object -> U.Pl;
		Object -> U.Pl = Poly;
	    }
        }
        CagdSrfFreeList(Surfaces);
    }

    for (Object = FreeForms -> TrimSrfObjs;
	 Object != NULL;
	 Object = Object -> Pnext) {
	RealType RelativeFineNess;
	TrimSrfStruct *TrimSrfs, *TrimSrf;

	if ((RelativeFineNess = AttrGetObjectRealAttrib(Object,
                                           "resolution")) > IP_ATTR_BAD_REAL)
	    RelativeFineNess = 1.0;

        TrimSrfs = Object -> U.TrimSrfs;
        Object -> U.Pl = NULL;
        Object -> ObjType = IP_OBJ_POLY;
        IP_SET_POLYGON_OBJ(Object);
        for (TrimSrf = TrimSrfs; TrimSrf != NULL; TrimSrf = TrimSrf -> Pnext) {
	    RealType t;

	    if ((t = AttrGetObjectRealAttrib(Object, "u_resolution"))
							    < IP_ATTR_BAD_REAL)
	        AttrSetRealAttrib(&TrimSrf -> Attr, "u_resolution", t);
	    if ((t = AttrGetObjectRealAttrib(Object, "v_resolution"))
							    < IP_ATTR_BAD_REAL)
	        AttrSetRealAttrib(&TrimSrf -> Attr, "v_resolution", t);

	    Poly = IritTrimSrf2Polygons(TrimSrf,
					FALSE,
					RelativeFineNess *
					    Options.Srf2PlgFineness,
                                        TRUE,
                                        TRUE,
					Options.Srf2PlgOptimal);
	    if (Poly != NULL) {
		IritPrsrGetLastPoly(Poly) -> Pnext = Object -> U.Pl;
		Object -> U.Pl = Poly;
	    }
        }
        TrimSrfFreeList(TrimSrfs);
    }

    for (Object = FreeForms -> TrivarObjs;
	 Object != NULL;
	 Object = Object -> Pnext) {
	RealType RelativeFineNess;
	TrivTVStruct *Trivars, *Trivar;

	if ((RelativeFineNess = AttrGetObjectRealAttrib(Object,
                                           "resolution")) > IP_ATTR_BAD_REAL)
	    RelativeFineNess = 1.0;

        Trivars = Object -> U.Trivars;
        Object -> U.Pl = NULL;
        Object -> ObjType = IP_OBJ_POLY;
        IP_SET_POLYGON_OBJ(Object);
        for (Trivar = Trivars; Trivar != NULL; Trivar = Trivar -> Pnext) {
            Poly = IritTrivar2Polygons(Trivar,
				       FALSE,
				       RelativeFineNess *
					   Options.Srf2PlgFineness,
                                        TRUE,
				       TRUE,
				       Options.Srf2PlgOptimal);
	    if (Poly != NULL) {
		IritPrsrGetLastPoly(Poly) -> Pnext = Object -> U.Pl;
		Object -> U.Pl = Poly;
	    }
        }
        TrivTVFreeList(Trivars);
    }

    for (Object = FreeForms -> TriSrfObjs;
	 Object != NULL;
	 Object = Object -> Pnext) {
	RealType RelativeFineNess;
	TrngTriangSrfStruct *TriSrfs, *TriSrf;

	if ((RelativeFineNess = AttrGetObjectRealAttrib(Object,
                                           "resolution")) > IP_ATTR_BAD_REAL)
	    RelativeFineNess = 1.0;

        TriSrfs = Object -> U.TriSrfs;
        Object -> U.Pl = NULL;
        Object -> ObjType = IP_OBJ_POLY;
        IP_SET_POLYGON_OBJ(Object);
        for (TriSrf = TriSrfs; TriSrf != NULL; TriSrf = TriSrf -> Pnext) {
            Poly = IritTriSrf2Polygons(TriSrf,
				       RelativeFineNess *
					   Options.Srf2PlgFineness,
				       TRUE,
				       TRUE,
				       Options.Srf2PlgOptimal);
	    if (Poly != NULL) {
		IritPrsrGetLastPoly(Poly) -> Pnext = Object -> U.Pl;
		Object -> U.Pl = Poly;
	    }
        }
	TrngTriSrfFreeList(TriSrfs);
    }

    return IritPrsrConcatFreeForm(FreeForms);
}
