home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * Filter to convert IRIT data files to ray shade format. *
- * *
- * Written by: Gershon Elber Ver 1.0, Sep 1991 *
- *****************************************************************************/
-
- #ifdef __MSDOS__
- #include <dos.h>
- #include <alloc.h>
- #endif /* __MSDOS__ */
-
- #include <stdio.h>
- #include <math.h>
- #include <string.h>
- #include <time.h>
- #include "irit_sm.h"
- #include "iritprsr.h"
- #include "getarg.h"
- #include "genmat.h"
-
- #define DIST_EPSILON 2e-4
- #define SIZE_EPSILON 1e-5
- #define CONVEX_EPSILON 1e-3
-
- #ifdef __MSDOS__
- extern unsigned int _stklen = 32766; /* Increase default stack size. */
- #endif /* __MSDOS__ */
-
- #ifdef NO_CONCAT_STR
- static char *VersionStr =
- "Irit2Ray Version 3.0, Gershon Elber,\n\
- (C) Copyright 1989/90/91 Gershon Elber, Non commercial use only.";
- #else
- static char *VersionStr = "Irit2Ray " VERSION ", Gershon Elber, "
- __DATE__ ", " __TIME__ "\n"
- "(C) Copyright 1989/90/91 Gershon Elber, Non commercial use only.";
- #endif /* NO_CONCAT_STR */
-
- static char
- *CtrlStr = "irit2ray l%- 4%- G%-GridSize!d f%-FineNess!d o%-OutName!s g%- z%- DFiles!*s";
- static char
- *OutFileName = "irit2ray";
-
- static int
- GlblGridSize = 5,
- GlblGridFlag = FALSE,
- GlblFineNess = 5,
- GlblDumpOnlyGeometry = FALSE,
- FourPerFlat = FALSE;
-
- static MatrixType CrntViewMat; /* This is the current view! */
-
- static int TransColorTable[][4] = {
- { /* BLACK */ 0, 0, 0, 0 },
- { /* BLUE */ 1, 0, 0, 255 },
- { /* GREEN */ 2, 0, 255, 0 },
- { /* CYAN */ 3, 0, 255, 255 },
- { /* RED */ 4, 255, 0, 0 },
- { /* MAGENTA */ 5, 255, 0, 255 },
- { /* BROWN */ 6, 50, 0, 0 },
- { /* LIGHTGRAY */ 7, 127, 127, 127 },
- { /* DARKGRAY */ 8, 63, 63, 63 },
- { /* LIGHTBLUE */ 9, 0, 0, 255 },
- { /* LIGHTGREEN */ 10, 0, 255, 0 },
- { /* LIGHTCYAN */ 11, 0, 255, 255 },
- { /* LIGHTRED */ 12, 255, 0, 0 },
- { /* LIGHTMAGENTA */ 13, 255, 0, 255 },
- { /* YELLOW */ 14, 255, 255, 0 },
- { /* WHITE */ 15, 255, 255, 255 },
- { /* BROWN */ 20, 50, 0, 0 },
- { /* DARKGRAY */ 56, 63, 63, 63 },
- { /* LIGHTBLUE */ 57, 0, 0, 255 },
- { /* LIGHTGREEN */ 58, 0, 255, 0 },
- { /* LIGHTCYAN */ 59, 0, 255, 255 },
- { /* LIGHTRED */ 60, 255, 0, 0 },
- { /* LIGHTMAGENTA */ 61, 255, 0, 255 },
- { /* YELLOW */ 62, 255, 255, 0 },
- { /* WHITE */ 63, 255, 255, 255 },
- { -1, 0, 0, 0 }
- };
-
- static IPObjectStruct *MainGetDataFiles(char **DataFileNames,
- int NumOfDataFiles);
- static IPPolygonStruct *Surface2Polygons(CagdSrfStruct *Srf, int FourPerFlat,
- int FineNess);
- static void DumpDataForRayShade(IPObjectStruct *PObjects);
- static int DumpOneObject(FILE *FRay, FILE *FGeom, IPObjectStruct *PObject);
- static int DumpOnePolygon(FILE *f, IPPolygonStruct *PPolygon);
- static int IsConvexPolygon(IPPolygonStruct *Pl);
- static RealType *MapPoint(RealType *Pt);
- static RealType *MapVector(RealType *Pt, RealType *Vec);
- static void MyExit(int ExitCode);
-
- /*****************************************************************************
- * Main routine - Read Parameter line and do what you need... *
- *****************************************************************************/
- void main(int argc, char **argv)
- {
- int Error,
- FineNessFlag = FALSE,
- LinearOnePolyFlag = FALSE,
- VerFlag = FALSE,
- OutFileFlag = FALSE,
- NumFiles = 0;
- char Line[LINE_LEN_LONG], *p,
- **FileNames = NULL;
- IPObjectStruct *PObjects;
-
- #ifdef __MSDOS__
- ctrlbrk((int (*)()) MyExit); /* Kill process if ^C. */
- #endif /* __MSDOS__ */
-
- if ((Error = GAGetArgs (argc, argv, CtrlStr, &LinearOnePolyFlag,
- &FourPerFlat, &GlblGridFlag, &GlblGridSize,
- &FineNessFlag, &GlblFineNess, &OutFileFlag,
- &OutFileName, &GlblDumpOnlyGeometry,
- &VerFlag, &NumFiles, &FileNames)) != 0) {
- GAPrintErrMsg(Error);
- GAPrintHowTo(CtrlStr);
- MyExit(1);
- }
-
- if (VerFlag) {
- fprintf(stderr, "\n%s\n\n", VersionStr);
- GAPrintHowTo(CtrlStr);
- MyExit(0);
- }
-
- if (LinearOnePolyFlag) {
- fprintf(stderr, "Linear patch side will have a single polygon.\n");
- CagdSetLinear2Poly(CAGD_ONE_POLY_PER_COLIN);
- }
- else
- CagdSetLinear2Poly(CAGD_REG_POLY_PER_LIN);
-
- fprintf(stderr, "%s triangles per flat will be created.\n",
- FourPerFlat ? "Four" : "Two");
-
- if (!NumFiles) {
- fprintf(stderr, "No data file names where given, exit.\n");
- GAPrintHowTo(CtrlStr);
- MyExit(1);
- }
-
- if (!OutFileFlag) { /* Pick the first input name as output name. */
- strcpy(Line, FileNames[0]);
- if ((p = strrchr(Line, '.')) != NULL); /* Remove old file type. */
- *p = 0;
- OutFileName = malloc(strlen(Line) + 1);
- strcpy(OutFileName, Line);
- }
-
- /* Get the data files: */
- IritPrsrPolyListCirc = FALSE;
- PObjects = MainGetDataFiles(FileNames, NumFiles);
-
- if (IritPrsrWasPrspMat)
- MultTwo4by4(CrntViewMat, IritPrsrViewMat, IritPrsrPrspMat);
- else
- GEN_COPY(CrntViewMat, IritPrsrViewMat, sizeof(MatrixType));
-
- DumpDataForRayShade(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;
- char
- *ErrorMsg = NULL;
- 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. */
-
- if (IritPrsrParseError(&ErrorMsg)) {
- fprintf(stderr, "Parse error in \"%s\":\n%s\n", *DataFileNames, ErrorMsg);
- MyExit(1);
- }
-
- DataFileNames++; /* Skip to next file name. */
- }
-
- if (PObjHead == NULL) {
- fprintf(stderr, "No data found.\n");
- MyExit(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 curves and surfaces are then deleted. *
- *****************************************************************************/
- IPObjectStruct *IritPrsrProcessFreeForm(IPObjectStruct *CrvObjs,
- IPObjectStruct *SrfObjs)
- {
- int LocalFourPerFlat;
- float RelativeFineNess;
- CagdCrvStruct *Crvs;
- CagdSrfStruct *Srf, *Srfs;
- IPObjectStruct *PObj, *PObjNext;
- IPPolygonStruct *PPolygon, *PPolygonTemp;
-
- if (CrvObjs == NULL && SrfObjs == NULL) return NULL;
-
- /* Make sure requested format is something reasonable. */
- if (GlblFineNess < 2) {
- GlblFineNess = 2;
- fprintf(stderr, "FineNess is less than 2, 2 picked instead.\n");
- }
-
- if (CrvObjs) {
- /* Curves are not rendered at this time and they are ignored. */
- for (PObj = CrvObjs; PObj != NULL;) {
- Crvs = PObj -> U.PCrvs;
- CagdCrvFreeList(Crvs);
- PObjNext = PObj -> Pnext;
- free((VoidPtr) PObj);
- PObj = PObjNext;
- }
- CrvObjs = NULL;
- }
-
- if (SrfObjs) {
- for (PObj = SrfObjs; PObj != NULL; PObj = PObj -> Pnext) {
- CagdBBoxStruct BBox, TempBBox;
- char GridStr[LINE_LEN], *p;
-
- Srfs = PObj -> U.PSrfs;
- PObj -> U.PPolygon = NULL;
-
- RelativeFineNess = 1.0;
- LocalFourPerFlat = FourPerFlat;
-
- if (IritPrsrGetStrAttrib(PObj, "twoperflat"))
- LocalFourPerFlat = FALSE;
- if (IritPrsrGetStrAttrib(PObj, "fourperflat"))
- LocalFourPerFlat = TRUE;
-
- if ((p = IritPrsrGetStrAttrib(PObj, "resolution")) != NULL &&
- sscanf(p, "%f", &RelativeFineNess) != 1)
- RelativeFineNess = 1.0;
-
- for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
- if (GlblGridFlag) {
- /* Generate bounding box to the surfaces and estimate */
- /* the grid size for it using GlblGridSize. */
- if (Srf == Srfs)
- CagdSrfBBox(Srf, &BBox);
- else {
- CagdSrfBBox(Srf, &TempBBox);
- CagdMergeBBox(&BBox, &TempBBox);
- }
- }
- PPolygon = PPolygonTemp =
- Surface2Polygons(Srf, LocalFourPerFlat,
- (int) (RelativeFineNess * GlblFineNess));
- while (PPolygonTemp -> Pnext)
- PPolygonTemp = PPolygonTemp -> Pnext;
- PPolygonTemp -> Pnext = PObj -> U.PPolygon;
- PObj -> U.PPolygon = PPolygon;
- }
- CagdSrfFreeList(Srfs);
-
- if (GlblGridFlag) {
- RealType
- Dx = BBox.Max[0] - BBox.Min[0],
- Dy = BBox.Max[1] - BBox.Min[1],
- Dz = BBox.Max[2] - BBox.Min[2],
- M = MAX(MAX(Dx, Dy), Dz);
- int IDx = (int) (GlblGridSize * (Dx / M)),
- IDy = (int) (GlblGridSize * (Dy / M)),
- IDz = (int) (GlblGridSize * (Dz / M));
-
- /* Save grid information derived from the surface bbox. */
- sprintf(GridStr, "%d %d %d",
- IDx > 0 ? IDx : 1,
- IDy > 0 ? IDy : 1,
- IDz > 0 ? IDz : 1);
- IritPrsrSetStrAttrib(PObj, "GridSize", GridStr);
- }
- }
- }
-
- return SrfObjs;
- }
-
- /*****************************************************************************
- * Routine to convert a single surface into a polylines with SamplesPerCurve *
- * samples, NumOfIsolines isolines into a polyline object list. *
- *****************************************************************************/
- static IPPolygonStruct *Surface2Polygons(CagdSrfStruct *Srf, int FourPerFlat,
- int FineNess)
- {
- int i, j;
- IPVertexStruct *V, *VHead,
- *VTail = NULL;
- IPPolygonStruct *P,
- *PHead = NULL;
- CagdPolygonStruct *CagdPolygon,
- *CagdPolygonHead = CagdSrf2Polygons(Srf, FineNess, TRUE, FourPerFlat);
-
- 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;
- }
-
- /*****************************************************************************
- * Dumps the data for ray shade into stdout. *
- *****************************************************************************/
- static void DumpDataForRayShade(IPObjectStruct *PObjects)
- {
- static char *Header1[] = {
- "/*",
- " * This file was automatically created from IRIT solid modeller data",
- " * using Irit2ray - IRIT to RayShade filter.",
- " *",
- " * (c) Copyright 1991/92 Gershon Elber, Non commercial use only.",
- " */",
- "",
- NULL
- };
- static char *Header2[] = {
- "",
- "eyep 0 0 10",
- "lookp 0 0 0",
- "up 0 1 0",
- "fov 12",
- "",
- "light 1 1 1 point 10 30 10",
- "",
- NULL
- };
- int i,
- TotalPolys = 0;
- char Line[128];
- IPObjectStruct *PObj,
- *PObjHead = NULL;
- FILE *FGeom, *FRay;
-
- sprintf(Line, "%s.ray", OutFileName);
- if (!GlblDumpOnlyGeometry) {
- if ((FRay = fopen(Line, "w")) == NULL) {
- fprintf(stderr, "Failed to open \"%s\".\n", Line);
- exit(2);
- }
- }
- else
- FRay = NULL;
-
- sprintf(Line, "%s.geom", OutFileName);
- if ((FGeom = fopen(Line, "w")) == NULL) {
- fprintf(stderr, "Failed to open \"%s\".\n", Line);
- exit(2);
- }
-
- if (FRay != NULL)
- for (i = 0; Header1[i] != NULL; i++)
- fprintf(FRay, "%s\n", Header1[i]);
- for (i = 0; Header1[i] != NULL; i++)
- fprintf(FGeom, "%s\n", Header1[i]);
-
- /* 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;
- }
- PObjects = PObjHead;
-
- while (PObjects) {
- TotalPolys += DumpOneObject(FRay, FGeom, PObjects);
- PObjects = PObjects -> Pnext;
- }
-
- if (FRay != NULL) {
- fprintf(FRay, "#include \"%s\"\n", Line);
- for (i = 0; Header2[i] != NULL; i++)
- fprintf(FRay, "%s\n", Header2[i]);
- fclose(FRay);
- }
-
- fclose(FGeom);
-
- fprintf(stderr, "\nTotal number of polygons - %d\n", TotalPolys);
- }
-
- /*****************************************************************************
- * Routine to dump one object PObject. *
- *****************************************************************************/
- static int DumpOneObject(FILE *FRay, FILE *FGeom, IPObjectStruct *PObject)
- {
- static int
- ObjectSeqNum = 1;
- int i, j,
- PolyCount = 0,
- HasColor = FALSE,
- HasSrfProp = FALSE;
- char *p, Name[LINE_LEN], SrfPropString[LINE_LEN_LONG];
- RealType RGBColor[3];
- IPPolygonStruct
- *PList = PObject -> U.PPolygon;
-
- if (strlen(PObject -> Name) == 0)
- sprintf(Name, "ObjSeq%d", ObjectSeqNum);
- else
- strcpy(Name, PObject -> Name);
-
- SrfPropString[0] = 0;
- for (i = 0; i < PObject -> Attrs.NumStrAttribs; i++)
- {
- if (strcmp(PObject -> Attrs.StrAttrName[i], "specpow") == 0 ||
- strcmp(PObject -> Attrs.StrAttrName[i], "reflect") == 0 ||
- strcmp(PObject -> Attrs.StrAttrName[i], "transp") == 0 ||
- strcmp(PObject -> Attrs.StrAttrName[i], "body") == 0 ||
- strcmp(PObject -> Attrs.StrAttrName[i], "index") == 0) {
- strcat(SrfPropString, PObject -> Attrs.StrAttrName[i]);
- strcat(SrfPropString, " ");
- strcat(SrfPropString, PObject -> Attrs.StrAttrData[i]);
- strcat(SrfPropString, " ");
- HasSrfProp = TRUE;
- }
- }
-
- if (GlblGridFlag) {
- char *GridStr = IritPrsrGetStrAttrib(PObject, "GridSize");
-
- if (GridStr != NULL)
- fprintf(FGeom, "name %s grid %s\n", Name, GridStr);
- else
- fprintf(FGeom, "name %s list\n", Name);
- }
- else
- fprintf(FGeom, "name %s list\n", Name);
-
- while (PList) {
- PolyCount += DumpOnePolygon(FGeom, PList);
- PList = PList -> Pnext;
- }
- fprintf(FGeom, "end\n");
-
- fprintf(stderr, "Processing \"%s\" - %d triangles.\n", Name, PolyCount);
-
- if ((p = IritPrsrGetStrAttrib(PObject, "rgb")) != NULL)
- {
- # ifdef __MSDOS__
- HasColor = sscanf(p, "%f,%f,%f",
- # else
- HasColor = sscanf(p, "%lf,%lf,%lf",
- # endif /* __MSDOS__ */
- &RGBColor[0], &RGBColor[1], &RGBColor[2]) == 3;
- }
- else if (IP_HAS_OBJ_RGB(PObject)) {
- HasColor = TRUE;
- for (i = 0; i < 3; i++) RGBColor[i] = PObject -> RGB[i];
- }
- else if (IP_HAS_OBJ_COLOR(PObject)) {
- for (i = 0; TransColorTable[i][0] >= 0; i++) {
- if (TransColorTable[i][0] == PObject -> Color) {
- HasColor = TRUE;
- for (j = 0; j < 3; j++) RGBColor[j] = TransColorTable[i][j+1];
- break;
- }
- }
- }
-
- if (HasColor || HasSrfProp) {
- if (FRay != NULL) {
- fprintf(FRay, "surface %sSrfProp\n", Name);
- if (HasColor) {
- for (i = 0; i < 3; i++) RGBColor[i] /= 255.0;
-
- fprintf(FRay, "\tambient %7.4lf %7.4lf %7.4lf\n",
- 0.1 * RGBColor[0],
- 0.1 * RGBColor[1],
- 0.1 * RGBColor[2]);
- fprintf(FRay, "\tdiffuse %7.4lf %7.4lf %7.4lf\n",
- 0.7 * RGBColor[0],
- 0.7 * RGBColor[1],
- 0.7 * RGBColor[2]);
- fprintf(FRay, "\tspecular %7.4lf %7.4lf %7.4lf\n",
- 0.8, 0.8, 0.8);
- }
- if (HasSrfProp)
- fprintf(FRay, "\t%s\n", SrfPropString);
- }
-
- fprintf(FGeom, "object %sSrfProp %s", Name, Name);
- }
- else
- fprintf(FGeom, "object %s", Name);
-
- for (i = 0; i < PObject -> Attrs.NumStrAttribs; i++) {
- if ((p = IritPrsrGetStrAttrib(PObject, "texture")) != NULL) {
- if (FRay != NULL)
- fprintf(FRay, "#define %sTEXTURE %s\n", Name, p);
- fprintf(FGeom, " texture %sTEXTURE", Name);
- break;
- }
- }
- fprintf(FGeom, "\n\n");
- if (FRay != NULL)
- fprintf(FRay, "\n\n");
-
- ObjectSeqNum++;
-
- return PolyCount;
- }
-
- /*****************************************************************************
- * Routine to dump one polygon, using global Matrix transform CrntViewMat. *
- *****************************************************************************/
- static int DumpOnePolygon(FILE *FGeom, IPPolygonStruct *PPolygon)
- {
- int i,
- TriCount = 0;
- RealType *MappedNormal[3], *MappedPoint[3], Normal[3], Vec1[3], Vec2[3];
- IPVertexStruct *VFirst, *V1, *V2,
- *VList = PPolygon -> PVertex;
-
- if (VList == NULL) return 0;
-
- if (!IsConvexPolygon(PPolygon)) {
- static int Printed = FALSE;
-
- if (!Printed) {
- fprintf(stderr,
- "Non convex polygon(s) may be in data (see CONVEX in IRIT).\n");
- Printed = TRUE;
- }
- }
-
- switch (PPolygon -> Type) {
- case IP_POLYGON:
- VFirst = VList;
- V1 = VFirst -> Pnext;
- V2 = V1 -> Pnext;
-
- while (V2 != NULL) {
- MappedPoint[0] = MapPoint(VFirst -> Coord);
- MappedPoint[1] = MapPoint(V1 -> Coord);
- MappedPoint[2] = MapPoint(V2 -> Coord);
-
- /* Test for two type of degeneracies. Make sure that no two */
- /* points in the triangle are the same and that they are */
- /* not colinear. */
- if (!PT_EQ(MappedPoint[0], MappedPoint[1]) &&
- !PT_EQ(MappedPoint[0], MappedPoint[2]) &&
- !PT_EQ(MappedPoint[1], MappedPoint[2])) {
-
- PT_SUB(Vec1, MappedPoint[0], MappedPoint[1]);
- PT_SUB(Vec2, MappedPoint[1], MappedPoint[2]);
- PT_NORMALIZE(Vec1);
- PT_NORMALIZE(Vec2);
- CROSS_PROD(Normal, Vec1, Vec2);
-
- if (PT_LENGTH(Normal) > SIZE_EPSILON) {
- PT_NORMALIZE(Normal);
-
- MappedNormal[0] =
- MapVector(VFirst -> Coord, VFirst -> Normal);
- MappedNormal[1] =
- MapVector(V1 -> Coord, V1 -> Normal);
- MappedNormal[2] =
- MapVector(V2 -> Coord, V2 -> Normal);
-
- if (DOT_PROD(Normal, MappedNormal[0]) < -SIZE_EPSILON ||
- DOT_PROD(Normal, MappedNormal[1]) < -SIZE_EPSILON ||
- DOT_PROD(Normal, MappedNormal[2]) < -SIZE_EPSILON) {
- SWAP(RealType *, MappedPoint[1], MappedPoint[2]);
- SWAP(RealType *, MappedNormal[1], MappedNormal[2]);
- PT_SCALE(Normal, -1.0);
- }
-
- /* Make sure all normals are set properly: */
- if (DOT_PROD(MappedNormal[0], MappedNormal[0]) < SIZE_EPSILON)
- PT_COPY(MappedNormal[0], Normal);
- if (DOT_PROD(MappedNormal[1], MappedNormal[1]) < SIZE_EPSILON)
- PT_COPY(MappedNormal[1], Normal);
- if (DOT_PROD(MappedNormal[2], MappedNormal[2]) < SIZE_EPSILON)
- PT_COPY(MappedNormal[2], Normal);
-
- TriCount++;
-
- for (i = 0; i < 3; i++)
- fprintf(FGeom,
- "%s %10.7lf %10.7lf %10.7lf %9.6lf %9.6lf %9.6lf\n",
- i == 0 ? " triangle" : "\t ",
- MappedPoint[i][0],
- MappedPoint[i][1],
- MappedPoint[i][2],
- MappedNormal[i][0],
- MappedNormal[i][1],
- MappedNormal[i][2]);
- }
- }
-
- V1 = V2;
- V2 = V2 -> Pnext;
- }
- break;
- }
-
- return TriCount;
- }
-
- /*****************************************************************************
- * Routine to test if the given polygon is convex or not. *
- * Algorithm: The polygon is convex iff the normals generated from cross *
- * products of two consecutive edges points to the same direction. The same *
- * direction is tested by a positive dot product. *
- *****************************************************************************/
- static int IsConvexPolygon(IPPolygonStruct *Pl)
- {
- RealType Size, V1[3], V2[3], LastNormal[3], Normal[3];
- IPVertexStruct *VNext, *VNextNext,
- *V = Pl -> PVertex;
-
- LastNormal[0] = LastNormal[1] = LastNormal[2] = 0.0;
-
- do {
- if ((VNext = V -> Pnext) == NULL)
- VNext = Pl -> PVertex;
- if ((VNextNext = VNext -> Pnext) == NULL)
- VNextNext = Pl -> PVertex;
-
- PT_SUB(V1, VNext -> Coord, V -> Coord);
- if ((Size = PT_LENGTH(V1)) > EPSILON) {
- Size = 1.0 / Size;
- PT_SCALE(V1, Size);
- }
- PT_SUB(V2, VNextNext -> Coord, VNext -> Coord);
- if ((Size = PT_LENGTH(V2)) > EPSILON) {
- Size = 1.0 / Size;
- PT_SCALE(V2, Size);
- }
- CROSS_PROD(Normal, V1, V2);
-
- if (V != Pl -> PVertex) {
- if (PT_LENGTH(Normal) > CONVEX_EPSILON &&
- DOT_PROD(Normal, LastNormal) < -CONVEX_EPSILON)
- return FALSE;
- }
-
- PT_COPY(LastNormal, Normal);
-
- V = VNext;
- }
- while (V != Pl -> PVertex && V != NULL);
-
- return TRUE;
- }
-
- /*****************************************************************************
- * Maps the given E3 point using the CrntViewMat. *
- *****************************************************************************/
- static RealType *MapPoint(RealType *Pt)
- {
- static int Count = 0;
- static RealType MappedPts[3][3];
- RealType *MappedPt = MappedPts[Count++];
-
- if (Count >= 3) Count = 0;
-
- MultVecby4by4(MappedPt, Pt, CrntViewMat);
-
- return MappedPt;
- }
-
- /*****************************************************************************
- * Maps the given E3 vector using the CrntViewMat. *
- * This routine will return a zero vector if normal is not computable. *
- *****************************************************************************/
- static RealType *MapVector(RealType *Pt, RealType *Vec)
- {
- static int
- Count = 0,
- WasWarning = 0;
- static RealType MappedVecs[3][3];
- RealType MappedPt[3], Pt2[3], MappedPt2[3],
- *MappedVec = MappedVecs[Count++];
-
- if (Count >= 3) Count = 0;
-
- if (DOT_PROD(Vec, Vec) < SIZE_EPSILON) {
- MappedVec[0] = MappedVec[1] = MappedVec[2] = 0.0;
- if (!WasWarning) {
- WasWarning = 1;
- fprintf(stderr, "Non computable normals detected. Approximated from geometry.\n");
- }
- }
- else {
- MultVecby4by4(MappedPt, Pt, CrntViewMat);
-
- PT_ADD(Pt2, Pt, Vec);
- MultVecby4by4(MappedPt2, Pt2, CrntViewMat);
-
- PT_SUB(MappedVec, MappedPt2, MappedPt);
- PT_NORMALIZE(MappedVec);
- }
-
- return MappedVec;
- }
-
- /*****************************************************************************
- * 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. *
- *****************************************************************************/
- static void MyExit(int ExitCode)
- {
- #ifdef __MSDOS__
- fprintf(stderr,
- "\nIrit2Ray: Core left %ldk.\n", coreleft() / 1024);
- #endif /* __MSDOS__ */
-
- exit(ExitCode);
- }
-