home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / gfx / 3d / irit / contrib / poly3d-r / poly3d-r.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-19  |  14.1 KB  |  390 lines

  1. /*****************************************************************************
  2. *   Program to draw 3D object as solid objects in GIF image file format.     *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 3.0, Aug 1990    *
  5. *****************************************************************************/
  6.  
  7. #include <stdio.h>
  8. #include <math.h>
  9. #include <time.h>
  10. #include "program.h"
  11. #include "getarg.h"
  12. #include "genmat.h"
  13. #include "iritprsr.h"
  14. #include "ip_cnvrt.h"
  15. #include "config.h"
  16.  
  17. #ifdef __TURBOC__      /* Malloc debug routine - only on TC++ 1.0 and above. */
  18. #define __DEBUG_MALLOC__
  19. #endif /* __TURBOC__ */
  20.  
  21. #ifdef NO_CONCAT_STR
  22. static char *VersionStr =
  23.     "Poly3D-R    Version 5.0,    Gershon Elber,\n\
  24.     (C) Copyright 1989/90-95 Gershon Elber, Non commercial use only.";
  25. #else
  26. static char *VersionStr = "Poly3D-R    " VERSION ",    Gershon Elber,    "
  27.     __DATE__ ",  " __TIME__ "\n" COPYRIGHT ", Non commercial use only.";
  28. #endif /* NO_CONCAT_STR */
  29.  
  30. static char *CtrlStr =
  31. #ifdef DOUBLE
  32.     "poly3d-r a%-Ambient!F c%-N!d l%-X|Y|Z!F!F!F 2%- m%- 4%- F%-PolyOpti|FineNess!d!F s%-Xsize|Ysize!d!d S%-SubSample!d g%- b%- M%-Mask!s z%- DFiles!*s";
  33. #else
  34.     "poly3d-r a%-Ambient!f c%-N!d l%-X|Y|Z!f!f!f 2%- m%- 4%- F%-PolyOpti|FineNess!d!f s%-Xsize|Ysize!d!d S%-SubSample!d g%- b%- M%-Mask!s z%- DFiles!*s";
  35. #endif /* DOUBLE */
  36.  
  37. static long SaveTotalTime;
  38. static GifColorType MaskColorMap[2] = {     /* Boolean mask GIF file color map. */
  39.     {   0,   0,   0 },
  40.     { 255, 255, 255 }
  41. };
  42. /* Fineness surface subdivision control. */
  43. static int
  44.     GlblFourPerFlat = FALSE,
  45.     GlblOptimalPolyApprox = FALSE;
  46.  
  47. int GlblNumOfPolys = 0;         /* Total number of polygons scan converted. */
  48. int GlblNumOfVerts = 0;                /* Total number of vertices. */
  49. MatrixType GlblViewMat;                  /* Current view of object. */
  50.  
  51. /* Amount scene was scaled up from normalized [-1..1] size on both X & Y: */
  52. static RealType
  53.     GlblFineNess = DEFAULT_FINENESS,
  54.     GlblScaleUpFctr = 0.0;
  55.  
  56. /* The following are setable variables (via configuration file poly3d-h.cfg).*/
  57. int GlblMore = FALSE;
  58.  
  59. ShadeInfoStruct GlblShadeInfo = {
  60.     1,                           /* Sub samples per pixel. */
  61.     DEFAULT_BITS_PER_PIXEL,
  62.     0,
  63.     DEFAULT_COLOR,
  64.     DEFAULT_BACK_GROUND_COLOR,
  65.     FALSE,                        /* No two light sources. */
  66.     DEFAULT_SCREEN_XSIZE,
  67.     DEFAULT_SCREEN_YSIZE,
  68.     FALSE,                          /* No Gouraud shading. */
  69.     FALSE,                      /* No back facing deletion. */
  70.     NULL,
  71.     NULL,                        /* No color map yet. */
  72.     DEFAULT_LIGHT_SOURCE,
  73.     DEFAULT_AMBIENT,
  74.     DEFAULT_NORMAL_AVG_DEGREE
  75. };
  76.  
  77. static ConfigStruct SetUp[] = {
  78.   { "Ambient",      "-a", (VoidPtr) &GlblShadeInfo.Ambient,    SU_REAL_TYPE },
  79.   { "LightSrcX",  "-l", (VoidPtr) &GlblShadeInfo.LightSource[0],SU_REAL_TYPE },
  80.   { "LightSrcY",  "-l", (VoidPtr) &GlblShadeInfo.LightSource[1],SU_REAL_TYPE },
  81.   { "LightSrcZ",  "-l", (VoidPtr) &GlblShadeInfo.LightSource[2],SU_REAL_TYPE },
  82.   { "AvgDegree",  "",   (VoidPtr) &GlblShadeInfo.NrmlAvgDegree,    SU_REAL_TYPE },
  83.   { "FineNess",      "-F", (VoidPtr) &GlblFineNess,        SU_REAL_TYPE },
  84.   { "TwoSources", "-2", (VoidPtr) &GlblShadeInfo.TwoSources,    SU_BOOLEAN_TYPE },
  85.   { "Gouraud",      "-g", (VoidPtr) &GlblShadeInfo.Gouraud,    SU_BOOLEAN_TYPE },
  86.   { "backFacing", "-b", (VoidPtr) &GlblShadeInfo.BackFacing,    SU_BOOLEAN_TYPE },
  87.   { "SubSample",  "-S", (VoidPtr) &GlblShadeInfo.SubSamplePixel,SU_INTEGER_TYPE },
  88.   { "BitsPerPixel","-c",(VoidPtr) &GlblShadeInfo.BitsPerPixel,    SU_INTEGER_TYPE },
  89.   { "Color",      "", (VoidPtr) &GlblShadeInfo.DefaultColor,    SU_INTEGER_TYPE },
  90.   { "BackGroundColor","",(VoidPtr) &GlblShadeInfo.BackGroundColor,SU_INTEGER_TYPE },
  91.   { "Xsize",      "-s", (VoidPtr) &GlblShadeInfo.ScrnXSize,    SU_INTEGER_TYPE },
  92.   { "Ysize",      "-s", (VoidPtr) &GlblShadeInfo.ScrnYSize,    SU_INTEGER_TYPE },
  93.   { "More",      "-m", (VoidPtr) &GlblMore,            SU_BOOLEAN_TYPE },
  94.   { "FourPerFlat","-4", (VoidPtr) &GlblFourPerFlat,        SU_BOOLEAN_TYPE },
  95.   { "PolyOpti",   "-F", (VoidPtr) &GlblOptimalPolyApprox,    SU_INTEGER_TYPE },
  96. };
  97. #define NUM_SET_UP    (sizeof(SetUp) / sizeof(ConfigStruct))
  98.  
  99. /* All polygons to be scan convert will be inserted into this hash table     */
  100. /* during the preprocessing (PrepareXXXX functions).                 */
  101. IPPolygonStruct **PolyHashTable;
  102.  
  103. /*****************************************************************************
  104. * Main routine - Read Parameter    line and do what you need...             *
  105. *****************************************************************************/
  106. void main(int argc, char **argv)
  107. {
  108.     int AmbientFlag = FALSE,
  109.     ColorFlag = FALSE,
  110.     LightSrcFlag = FALSE,
  111.     GifMaskFlag = FALSE,
  112.     VerFlag = FALSE,
  113.     NumFiles = 0,
  114.     ImageSizeFlag = FALSE,
  115.     SubSampleFlag = FALSE,
  116.     OptPolyApproxFlag = FALSE,
  117.     Error;
  118.     char *GifMaskName,
  119.     **FileNames = NULL;
  120.     RealType Size, Scale;
  121.     MatrixType Mat;
  122.     IPObjectStruct *PObjects;
  123.     GifFileType *GifFile,
  124.     *GifMask = NULL;
  125.  
  126.     SaveTotalTime = time(NULL);                  /* Save starting time. */
  127.  
  128.     Config("poly3d-r", SetUp, NUM_SET_UP);   /* Read config. file if exists. */
  129.  
  130.     if ((Error = GAGetArgs (argc, argv, CtrlStr,
  131.         &AmbientFlag, &GlblShadeInfo.Ambient,
  132.         &ColorFlag, &GlblShadeInfo.BitsPerPixel, &LightSrcFlag,
  133.         &GlblShadeInfo.LightSource[0],
  134.         &GlblShadeInfo.LightSource[1],
  135.         &GlblShadeInfo.LightSource[2],
  136.         &GlblShadeInfo.TwoSources, &GlblMore, &GlblFourPerFlat,
  137.         &OptPolyApproxFlag, &GlblOptimalPolyApprox, &GlblFineNess,
  138.         &ImageSizeFlag, &GlblShadeInfo.ScrnXSize,
  139.         &GlblShadeInfo.ScrnYSize, &SubSampleFlag,
  140.         &GlblShadeInfo.SubSamplePixel, &GlblShadeInfo.Gouraud,
  141.         &GlblShadeInfo.BackFacing, &GifMaskFlag, &GifMaskName,
  142.         &VerFlag, &NumFiles, &FileNames)) != 0) {
  143.     GAPrintErrMsg(Error);
  144.     GAPrintHowTo(CtrlStr);
  145.     Poly3drExit(1);
  146.     }
  147.  
  148.     if (GlblShadeInfo.Ambient < 0.0 || GlblShadeInfo.Ambient > 1.0) {
  149.     fprintf(stderr,
  150.             "Ambient light specified not in [0.0..1.0] range, %f selected instead.\n",
  151.         DEFAULT_AMBIENT);
  152.     GlblShadeInfo.Ambient = DEFAULT_AMBIENT;
  153.     }
  154.     if (GlblShadeInfo.BitsPerPixel < 1 || GlblShadeInfo.BitsPerPixel > 8) {
  155.     fprintf(stderr,
  156.             "PitsPerPixel not in [1..8] range, %d selected instead.\n",
  157.         DEFAULT_BITS_PER_PIXEL);
  158.     GlblShadeInfo.BitsPerPixel = DEFAULT_BITS_PER_PIXEL;
  159.     }
  160.  
  161.     Size = sqrt(SQR(GlblShadeInfo.LightSource[0]) +
  162.         SQR(GlblShadeInfo.LightSource[1]) +
  163.         SQR(GlblShadeInfo.LightSource[2]));
  164.     if (ABS(Size) < EPSILON) {
  165.     fprintf(stderr, "Light source vector is zero, Z axis selected instead.\n");
  166.     GlblShadeInfo.LightSource[0] =
  167.     GlblShadeInfo.LightSource[1] = 0.0;
  168.     GlblShadeInfo.LightSource[2] = 1.0;
  169.     }
  170.     else {
  171.     GlblShadeInfo.LightSource[0] /= Size;
  172.     GlblShadeInfo.LightSource[1] /= Size;
  173.     GlblShadeInfo.LightSource[2] /= Size;
  174.     }
  175.  
  176.     if (VerFlag) {
  177.     fprintf(stderr, "\n%s\n\n", VersionStr);
  178.     GAPrintHowTo(CtrlStr);
  179.     ConfigPrint(SetUp, NUM_SET_UP);
  180.     Poly3drExit(0);
  181.     }
  182.  
  183.     if (!NumFiles) {
  184.     fprintf(stderr, "No data file names were given, exit.\n");
  185.     GAPrintHowTo(CtrlStr);
  186.     Poly3drExit(1);
  187.     }
  188.  
  189.     if (SubSampleFlag) {
  190.     if (GlblShadeInfo.SubSamplePixel < 1 || GlblShadeInfo.SubSamplePixel > 4) {
  191.         fprintf(stderr, "Sub sampling can be 1 to 4 only (1x1 to 4x4).\n");
  192.         GAPrintHowTo(CtrlStr);
  193.         Poly3drExit(1);
  194.     }
  195.     }
  196.  
  197.     /* Get the data files: */
  198.     if ((PObjects = IritPrsrGetDataFiles(FileNames, NumFiles, TRUE,
  199.                      GlblMore)) == NULL)
  200.     Poly3drExit(1);
  201.  
  202.     /* Compute the viewing matrices and related data: */
  203.     if (IritPrsrWasPrspMat)
  204.     MatMultTwo4by4(GlblViewMat, IritPrsrViewMat, IritPrsrPrspMat);
  205.     else
  206.     GEN_COPY(GlblViewMat, IritPrsrViewMat, sizeof(MatrixType));
  207.  
  208.     /* Now its time to scale the normalized image (+/-1 on both X & Y) to    */
  209.     /* size specified by the image dimensions. We scale up to the SMALLER    */
  210.     /* dimension, and put the center at the image center.             */
  211.     /* Also, as the GIF image starts at the top, we must flip the image      */
  212.     /* along Y axis.                                 */
  213.     GlblScaleUpFctr = Scale = MIN(GlblShadeInfo.ScrnXSize *
  214.                   GlblShadeInfo.SubSamplePixel,
  215.                   GlblShadeInfo.ScrnYSize *
  216.                   GlblShadeInfo.SubSamplePixel) / 2.0;
  217.     MatGenMatScale(Scale, -Scale, Scale, Mat);
  218.     MatMultTwo4by4(GlblViewMat, GlblViewMat, Mat);
  219.     MatGenMatTrans(GlblShadeInfo.ScrnXSize * GlblShadeInfo.SubSamplePixel / 2.0,
  220.            GlblShadeInfo.ScrnYSize * GlblShadeInfo.SubSamplePixel / 2.0,
  221.            0.0, Mat);
  222.     MatMultTwo4by4(GlblViewMat, GlblViewMat, Mat);
  223.  
  224.     /* Prepare data structures of objects themselves: */
  225.     PrepareViewData(PObjects);
  226.  
  227.     /* Into shadingInfo global structure: */
  228.     PrepareColorTable(PObjects);
  229.  
  230.     EvalVrtxColors(PObjects);
  231.  
  232. #ifndef DEBUG_NO_GIF
  233.  
  234.     /* Open stdout for the GIF image file: */
  235.     if ((GifFile = EGifOpenFileHandle(1)) == NULL ||
  236.     EGifPutScreenDesc(GifFile,
  237.         GlblShadeInfo.ScrnXSize, GlblShadeInfo.ScrnYSize,
  238.         GlblShadeInfo.BitsPerPixel, 0,
  239.         GlblShadeInfo.BitsPerPixel, GlblShadeInfo.PColorMap) ==
  240.                                 GIF_ERROR ||
  241.     EGifPutImageDesc(GifFile,
  242.         0, 0, GlblShadeInfo.ScrnXSize, GlblShadeInfo.ScrnYSize, FALSE,
  243.         GlblShadeInfo.BitsPerPixel, NULL) == GIF_ERROR)
  244.     QuitGifError();
  245.     /* Open special mask file if required: */
  246.     if (GifMaskFlag &&
  247.     ((GifMask = EGifOpenFileName(GifMaskName, FALSE)) == NULL ||
  248.      EGifPutScreenDesc(GifMask,
  249.                GlblShadeInfo.ScrnXSize, GlblShadeInfo.ScrnYSize,
  250.                1, 0, 1, MaskColorMap) == GIF_ERROR ||
  251.      EGifPutImageDesc(GifMask, 0, 0,
  252.               GlblShadeInfo.ScrnXSize, GlblShadeInfo.ScrnYSize,
  253.               FALSE, 1, NULL) == GIF_ERROR))
  254.     QuitGifError();
  255.  
  256. #endif /* DEBUG_NO_GIF */
  257.  
  258.     ScanConvertData(GifFile, GifMask);     /* Do the real interesting stuff... */
  259.  
  260. #ifndef DEBUG_NO_GIF
  261.  
  262.     EGifCloseFile(GifFile);
  263.     if (GifMask)
  264.     EGifCloseFile(GifMask);
  265.  
  266. #endif /* DEBUG_NO_GIF */
  267.  
  268.     Poly3drExit(0);
  269. }
  270.  
  271. /*****************************************************************************
  272. * DESCRIPTION:                                                               M
  273. * Routine to convert all surfaces/curves into polylines as follows:         M
  274. *   Curve is converted to a single polyline with SamplesPerCurve samples.    M
  275. *   Surface is converted into GlblNumOfIsolines curves in each axes, each    M
  276. * handled as Curve above. The original curves and surfaces are then deleted. M
  277. *   This function is a call back function of the irit parser.             M
  278. *                                                                            *
  279. * PARAMETERS:                                                                M
  280. *   FreeForms:  Crvs/Srfs/Trimmed Srfs/Trivariates read from a file by the   M
  281. *               irit parser.                                 M
  282. *                                                                            *
  283. * RETURN VALUE:                                                              M
  284. *   IPObjectStruct *:   Processed freeform geometry. This function simply    M
  285. *                       returns what it gots.                                M
  286. *                                                                            *
  287. * KEYWORDS:                                                                  M
  288. *   IritPrsrProcessFreeForm, conversion                                      M
  289. *****************************************************************************/
  290. IPObjectStruct *IritPrsrProcessFreeForm(IritPrsrFreeFormStruct *FreeForms)
  291. {
  292.     CagdCrvStruct *Crvs;
  293.     CagdSrfStruct *Srf, *Srfs;
  294.     IPObjectStruct *PObj, *PObjNext,
  295.     *CrvObjs = FreeForms -> CrvObjs,
  296.     *SrfObjs = FreeForms -> SrfObjs;
  297.     IPPolygonStruct *PPolygon, *PPolygonTemp;
  298.  
  299.     if (CrvObjs == NULL && SrfObjs == NULL)
  300.     return NULL;
  301.  
  302.     /* Make sure requested format is something reasonable. */
  303.     if (GlblOptimalPolyApprox == 0 && GlblFineNess < 2) {
  304.     GlblFineNess = 2;
  305.     if (GlblMore)
  306.         fprintf(stderr, "FineNess is less than 2, 2 picked instead.\n");
  307.     }
  308.  
  309.     if (CrvObjs) {
  310.     /* Curves are not rendered at this time and they are ignored. */
  311.     for (PObj = CrvObjs; PObj != NULL;) {
  312.         Crvs = PObj -> U.Crvs;
  313.         CagdCrvFreeList(Crvs);
  314.         PObjNext = PObj -> Pnext;
  315.         IPFreeObject(PObj);
  316.         PObj = PObjNext;
  317.     }
  318.     CrvObjs = NULL;
  319.     }
  320.  
  321.     if (SrfObjs) {
  322.     for (PObj = SrfObjs; PObj != NULL; PObj = PObj -> Pnext) {
  323.         Srfs = PObj -> U.Srfs;
  324.         PObj -> U.Pl = NULL;
  325.         PObj -> ObjType = IP_OBJ_POLY;
  326.         IP_SET_POLYGON_OBJ(PObj);
  327.  
  328.         for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
  329.         PPolygon = PPolygonTemp =
  330.             IritSurface2Polygons(Srf, GlblFourPerFlat, GlblFineNess,
  331.                      TRUE, GlblOptimalPolyApprox);
  332.  
  333.         if (PPolygon != NULL) {
  334.             while (PPolygonTemp -> Pnext)
  335.             PPolygonTemp = PPolygonTemp -> Pnext;
  336.             PPolygonTemp -> Pnext = PObj -> U.Pl;
  337.             PObj -> U.Pl = PPolygon;
  338.         }
  339.         }
  340.         CagdSrfFreeList(Srfs);
  341.     }
  342.     }
  343.  
  344.     return SrfObjs;
  345. }
  346.  
  347. /*****************************************************************************
  348. * Poly3d-r Exit routine. Note it might call to CloseGraph without calling    *
  349. * InitGraph(), or call MouseClose() without MouseInit(), or call         *
  350. * RestoreCtrlBrk() without SetUpCtrlBrk() and it is the responsibility         *
  351. * of the individual modules to do nothing in these cases.             *
  352. *****************************************************************************/
  353. void Poly3drExit(int ExitCode)
  354. {
  355.     fprintf(stderr,
  356.     "\nPoly3D-R: Total RealTime %ld seconds.\n",
  357.         time(NULL) - SaveTotalTime);
  358.  
  359.     exit(ExitCode);
  360. }
  361.  
  362. /******************************************************************************
  363. * Close output file (if open), and exit.                      *
  364. ******************************************************************************/
  365. void QuitGifError(void)
  366. {
  367.     PrintGifError();
  368.     Poly3drExit('G');
  369. }
  370.  
  371. #ifdef DEBUG
  372.  
  373. /*****************************************************************************
  374. * DESCRIPTION:                                                               *
  375. *    Dummy function to link at debugging time.                               *
  376. *                                                                            *
  377. * PARAMETERS:                                                                *
  378. *                                                                            *
  379. * RETURN VALUE:                                                              *
  380. *   void                                                                     *
  381. *                                                                            *
  382. * KEYWORDS:                                                                  *
  383. *****************************************************************************/
  384. void DummyLinkCagdDebug(void)
  385. {
  386.     IritPrsrDbg();
  387. }
  388.  
  389. #endif /* DEBUG */
  390.