home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * Program to draw 3D object as wireframe from any ortographic view *
- * Options: *
- * 1. -c : Object is closed. If object is closed each edge is shared by two *
- * polygons and therefore can bedrawn only once. *
- * 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. *
- * Note all messages goes to STDOUT (not stderr!) as this program *
- * works in graphic mode, and we can redirect stdout to a file. *
- * 5. -n : Draw vertices normals if the data has them, otherwise ignore. *
- * 6. -M : draw surfaces Mesh and curves control polygon. *
- * 7. -I n : number of isolines for a given surface. *
- * 8. -P : generate polygon for surfaces. *
- * 9. -S n : log based 2 of number of samples per curve. *
- * 10. -f FineNess : log based 2 of the fineness control of surface to *
- * polygon subdivision. *
- * 11. -4 : force 4 polygons per flat. Otherwise two. *
- * 12. -z : Print current version, and some helpfull data. *
- * *
- * Note some of those options way be permanently set to a different default *
- * using the configuration file "Poly3D.cfg" *
- * *
- * Usage: *
- * Poly3D [-c] [-m] [-i] [-e #Edges] [-n] [-N] [-M] [-I n] [-P] [-S n] *
- * [-f FineNess] [-4] [-z] Files *
- * *
- * Written by: Gershon Elber Ver 3.0, Aug 1990 *
- *****************************************************************************/
-
- #ifdef __MSDOS__
- #include <stdlib.h>
- #include <conio.h>
- #include <dos.h>
- #include <graphics.h>
- #include <alloc.h>
- #endif /* __MSDOS__ */
-
- #include <stdio.h>
- #include <string.h>
- #include <time.h>
- #include "program.h"
- #include "getarg.h"
- #include "genmat.h"
- #include "interact.h"
- #include "graphgen.h"
- #include "config.h"
-
- #ifdef __TURBOC__ /* Malloc debug routine - only on TC++ 1.0 and above. */
- #define __DEBUG_MALLOC__
- #endif /* __TURBOC__ */
-
- #ifdef __MSDOS__
- #include "matherr.h"
- #endif /* __MSDOS__ */
-
- #ifdef __MSDOS__
- extern unsigned int _stklen = 32766; /* Increase default stack size. */
- #endif /* __MSDOS__ */
-
- #ifdef NO_CONCAT_STR
- static char *VersionStr =
- "Poly3D Version 3.0, Gershon Elber,\n\
- (C) Copyright 1989/90/91 Gershon Elber, Non commercial use only.";
- #else
- static char *VersionStr = "Poly3D " 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 c%- m%- i%- e%-#Edges!d n%- N%- M%- P%- I%-#IsoLines!d S%-#SampPerCrv!d f%-FineNess!d 4%- z%- DFiles!*s";
-
- static int
- GlblNormalLenAux = NORMAL_DEFAULT_LENGTH,
- GlblFineNess = 5,
- GlblFourPerFlat = FALSE;
-
- /* The following are setable variables (via configuration file poly3d.cfg). */
- int
- #if defined(__MSDOS__) || defined(DJGCC) /* Defaults for MSDOS intr_lib. */
- GlblWindowFrameWidth = 8,
- GlblViewFrameColor = INTR_COLOR_RED,
- GlblViewBackColor = INTR_COLOR_BLACK,
- GlblTransFrameColor = INTR_COLOR_GREEN,
- GlblTransBackColor = INTR_COLOR_BLACK,
- GlblStatusFrameColor = INTR_COLOR_RED,
- GlblStatusBackColor = INTR_COLOR_BLACK,
- GlblInputFrameColor = INTR_COLOR_RED,
- GlblInputBackColor = INTR_COLOR_BLACK,
- GlblDrawHeader = FALSE,
- GlblSmoothTextScroll = FALSE,
- GlblIntrSaveMethod = INTR_SAVE_DISK,
- GlblMouseSensitivity = 10, /* Sensitivity control of mouse device. */
- GlblJoystickExists = FALSE,
- #endif /*__MSDOS__ || DJGCC */
- #ifdef __MSDOS__
- GlblGraphDriver = DETECT,
- #endif /* __MSDOS__ */
- GlblWasCtrlBrk = FALSE,
- GlblMouseExists = TRUE,
- GlblTransformMode = TRANS_SCREEN, /* Screen, Object trans. mode. */
- GlblViewMode = VIEW_ORTHOGRAPHIC, /* Persp, Ortho etc. */
- GlblDepthCue = TRUE, /* Activate depth cueing. */
- GlblDrawSolid = FALSE, /* Use hardware Z buffer rendering. */
- GlblInternal = FALSE,
- GlblDoGraphics = TRUE,/* Control if running in graphics/text mode. */
- GlblMore = FALSE,
- GlblNumEdges = 0,
- GlblDrawVNormal = FALSE,
- GlblDrawPNormal = FALSE,
- GlblClosedObject = FALSE,
- GlblDrawSurfaceMesh = FALSE,
- GlblDrawSurfacePoly = FALSE,
- GlblNumOfIsolines = DEFAULT_NUM_OF_ISOLINES,
- GlblSamplesPerCurve = DEFAULT_SAMPLES_PER_CURVE;
-
- static char
- *BGIDriverPath = NULL,
- *SVGANameMode = NULL;
-
- char
- #ifdef __GL__
- /* Preferance position and size of view and transformation windows. */
- *GlblTransPrefPos = "455, 640, 520, 965",
- *GlblViewPrefPos = "1, 450, 520, 965",
- #endif /* __GL__ */
- #if defined(__MSDOS__) || defined(DJGCC) /* Defaults for MSDOS intr_lib. */
- *GlblViewWndwPos = "0.02, 0.02, 0.72, 0.98",
- *GlblTransWndwPos = "0.75, 0.02, 0.98, 0.98",
- *GlblStatusWndwPos = "",
- *GlblInputWndwPos = "",
- *GlblIntrSaveDisk = "d:\\",
- #endif /* __MSDOS__ || DJGCC */
- GlblFirstDataFileName[PATH_NAME_LEN]; /* Hold name of first data file. */
-
- static long SaveTotalTime;
-
- MatrixType CrntViewMat; /* This is the current view! */
-
- RealType GlblNormalLen = 0.0; /* Scaler for normals if drawn. */
-
- static ConfigStruct SetUp[] =
- {
- #if defined(__MSDOS__) || defined(DJGCC) /* Defaults for MSDOS intr_lib. */
- { "Joystick", (VoidPtr) &GlblJoystickExists, SU_BOOLEAN_TYPE },
- { "Mouse", (VoidPtr) &GlblMouseExists, SU_BOOLEAN_TYPE },
- { "MouseSensitivity", (VoidPtr) &GlblMouseSensitivity,SU_INTEGER_TYPE },
- { "WndwWidth", (VoidPtr) &GlblWindowFrameWidth,SU_INTEGER_TYPE },
- { "WndwHeader", (VoidPtr) &GlblDrawHeader, SU_BOOLEAN_TYPE },
- { "WndwViewClr", (VoidPtr) &GlblViewFrameColor, SU_INTEGER_TYPE },
- { "WndwTransClr", (VoidPtr) &GlblTransFrameColor, SU_INTEGER_TYPE },
- { "WndwViewPos", (VoidPtr) &GlblViewWndwPos, SU_STRING_TYPE },
- { "WndwTransPos", (VoidPtr) &GlblStatusWndwPos, SU_STRING_TYPE },
- { "WndwBackSave", (VoidPtr) &GlblIntrSaveMethod, SU_INTEGER_TYPE },
- { "WndwBackSavePath", (VoidPtr) &GlblIntrSaveDisk, SU_STRING_TYPE },
- #endif /* __MSDOS__ || DJGCC */
- #ifdef __MSDOS__
- { "SVGANameMode", (VoidPtr) &SVGANameMode, SU_STRING_TYPE },
- { "BGIDriverPath", (VoidPtr) &BGIDriverPath, SU_STRING_TYPE },
- { "GraphDriver", (VoidPtr) &GlblGraphDriver, SU_INTEGER_TYPE },
- #endif /* __MSDOS__ */
- #ifdef __GL__
- { "TransPrefPos", (VoidPtr) &GlblTransPrefPos, SU_STRING_TYPE },
- { "ViewPrefPos", (VoidPtr) &GlblViewPrefPos, SU_STRING_TYPE },
- #endif /* __GL__ */
- { "FineNess", (VoidPtr) &GlblFineNess, SU_INTEGER_TYPE },
- { "FourPerFlat", (VoidPtr) &GlblFourPerFlat, SU_BOOLEAN_TYPE },
- { "ViewMode", (VoidPtr) &GlblViewMode, SU_INTEGER_TYPE },
- { "TransMode", (VoidPtr) &GlblTransformMode, SU_INTEGER_TYPE },
- { "ClosedObject", (VoidPtr) &GlblClosedObject, SU_BOOLEAN_TYPE },
- { "DepthCue", (VoidPtr) &GlblDepthCue, SU_BOOLEAN_TYPE },
- { "DrawSolid", (VoidPtr) &GlblDrawSolid, SU_BOOLEAN_TYPE },
- { "Internal", (VoidPtr) &GlblInternal, SU_BOOLEAN_TYPE },
- { "More", (VoidPtr) &GlblMore, SU_BOOLEAN_TYPE },
- { "NormalLength", (VoidPtr) &GlblNormalLenAux, SU_INTEGER_TYPE },
- { "DrawVNormal", (VoidPtr) &GlblDrawVNormal, SU_BOOLEAN_TYPE },
- { "DrawPNormal", (VoidPtr) &GlblDrawPNormal, SU_BOOLEAN_TYPE },
- { "NumOfEdges", (VoidPtr) &GlblNumEdges, SU_INTEGER_TYPE },
- { "NumOfIsolines", (VoidPtr) &GlblNumOfIsolines, SU_INTEGER_TYPE },
- { "SamplesPerCurve", (VoidPtr) &GlblSamplesPerCurve, SU_INTEGER_TYPE },
- { "DrawSurfaceMesh", (VoidPtr) &GlblDrawSurfaceMesh, SU_BOOLEAN_TYPE },
- { "DrawSurfacePoly", (VoidPtr) &GlblDrawSurfacePoly, SU_BOOLEAN_TYPE } };
-
- #define NUM_SET_UP (sizeof(SetUp) / sizeof(ConfigStruct))
-
- static IPObjectStruct *MainGetDataFiles(char **DataFileNames, int NumOfDataFiles);
- static IPPolygonStruct *Curve2Polylines(CagdCrvStruct *Crv);
- static IPPolygonStruct *Surface2Polylines(CagdSrfStruct *Srf);
-
- /*****************************************************************************
- * 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 Error,
- EdgesFlag = FALSE,
- VerFlag = FALSE,
- IsoLinesFlag = FALSE,
- SamplesPerCurveFlag = FALSE,
- NumFiles = 0,
- FineNessFlag = FALSE;
- char
- **FileNames = NULL;
- IPObjectStruct *PObjects;
-
- SaveTotalTime = time(NULL);
-
- #ifdef __MSDOS__
- ctrlbrk((int cdecl (*)()) MyExit); /* Kill process if ^C. */
- #endif /* __MSDOS__ */
-
- #ifdef __MSDOS__
- MathErrorSetUp(ME_KILL, NULL); /* Kill process if math error occurs! */
- #endif /* __MSDOS__ */
-
- Config("poly3d", SetUp, NUM_SET_UP); /* Read config. file if exists. */
-
- if ((Error = GAGetArgs(argc, argv, CtrlStr,
- &GlblClosedObject, &GlblMore, &GlblInternal, &EdgesFlag,
- &GlblNumEdges, &GlblDrawVNormal, &GlblDrawPNormal,
- &GlblDrawSurfaceMesh, &GlblDrawSurfacePoly,
- &IsoLinesFlag, &GlblNumOfIsolines,
- &SamplesPerCurveFlag, &GlblSamplesPerCurve,
- &FineNessFlag, &GlblFineNess,
- &GlblFourPerFlat, &VerFlag, &NumFiles, &FileNames)) != 0) {
- GAPrintErrMsg(Error);
- GAPrintHowTo(CtrlStr);
- exit(1);
- }
-
- if (VerFlag) {
- fprintf(stderr, "\n%s\n\n", VersionStr);
- GAPrintHowTo(CtrlStr);
- ConfigPrint(SetUp, NUM_SET_UP);
- exit(0);
- }
-
- if (!NumFiles) {
- fprintf(stderr, "No data file names where given, exit.\n");
- GAPrintHowTo(CtrlStr);
- exit(1);
- }
-
- GlblNormalLen = ((RealType) GlblNormalLenAux) / NORMAL_SCALER_LENGTH;
-
- strcpy(GlblFirstDataFileName, FileNames[0]);/* Save name of first file. */
-
- /* Get the data files: */
- IritPrsrPolyListCirc = FALSE;
- PObjects = MainGetDataFiles(FileNames, NumFiles);
- if (GlblViewMode != VIEW_PERSPECTIVE)
- GlblViewMode = IritPrsrWasPrspMat ? VIEW_PERSPECTIVE :
- VIEW_ORTHOGRAPHIC;
-
- /* If no limit on num of edges set to maximum. Else increase count by */
- /* one as we count vertices and n vertices bounds n-1 edges. */
- if (GlblNumEdges == 0)
- GlblNumEdges = 32767;
- else
- GlblNumEdges++;
-
- #ifdef __MSDOS__
- GGInstallBGI(BGIDriverPath, SVGANameMode);
- GGInitGraph(GlblGraphDriver, TRUE); /* Initiate the graphic driver. */
- #else
- #ifdef DJGCC
- GGInitGraph(0, TRUE); /* Initiate the graphic driver. */
- #else
- GGInitGraph(argc, argv, TRUE, TRUE); /* Initiate the graphic driver. */
- #endif /* DJGCC */
- #endif /* __MSDOS__ */
-
- InteractGeomObject(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;
- char *ErrorMsg;
- FILE *f;
- IPObjectStruct *PObj, *PObjTail,
- *PObjHead = NULL;
-
- for (i = 0; i < NumOfDataFiles; i++) {
- if (GlblMore) fprintf(stderr, "Reading data file %s\n", *DataFileNames);
- #if defined(__MSDOS__) || defined(DJGCC)
- if ((f = fopen(*DataFileNames, "rt")) == NULL) { /* Open the file. */
- #else
- if ((f = fopen(*DataFileNames, "r")) == NULL) { /* Open the file. */
- #endif /* __MSDOS__ || DJGCC */
- fprintf(stderr, "Can't open data file %s\n", *DataFileNames);
- exit(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");
- exit(1);
- }
-
- 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 polylines are saved in the appropriate *
- * surface/curve slots. *
- *****************************************************************************/
- IPObjectStruct *IritPrsrProcessFreeForm(IPObjectStruct *CrvObjs,
- IPObjectStruct *SrfObjs)
- {
- CagdCrvStruct *Crv, *Crvs;
- CagdSrfStruct *Srf, *Srfs;
- IPObjectStruct *PObj, *PPolyObj;
- IPPolygonStruct *PPolygon, *PPolygonTemp;
-
- if (CrvObjs == NULL && SrfObjs == NULL) return NULL;
-
- /* Make sure requested format is something reasonable. */
- if (GlblNumOfIsolines < 2) {
- GlblNumOfIsolines = 2;
- if (GlblMore)
- fprintf(stderr,
- "NumOfIsolines is less than 2, 2 picked instead.\n");
- }
-
- if (GlblSamplesPerCurve < 1) {
- GlblSamplesPerCurve = 1;
- if (GlblMore)
- fprintf(stderr,
- "SamplesPerCurve is less than 1, 1 picked instead.\n");
- }
- if (GlblSamplesPerCurve > CAGD_MAX_BEZIER_CACHE_ORDER) {
- GlblSamplesPerCurve = CAGD_MAX_BEZIER_CACHE_ORDER;
- if (GlblMore)
- fprintf(stderr,
- "Log2 SamplesPerCurve is more than %d, %d picked instead.\n",
- CAGD_MAX_BEZIER_CACHE_ORDER, CAGD_MAX_BEZIER_CACHE_ORDER);
- }
- BzrCrvSetCache(GlblSamplesPerCurve, TRUE); /* Set up the bezier cache. */
-
- if (CrvObjs) {
- for (PObj = CrvObjs; PObj != NULL; PObj = PObj -> Pnext) {
- Crvs = PObj -> U.PCrvs;
- PObj -> FFPolylines = PPolyObj = IritPrsrNewObjectStruct();
- *PPolyObj = *PObj; /* Copy all its attributes. */
- PPolyObj -> U.PPolygon = NULL;
- PPolyObj -> Type = IP_OBJ_POLY;
- for (Crv = Crvs; Crv != NULL; Crv = Crv -> Pnext) {
- PPolygon = PPolygonTemp = Curve2Polylines(Crv);
- while (PPolygonTemp -> Pnext)
- PPolygonTemp = PPolygonTemp -> Pnext;
- PPolygonTemp -> Pnext = PPolyObj -> U.PPolygon;
- PPolyObj -> U.PPolygon = PPolygon;
- }
- }
- }
-
- if (SrfObjs) {
- for (PObj = SrfObjs; PObj != NULL; PObj = PObj -> Pnext) {
- Srfs = PObj -> U.PSrfs;
- PObj -> FFPolylines = PPolyObj = IritPrsrNewObjectStruct();
- *PPolyObj = *PObj; /* Copy all its attributes. */
- PPolyObj -> U.PPolygon = NULL;
- PPolyObj -> Type = IP_OBJ_POLY;
- for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
- PPolygon = PPolygonTemp = Surface2Polylines(Srf);
- while (PPolygonTemp -> Pnext)
- PPolygonTemp = PPolygonTemp -> Pnext;
- PPolygonTemp -> Pnext = PPolyObj -> U.PPolygon;
- PPolyObj -> U.PPolygon = PPolygon;
- }
- /* IF polygons were actually created, make sure we would not */
- /* create then again... */
- if (GlblDrawSurfacePoly)
- PObj -> FFPolygons = PObj -> FFPolylines;
- }
- }
-
- 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, n;
- IPVertexStruct *V,
- *VHead = NULL,
- *VTail = NULL;
- IPPolygonStruct *P,
- *PHead = NULL;
- CagdPolylineStruct *CagdPoly,
- *CagdPolyHead = CagdCrv2Polyline(Crv, GlblSamplesPerCurve);
-
- if (GlblDrawSurfaceMesh) {
- CagdPoly = CagdCrv2CtrlPoly(Crv);
- CagdPoly -> Pnext = CagdPolyHead;
- CagdPolyHead = CagdPoly;
- }
-
- for (CagdPoly = CagdPolyHead;
- CagdPoly != NULL;
- CagdPoly = CagdPoly -> Pnext) {
- n = CagdPoly -> Length;
-
- for (i = 0, VHead = NULL; i < n; i++) { /* Convert to vertices. */
- V = IritPrsrNewVertexStruct();
-
- for (j = 0; j < 3; j++) /* Convert to our format. */
- V -> Coord[j] = CagdPoly -> Polyline[i].Pt[j];
-
- if (VHead) {
- VTail -> Pnext = V;
- VTail = V;
- }
- else
- VHead = VTail = V;
- }
-
- P = IritPrsrNewPolygonStruct();
- P -> PVertex = VHead;
- P -> Type = IP_POLYLINE;
-
- P -> Pnext = PHead;
- PHead = P;
- }
-
- CagdPolylineFreeList(CagdPoly);
-
- return PHead;
- }
-
- #ifdef __GL__
-
- /*****************************************************************************
- * Routine to convert a single surface into polygons with GlblFineNess as *
- * sample control, and GlblFourPerFlat controlling # of polys per bilinear. *
- *****************************************************************************/
- IPPolygonStruct *Surface2Polygons(CagdSrfStruct *Srf)
- {
- int i, j;
- IPVertexStruct *V, *VHead,
- *VTail = NULL;
- IPPolygonStruct *P,
- *PHead = NULL;
- CagdPolygonStruct *CagdPolygon,
- *CagdPolygonHead = CagdSrf2Polygons(Srf, 1 << GlblFineNess, TRUE,
- GlblFourPerFlat);
-
- for (CagdPolygon = CagdPolygonHead, VHead = NULL;
- CagdPolygon != NULL;
- CagdPolygon = CagdPolygon -> Pnext) {
- /* All polygons are triangles! */
-
- for (i = 0, VHead = NULL; i < 3; i++) { /* Convert to vertices. */
- V = IritPrsrNewVertexStruct();
- IP_SET_VRTX_NORMAL(V); /* This vertex has normal. */
-
- for (j = 0; j < 3; j++) /* Convert to our format. */
- V -> Coord[j] = CagdPolygon -> Polygon[i].Pt[j];
- for (j = 0; j < 3; j++)
- V -> Normal[j] = CagdPolygon -> Normal[i].Vec[j];
-
- if (VHead) {
- VTail -> Pnext = V;
- VTail = V;
- }
- else
- VHead = VTail = V;
- }
-
- P = IritPrsrNewPolygonStruct();
- P -> PVertex = VHead;
- P -> Type = IP_POLYGON;
- P -> Pnext = PHead;
-
- PHead = P;
- }
-
- CagdPolygonFreeList(CagdPolygonHead);
-
- return PHead;
- }
-
- #endif /* __GL__ */
-
- /*****************************************************************************
- * Routine to convert a single surface into a polylines with SamplesPerCurve *
- * samples, NumOfIsolines isolines into a polyline object list. *
- * If surface is to be approximated as polygons GlblFineNess and *
- * GlblFourPerFlat controls this approximation. *
- *****************************************************************************/
- static IPPolygonStruct *Surface2Polylines(CagdSrfStruct *Srf)
- {
- int i, j, n;
- IPVertexStruct *V,
- *VHead = NULL,
- *VTail = NULL;
- IPPolygonStruct *P,
- *PHead = NULL;
- CagdPolylineStruct *CagdPolyline, *CagdPolylineTemp,
- *CagdPolylineHead = NULL;
- CagdPolygonStruct *CagdPolygon,
- *CagdPolygonHead = NULL;
-
- /* Note we compute normals in msdos only on demand. On unix we always */
- /* compute them as they are also used in shading. */
- if (GlblDrawSurfacePoly)
- CagdPolygonHead = CagdSrf2Polygons(Srf, 1 << GlblFineNess,
- #if defined(__MSDOS__) || defined(DJGCC)
- GlblDrawVNormal, GlblFourPerFlat);
- #else
- TRUE, GlblFourPerFlat);
- #endif /* __MSDOS__ || DJGCC */
-
- else
- CagdPolylineHead = CagdSrf2Polylines(Srf, GlblNumOfIsolines,
- GlblSamplesPerCurve);
-
- if (GlblDrawSurfaceMesh) {
- CagdPolyline = CagdPolylineTemp = CagdSrf2CtrlMesh(Srf);
- if (CagdPolylineTemp)
- while (CagdPolylineTemp -> Pnext)
- CagdPolylineTemp = CagdPolylineTemp -> Pnext;
- CagdPolylineTemp -> Pnext = CagdPolylineHead;
- CagdPolylineHead = CagdPolyline;
- }
-
- for (CagdPolyline = CagdPolylineHead;
- CagdPolyline != NULL;
- CagdPolyline = CagdPolyline -> Pnext) {
- n = CagdPolyline -> Length;
-
- for (i = 0, VHead = NULL; i < n; i++) { /* Convert to vertices. */
- V = IritPrsrNewVertexStruct();
-
- for (j = 0; j < 3; j++) /* Convert to our format. */
- V -> Coord[j] = CagdPolyline -> Polyline[i].Pt[j];
-
- if (VHead) {
- VTail -> Pnext = V;
- VTail = V;
- }
- else
- VHead = VTail = V;
- }
-
- P = IritPrsrNewPolygonStruct();
- P -> PVertex = VHead;
- P -> Type = IP_POLYLINE;
- P -> Pnext = PHead;
-
- PHead = P;
- }
-
- CagdPolylineFreeList(CagdPolylineHead);
-
- for (CagdPolygon = CagdPolygonHead, VHead = NULL;
- CagdPolygon != NULL;
- CagdPolygon = CagdPolygon -> Pnext) {
- /* All polygons are triangles! */
-
- for (i = 0, VHead = NULL; i < 3; i++) { /* Convert to vertices. */
- V = IritPrsrNewVertexStruct();
- IP_SET_VRTX_NORMAL(V); /* This vertex has normal. */
-
- for (j = 0; j < 3; j++) /* Convert to our format. */
- V -> Coord[j] = CagdPolygon -> Polygon[i].Pt[j];
- for (j = 0; j < 3; j++)
- V -> Normal[j] = CagdPolygon -> Normal[i].Vec[j] * GlblNormalLen;
-
- if (VHead) {
- VTail -> Pnext = V;
- VTail = V;
- }
- else
- VHead = VTail = V;
- }
-
- 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)
- {
- 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);
-
- GGCloseGraph(); /* Close the graphic driver. */
-
- fprintf(stderr, "CAGD_LIB: %s", ErrorMsg);
-
- exit(-1);
- }
-
- /*****************************************************************************
- * My exit routine. *
- *****************************************************************************/
- void MyExit(int ExitCode)
- {
- GGCloseGraph(); /* Close the graphic driver. */
-
- #ifdef __MSDOS__
- fprintf(stderr,
- "\nPoly3D: Total RealTime %ld seconds, Core left %ldk.\n",
- time(NULL) - SaveTotalTime, coreleft() / 1024);
- #else
- fprintf(stderr,
- "\nPoly3D: Total RealTime %ld seconds.\n",
- time(NULL) - SaveTotalTime);
- #endif /* __MSDOS__ */
-
- exit(ExitCode);
- }
-