home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * Program to draw 3D object as wireframe after removing the hidden lines. *
- * This porgram works in object space, and if redirect stdout to a file, dump *
- * the visible polylines into it instead of drawing them on current device. *
- * This may be used to display the results on any device (a plotter !?) later.*
- * *
- * Options: *
- * 1. -b : Delete back facing polygons. *
- * 2. -e #Edges : If the edges are order is specific way (like in DrawFn3D) *
- * and only the k first edges of each polygons are to be displayed *
- * use this option as -e k. *
- * 3. -i : Internal edges. IRIT solid modeller may generate edges, which one *
- * may not want to see (default). -i will draw all of them. *
- * 4. -m : More flag, to print more imformation on input/errors. *
- * 5. -f FineNess : log based 2 of the fineness control of surfaces subdiv. *
- * 6. -4 : Four per flat bilinear, otherwise two. *
- * 7. -z : Print current version, and some helpfull data. *
- * *
- * Note some of those options may be permanently set to a different default *
- * using the configuration file "Poly3D-H.cfg" *
- * *
- * Usage: Poly3D-H [-b] [-i] [-m] [-e #Edges] [-f FineNess] [-4] [-z] DFiles. *
- * *
- * Written by: Gershon Elber Ver 3.0, Aug. 1990 *
- *****************************************************************************/
-
- #ifdef __MSDOS__
- #include <stdlib.h>
- #include <string.h>
- #include <conio.h>
- #include <io.h>
- #include <dos.h>
- #include <alloc.h>
- #endif /* __MSDOS__ */
-
- #include <stdio.h>
- #include <math.h>
- #include <time.h>
- #include "program.h"
- #include "getarg.h"
- #include "genmat.h"
- #include "iritprsr.h"
- #include "config.h"
-
- #ifdef __TURBOC__ /* Malloc debug routine - only on TC++ 1.0 and above. */
- #define __DEBUG_MALLOC__
- #endif /* __TURBOC__ */
-
- #ifdef __MSDOS__
- /* This huge stack is mainly from second phase - the segment intersections */
- /* which may cause recursive calls - a lot... */
- extern unsigned int _stklen = 32766;
- #endif /* __MSDOS__ */
-
- #ifdef NO_CONCAT_STR
- static char *VersionStr =
- "Poly3D-H Version 3.0, Gershon Elber,\n\
- (C) Copyright 1989/90/91 Gershon Elber, Non commercial use only.";
- #else
- static char *VersionStr = "Poly3D-H " VERSION ", Gershon Elber, "
- __DATE__ ", " __TIME__ "\n"
- "(C) Copyright 1989/90/91 Gershon Elber, Non commercial use only.";
- #endif /* NO_CONCAT_STR */
-
- static char *CtrlStr =
- "poly3d-h b%- m%- i%- e%-#Edges!d f%-FineNess!d 4%- z%- DFiles!*s";
-
- static long SaveTotalTime;
- static int
- GlblFourPerFlat = FALSE;
-
- int NumOfPolygons = 0; /* Total number of polygons to handle. */
- MatrixType GlblViewMat; /* Current view of object. */
-
- /* Data structures used by the hidden line modules: */
- int EdgeCount = 0;
- EdgeStruct *EdgeHashTable[EDGE_HASH_TABLE_SIZE];
- IPPolygonStruct *PolyHashTable[POLY_HASH_TABLE_SIZE];
-
- /* The following are setable variables (via configuration file poly3d-h.cfg).*/
- int GlblMore = FALSE,
- GlblNumEdge = 0,
- GlblBackFacing = FALSE,
- GlblInternal = FALSE,
- GlblFineNess = DEFAULT_FINENESS;
-
- static ConfigStruct SetUp[] =
- { { "Internal", (VoidPtr) &GlblInternal, SU_BOOLEAN_TYPE },
- { "BackFacing", (VoidPtr) &GlblBackFacing, SU_BOOLEAN_TYPE },
- { "More", (VoidPtr) &GlblMore, SU_BOOLEAN_TYPE },
- { "FourPerFlat", (VoidPtr) &GlblFourPerFlat, SU_BOOLEAN_TYPE },
- { "FineNess", (VoidPtr) &GlblFineNess, SU_INTEGER_TYPE },
- { "NumOfEdges", (VoidPtr) &GlblNumEdge, SU_INTEGER_TYPE } };
-
- #define NUM_SET_UP (sizeof(SetUp) / sizeof(ConfigStruct))
-
- static IPPolygonStruct *Curve2Polylines(CagdCrvStruct *Crv);
- static IPPolygonStruct *Surface2Polygons(CagdSrfStruct *Srf);
- static IPObjectStruct *MainGetDataFiles(char **DataFileNames, int NumOfDataFiles);
-
- /*****************************************************************************
- * Main routine - Read Parameter line and do what you need... *
- *****************************************************************************/
- void
- #ifdef __MSDOS__
- cdecl /* So we can use -rp in Borland 3.0 (parameters in registers.). */
- #endif /* __MSDOS__ */
- main(int argc, char **argv)
- {
- int EdgesFlag = FALSE,
- VerFlag = FALSE,
- NumFiles = FALSE,
- FineNessFlag = FALSE, Error;
- char
- **FileNames = NULL;
- IPObjectStruct *PObjects;
-
- SaveTotalTime = time(NULL); /* Save starting time. */
- #ifdef __MSDOS__
- ctrlbrk((int cdecl (*)()) MyExit); /* Kill this program if ^C... */
- #endif /* __MSDOS_ */
-
- Config("poly3d-h", SetUp, NUM_SET_UP); /* Read config. file if exists. */
-
- if ((Error = GAGetArgs (argc, argv, CtrlStr,
- &GlblBackFacing, &GlblMore, &GlblInternal,
- &EdgesFlag, &GlblNumEdge, &FineNessFlag, &GlblFineNess,
- &GlblFourPerFlat, &VerFlag, &NumFiles, &FileNames)) != 0) {
- GAPrintErrMsg(Error);
- GAPrintHowTo(CtrlStr);
- MyExit(1);
- }
-
- if (VerFlag) {
- fprintf(stderr, "\n%s\n\n", VersionStr);
- GAPrintHowTo(CtrlStr);
- ConfigPrint(SetUp, NUM_SET_UP);
- MyExit(0);
- }
-
- if (!NumFiles) {
- fprintf(stderr, "No data file names were given, exit\n");
- GAPrintHowTo(CtrlStr);
- MyExit(1);
- }
-
- /* Get the data files: */
- IritPrsrPolyListCirc = FALSE;
- PObjects = MainGetDataFiles(FileNames, NumFiles);
-
- /* And update the global viewing matrix: */
- if (IritPrsrWasPrspMat)
- MultTwo4by4(GlblViewMat, IritPrsrViewMat, IritPrsrPrspMat);
- else
- GEN_COPY(GlblViewMat, IritPrsrViewMat, sizeof(MatrixType));
-
- /* Prepare data structures to be able to decide on visibility: */
- PrepareViewData(PObjects);
-
- OutVisibleEdges(); /* Scan all sub-edges output visible. */
-
- 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;
- char *ErrorMsg;
- FILE *f;
- long
- SaveTime = time(NULL);
- IPObjectStruct *PObj, *PObjTail,
- *PObjHead = NULL;
-
- fprintf(stderr, "Reading data file(s).\n");
-
- for (i = 0; i < NumOfDataFiles; i++) {
- if (GlblMore) fprintf(stderr, "Reading %s.\n", *DataFileNames);
-
- #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;
- }
-
- if (GlblMore && IritPrsrParseError(&ErrorMsg))
- fprintf(stderr, "File %s, %s\n", *DataFileNames, ErrorMsg);
-
- fclose(f); /* Close the file. */
-
- DataFileNames++; /* Skip to next file name. */
- }
-
- if (PObjHead == NULL) {
- fprintf(stderr, "No data found.\n");
- MyExit(1);
- }
-
- fprintf(stderr, "Done reading, %ld seconds.", time(NULL) - SaveTime);
-
- return PObjHead;
- }
-
- /*****************************************************************************
- * Routine to convert all surfaces/curves into polylines as follows: *
- * Curves are converted to single polyline with SamplesPerCurve samples. *
- * Surface are converted into GlblNumOfIsolines curves in each axes, each *
- * handled as Curves above. The curves and surfaces are then deleted. *
- *****************************************************************************/
- IPObjectStruct *IritPrsrProcessFreeForm(IPObjectStruct *CrvObjs,
- IPObjectStruct *SrfObjs)
- {
- CagdCrvStruct *Crv, *Crvs;
- CagdSrfStruct *Srf, *Srfs;
- IPObjectStruct *PObj;
- IPPolygonStruct *PPolygon, *PPolygonTemp;
-
- if (CrvObjs == NULL && SrfObjs == NULL) return NULL;
-
- /* Make sure requested format is something reasonable. */
- if (GlblFineNess < 2) {
- GlblFineNess = 2;
- if (GlblMore)
- fprintf(stderr, "FineNess is less than 2, 2 picked instead.\n");
- }
-
- if (CrvObjs) {
- for (PObj = CrvObjs; PObj != NULL; PObj = PObj -> Pnext) {
- Crvs = PObj -> U.PCrvs;
- PObj -> U.PPolygon = NULL;
- for (Crv = Crvs; Crv != NULL; Crv = Crv -> Pnext) {
- PPolygon = PPolygonTemp = Curve2Polylines(Crv);
- while (PPolygonTemp -> Pnext)
- PPolygonTemp = PPolygonTemp -> Pnext;
- PPolygonTemp -> Pnext = PObj -> U.PPolygon;
- PObj -> U.PPolygon = PPolygon;
- }
- CagdCrvFreeList(Crvs);
- }
- }
-
- if (SrfObjs) {
- for (PObj = SrfObjs; PObj != NULL; PObj = PObj -> Pnext) {
- Srfs = PObj -> U.PSrfs;
- PObj -> U.PPolygon = NULL;
- for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
- PPolygon = PPolygonTemp = Surface2Polygons(Srf);
- while (PPolygonTemp -> Pnext)
- PPolygonTemp = PPolygonTemp -> Pnext;
- PPolygonTemp -> Pnext = PObj -> U.PPolygon;
- PObj -> U.PPolygon = PPolygon;
- }
- CagdSrfFreeList(Srfs);
- }
- }
-
- if (SrfObjs == NULL)
- return CrvObjs;
- else if (CrvObjs == NULL)
- return SrfObjs;
- else {
- for (PObj = SrfObjs; PObj -> Pnext != NULL; PObj = PObj -> Pnext);
- PObj -> Pnext = CrvObjs;
- return SrfObjs;
- }
- }
-
- /*****************************************************************************
- * Routine to convert a single curve into a polyline with SamplesPerCurve *
- * samples, into a polyline object. *
- *****************************************************************************/
- static IPPolygonStruct *Curve2Polylines(CagdCrvStruct *Crv)
- {
- int i, j;
- IPVertexStruct *V,
- *VHead = NULL;
- IPPolygonStruct *P;
- CagdPolylineStruct
- *CagdPoly = CagdCrv2Polyline(Crv, GlblFineNess);
-
- for (i = 0; i < CagdPoly -> Length; i++) {
- if (VHead == NULL)
- VHead = V = IritPrsrNewVertexStruct();
- else {
- V -> Pnext = IritPrsrNewVertexStruct();
- V = V -> Pnext;
- }
-
- for (j = 0; j < 3; j++) /* Convert to our format. */
- V -> Coord[j] = CagdPoly -> Polyline[i].Pt[j];
- }
-
- V -> Pnext = NULL;
- P = IritPrsrNewPolygonStruct();
- P -> PVertex = VHead;
- P -> Type = IP_POLYLINE;
-
- CagdPolylineFree(CagdPoly);
-
- return P;
- }
-
- /*****************************************************************************
- * Routine to convert a single surface into a polygons with 2^GlblFineNess *
- * as fineness measure. *
- *****************************************************************************/
- static IPPolygonStruct *Surface2Polygons(CagdSrfStruct *Srf)
- {
- int i, j;
- IPVertexStruct *V, *VHead;
- IPPolygonStruct *P,
- *PHead = NULL;
- CagdPolygonStruct *CagdPolygon,
- *CagdPolygonHead = NULL;
-
- CagdPolygonHead = CagdSrf2Polygons(Srf, 1 << GlblFineNess,
- FALSE, GlblFourPerFlat);
-
- for (CagdPolygon = CagdPolygonHead;
- CagdPolygon != NULL;
- CagdPolygon = CagdPolygon -> Pnext) {
- /* All polygons are triangles! */
- VHead = NULL;
- for (i = 0; i < 3; i++) { /* Convert to vertices. */
- if (VHead == NULL)
- VHead = V = IritPrsrNewVertexStruct();
- else {
- V -> Pnext = IritPrsrNewVertexStruct();
- V = V -> Pnext;
- }
-
- for (j = 0; j < 3; j++) /* Convert to our format. */
- V -> Coord[j] = CagdPolygon -> Polygon[i].Pt[j];
- }
-
- V -> Pnext = NULL;
- P = IritPrsrNewPolygonStruct();
- P -> PVertex = VHead;
- P -> Type = IP_POLYGON;
- P -> Pnext = PHead;
-
- PHead = P;
- }
-
- CagdPolygonFreeList(CagdPolygonHead);
-
- return PHead;
- }
-
- #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)
- {
- VoidPtr p;
-
- 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(), or call *
- * RestoreCtrlBrk() without SetUpCtrlBrk() and it is the responsibility *
- * of the individual modules to do nothing in these cases. *
- *****************************************************************************/
- void MyExit(int ExitCode)
- {
- #ifdef __MSDOS__
- fprintf(stderr,
- "\nPoly3D-H: Total RealTime %ld seconds, Core left %ldk.\n",
- time(NULL) - SaveTotalTime, coreleft() / 1024);
- #else
- fprintf(stderr,
- "\nPoly3D-H: Total RealTime %ld seconds.\n",
- time(NULL) - SaveTotalTime);
- #endif /* __MSDOS__ */
-
- exit(ExitCode);
- }
-