/***************************************************************************** * Filter to convert IRIT data files back to IRIT .irt files. * * * * Written by: Gershon Elber Ver 1.0, Sep 1991 * *****************************************************************************/ #ifdef __MSDOS__ #include #include #endif /* __MSDOS__ */ #include #include #include #include #include "irit_sm.h" #include "iritprsr.h" #include "getarg.h" #include "genmat.h" #ifdef __MSDOS__ extern unsigned int _stklen = 32766; /* Increase default stack size. */ #endif /* __MSDOS__ */ #ifdef NO_CONCAT_STR static char *VersionStr = "Dat2Irit Version 3.0, Gershon Elber,\n\ (C) Copyright 1989/90/91 Gershon Elber, Non commercial use only."; #else static char *VersionStr = "Dat2Irit " VERSION ", Gershon Elber, " __DATE__ ", " __TIME__ "\n" "(C) Copyright 1989/90/91 Gershon Elber, Non commercial use only."; #endif /* NO_CONCAT_STR */ static char *CtrlStr = "dat2irit z%- DFiles!*s"; static IPObjectStruct *MainGetDataFiles(char **DataFileNames, int NumOfDataFiles); static void DumpDataForIrit(IPObjectStruct *PObjects); static void DumpOneObject(FILE *f, IPObjectStruct *PObject); static void DumpOnePolygon(FILE *f, IPPolygonStruct *PPolygon, int PolyNum); static void DumpOneSurface(FILE *f, char *Name, CagdSrfStruct *Srf); static void DumpOneCurve(FILE *f, char *Name, CagdCrvStruct *Crv); static void DumpCtlPt(FILE *f, CagdPointType PType, RealType **Points, int Index); static void DumpKnotVector(FILE *f, RealType *KnotVector, int Length); #ifdef __DEBUG_MALLOC__ static void AllocError(const char *Msg, VoidPtr *p); #endif /* __DEBUG_MALLOC__ */ VoidPtr MyMalloc(unsigned size); void MyFree(VoidPtr p); void CagdFatalError(CagdFatalErrorType ErrID); void MyExit(int ExitCode); /***************************************************************************** * Main routine - Read Parameter line and do what you need... * *****************************************************************************/ void main(int argc, char **argv) { int Error, VerFlag = FALSE, NumFiles = 0; char **FileNames = NULL; IPObjectStruct *PObjects; #ifdef __MSDOS__ ctrlbrk((int (*)()) MyExit); /* Kill process if ^C. */ #endif /* __MSDOS__ */ if ((Error = GAGetArgs (argc, argv, CtrlStr, &VerFlag, &NumFiles, &FileNames)) != 0) { GAPrintErrMsg(Error); GAPrintHowTo(CtrlStr); MyExit(1); } if (VerFlag) { fprintf(stderr, "\n%s\n\n", VersionStr); GAPrintHowTo(CtrlStr); MyExit(0); } if (!NumFiles) { fprintf(stderr, "No data file names where given, exit.\n"); GAPrintHowTo(CtrlStr); MyExit(1); } /* Get the data files: */ IritPrsrPolyListCirc = FALSE; PObjects = MainGetDataFiles(FileNames, NumFiles); DumpDataForIrit(PObjects); MyExit(0); } /***************************************************************************** * Main routine to read the data description files: * * Returns pointer to pointers on FileDescription structures (one per file). * *****************************************************************************/ static IPObjectStruct *MainGetDataFiles(char **DataFileNames, int NumOfDataFiles) { int i; FILE *f; IPObjectStruct *PObj, *PObjTail, *PObjHead = NULL; for (i = 0; i < NumOfDataFiles; i++) { #ifdef __MSDOS__ if ((f = fopen(*DataFileNames, "rt")) == NULL) { /* Open the file. */ #else if ((f = fopen(*DataFileNames, "r")) == NULL) { /* Open the file. */ #endif /* __MSDOS__ */ fprintf(stderr, "Can't open data file %s\n", *DataFileNames); MyExit(1); } if ((PObj = IritPrsrGetObjects(f)) != NULL) { /* Get the data file. */ PObjTail = PObj; while (PObjTail -> Pnext) PObjTail = PObjTail -> Pnext; PObjTail -> Pnext = PObjHead; PObjHead = PObj; } fclose(f); /* Close the file. */ DataFileNames++; /* Skip to next file name. */ } if (PObjHead == NULL) { fprintf(stderr, "No data found.\n"); MyExit(1); } return PObjHead; } /***************************************************************************** * Routine to handle all surfaces/curves. Simple chain them into a linear * * list and return it. * *****************************************************************************/ IPObjectStruct *IritPrsrProcessFreeForm(IPObjectStruct *CrvObjs, IPObjectStruct *SrfObjs) { if (CrvObjs == NULL) return SrfObjs; else if (SrfObjs == NULL) return CrvObjs; else { IPObjectStruct *PTmp = CrvObjs; while (PTmp -> Pnext) PTmp = PTmp -> Pnext; PTmp -> Pnext = SrfObjs; return CrvObjs; } } /***************************************************************************** * Dumps the data for ray shade into stdout. * *****************************************************************************/ static void DumpDataForIrit(IPObjectStruct *PObjects) { int NameCount = 1; IPObjectStruct *PObj, *PObjHead = NULL; /* Reverse object list since it was loaded in reverse by iritprsr module.*/ while (PObjects != NULL) { PObj = PObjects; PObjects = PObjects -> Pnext; PObj -> Pnext = PObjHead; PObjHead = PObj; } for (PObjects = PObjHead; PObjects != NULL; PObjects = PObjects -> Pnext) DumpOneObject(stdout, PObjects); printf("\n\ndat2irit = list(\n"); for (PObjects = PObjHead; PObjects != NULL; PObjects = PObjects -> Pnext) if (PObjects -> Name == NULL || strlen(PObjects -> Name) == 0) printf("\tNoName%d%s\n", NameCount++, PObjects -> Pnext == NULL ? "" : ","); else printf("\t%s%s\n", PObjects -> Name, PObjects -> Pnext == NULL ? "" : ","); printf(");\n"); } /***************************************************************************** * Routine to dump one object PObject. * *****************************************************************************/ static void DumpOneObject(FILE *f, IPObjectStruct *PObject) { static int NameCount = 1; int i, j; char Name[LINE_LEN_LONG]; CagdSrfStruct *Srf; CagdCrvStruct *Crv; IPPolygonStruct *Pl; if (PObject -> Name == NULL || strlen(PObject -> Name) == 0) sprintf(Name, "NoName%d", NameCount++); else strcpy(Name, PObject -> Name); switch (PObject -> Type) { case IP_OBJ_POLY: for (Pl = PObject -> U.PPolygon, i = 1; Pl != NULL; Pl = Pl -> Pnext, i++) DumpOnePolygon(f, Pl, i); fprintf(f, "%s = mergePoly( list( ", Name); for (j = 1; j < i; j++) { if (j % 7 == 0) fprintf(f, "\n\t\t"); fprintf(f, "POLY%d%s ", j, j == i - 1 ? "" : ","); } printf(") );\n\n"); break; case IP_OBJ_SURFACE: for (Srf = PObject -> U.PSrfs; Srf != NULL; Srf = Srf -> Pnext) DumpOneSurface(stdout, Name, Srf); break; case IP_OBJ_CURVE: for (Crv = PObject -> U.PCrvs; Crv != NULL; Crv = Crv -> Pnext) DumpOneCurve(stdout, Name, Crv); break; } } /***************************************************************************** * Routine to dump one polygon. * *****************************************************************************/ static void DumpOnePolygon(FILE *f, IPPolygonStruct *PPolygon, int PolyNum) { int i, VCount = 1; IPVertexStruct *V = PPolygon -> PVertex, *VFirst = V; do { fprintf(f, "VRTX%d = vector( %lg, %lg, %lg );\n", VCount++, V -> Coord[0], V -> Coord[1], V -> Coord[2]); V = V -> Pnext; } while (V != VFirst && V != NULL); fprintf(f, "POLY%d = poly( list( ", PolyNum ); for (i = 1; i < VCount; i++) { if (VCount % 9 == 0) fprintf(f, "\n\t\t"); fprintf(f, "VRTX%d%s ", i, i == VCount - 1 ? "" : "," ); } fprintf(f, ") );\n\n"); } /***************************************************************************** * Routine to dump one surface. * *****************************************************************************/ static void DumpOneSurface(FILE *f, char *Name, CagdSrfStruct *Srf) { int i, j, k; switch (Srf -> GType) { case CAGD_SBEZIER_TYPE: fprintf(f, "%s = sbezier(\n", Name); break; case CAGD_SBSPLINE_TYPE: fprintf(f, "%s = sbspline( %d, %d, \n", Name, Srf -> UOrder, Srf -> VOrder); break; default: fprintf(stderr, "Unsupported surface type ignored.\n"); return; } /* Print the control mesh: */ for (i = k = 0; i < Srf -> VLength; i++) { for (j = 0; j < Srf -> ULength; j++) { fprintf(f, "%s", i == 0 && j == 0 ? "\tlist( " : "\t "); fprintf(f, "%s", j == 0 ? "list( " : " "); DumpCtlPt(f, Srf -> PType, Srf -> Points, k++); fprintf(f, "%s", j == Srf -> ULength - 1 ? " )" : ",\n" ); } if (i < Srf -> VLength - 1) fprintf(f, ",\n"); } switch (Srf -> GType) { case CAGD_SBEZIER_TYPE: fprintf(f, " ) );\n"); break; case CAGD_SBSPLINE_TYPE: fprintf(f, " ),\n\tlist( "); DumpKnotVector(f, Srf -> UKnotVector, Srf -> UOrder + Srf -> ULength); fprintf(f, ",\n\t "); DumpKnotVector(f, Srf -> VKnotVector, Srf -> VOrder + Srf -> VLength); fprintf(f, " ) );\n"); break; } } /***************************************************************************** * Routine to dump one curve. * *****************************************************************************/ static void DumpOneCurve(FILE *f, char *Name, CagdCrvStruct *Crv) { int i; switch (Crv -> GType) { case CAGD_CBEZIER_TYPE: fprintf(f, "%s = cbezier(\n", Name); break; case CAGD_CBSPLINE_TYPE: fprintf(f, "%s = cbspline( %d,\n", Name, Crv -> Order); break; default: fprintf(stderr, "Unsupported curve type ignored.\n"); return; } /* Print the control polygon: */ fprintf(f, "\tlist( "); for (i = 0; i < Crv -> Length; i++) { DumpCtlPt(f, Crv -> PType, Crv -> Points, i); if (i < Crv -> Length - 1) fprintf(f, ",\n\t "); } switch (Crv -> GType) { case CAGD_CBEZIER_TYPE: fprintf(f, " ) );\n"); break; case CAGD_CBSPLINE_TYPE: fprintf(f, " ),\n\t "); DumpKnotVector(f, Crv -> KnotVector, Crv -> Order + Crv -> Length); fprintf(f, " );\n"); break; } } /***************************************************************************** * Routine to dump one control point. * *****************************************************************************/ static void DumpCtlPt(FILE *f, CagdPointType PType, RealType **Points, int Index) { fprintf(f, "ctlpt( "); switch (PType) { case CAGD_PT_E2_TYPE: fprintf(f, "E2, %lg, %lg", Points[1][Index], Points[2][Index]); break; case CAGD_PT_P2_TYPE: fprintf(f, "P2, %lg, %lg, %lg", Points[0][Index], Points[1][Index], Points[2][Index]); break; case CAGD_PT_E3_TYPE: fprintf(f, "E3, %lg, %lg, %lg", Points[1][Index], Points[2][Index], Points[3][Index]); break; case CAGD_PT_P3_TYPE: fprintf(f, "P3, %lg, %lg, %lg, %lg", Points[0][Index], Points[1][Index], Points[2][Index], Points[3][Index]); break; default: fprintf(stderr, "Unsupported control point type.\n"); MyExit(1); } fprintf(f, " )"); } /***************************************************************************** * Routine to dump one knot vector. * *****************************************************************************/ static void DumpKnotVector(FILE *f, RealType *KnotVector, int Length) { int i; fprintf(f, "list( "); for (i = 0; i < Length; i++) fprintf(f, "%lg%s ", KnotVector[i], i < Length -1 ? "," : ""); fprintf(f, ")"); } #ifdef __DEBUG_MALLOC__ /***************************************************************************** * My Routine to allocate dynamic memory. All program requests must call this * * routine (no direct call to malloc). Dies if no memory. * *****************************************************************************/ static void AllocError(const char *Msg, VoidPtr *p) { fprintf(stderr, "%s, Ptr = %p\n", Msg, p); MyExit(3); } #endif /* __DEBUG_MALLOC__ */ /***************************************************************************** * My Routine to allocate dynamic memory. All program requests must call this * * routine (no direct call to malloc). Dies if no memory. * *****************************************************************************/ VoidPtr MyMalloc(unsigned size) { static int Count = 0; VoidPtr p; #ifdef __MSDOS__ if (Count++ == 50) { Count = 0; fprintf(stderr, "Core left: %ldk \r", coreleft() / 1024); } #endif /* __MSDOS__ */ if ((p = malloc(size)) != NULL) return p; fprintf(stderr, "Not enough memory, exit.\n"); MyExit(2); return NULL; /* Make warnings silent. */ } /***************************************************************************** * My Routine to free dynamic memory. All program requests must call this * * routine (no direct call to free). * *****************************************************************************/ void MyFree(VoidPtr p) { #ifdef __DEBUG_MALLOC__ switch (heapchecknode(p)) { case _HEAPCORRUPT: AllocError("Heap is corrupted", p); break; case _BADNODE: AllocError("Attempt to free a bogus pointer", p); break; case _FREEENTRY: AllocError("Attempt to free an already freed pointer", p); break; case _USEDENTRY: break; default: AllocError("Allocation error", p); break; } #endif /* __DEBUG_MALLOC__ */ free(p); } /***************************************************************************** * Trap Cagd_lib errors right here. * *****************************************************************************/ void CagdFatalError(CagdFatalErrorType ErrID) { char *ErrorMsg = CagdDescribeError(ErrID); fprintf(stderr, "CAGD_LIB: %s", ErrorMsg); exit(-1); } /***************************************************************************** * MyExit routine. Note it might call to CloseGraph without calling * * InitGraph(), or call MouseClose() without MouseInit() etc. and it is the * * responsibility of the individual modules to do nothing in these cases. * *****************************************************************************/ void MyExit(int ExitCode) { #ifdef __MSDOS__ fprintf(stderr, "\nIrit2Ray: Core left %ldk.\n", coreleft() / 1024); #endif /* __MSDOS__ */ exit(ExitCode); }