home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / IRIT / IRITS.ZIP / OBJECTS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-05  |  16.3 KB  |  476 lines

  1. /*****************************************************************************
  2. *   "Irit" - the 3d polygonal solid modeller.                     *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.2, Mar. 1990   *
  5. ******************************************************************************
  6. *   Module to handle the objects list - fetch, insert, delete etc...         *
  7. *****************************************************************************/
  8.  
  9. /* #define DEBUG               Output goes to stdout if defined. */
  10.  
  11. #ifdef __MSDOS__
  12. #include <graphics.h>
  13. #endif /* __MSDOS__ */
  14.  
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <math.h>
  18. #include "program.h"
  19. #include "objects.h"
  20. #include "allocatg.h"
  21. #include "geomat3d.h"
  22. #include "windowsg.h"
  23.  
  24. #ifndef __MSDOS__
  25. #include "xgraphic.h"
  26. #endif /* __MSDOS__ */
  27.  
  28. static struct PolygonStruct *GenAxesObjectPolylines(void);
  29.  
  30. /*****************************************************************************
  31. *   Routine to set up all the predefined objects - objects that the system   *
  32. * must have all the time, like global transformation matrix.             *
  33. *****************************************************************************/
  34. void SetUpPredefObjects(void)
  35. {
  36.     RealType R;
  37.     MatrixType Mat1, Mat2;
  38.     struct ObjectStruct *PObj;
  39.  
  40.     /* 90 - 35.2644 = 54.7356 */
  41.     MatGenMatRotX1(DEG2RAD(-54.7356), Mat1); /* Generate default view trans. */
  42.     MatGenMatRotZ1(M_PI+M_PI/4, Mat2);         /* which is isometric view. */
  43.     MatMultTwo4by4(Mat2, Mat2, Mat1);
  44.     PObj = GenMatObject("VIEW_MAT", Mat2, NULL);
  45.     InsertObject(PObj);
  46.  
  47.     R = DEFAULT_RESOLUTION;
  48.     PObj = GenNumObject("RESOLUTION", &R, NULL);
  49.     InsertObject(PObj);
  50.  
  51.     R = DEFAULT_INTERNAL;
  52.     PObj = GenNumObject("INTERNAL", &R, NULL);
  53.     InsertObject(PObj);
  54.  
  55.     R = DEFAULT_INTERCRV;
  56.     PObj = GenNumObject("INTERCRV", &R, NULL);
  57.     InsertObject(PObj);
  58.  
  59.     PObj = GenGeomObject("AXES", GenAxesObjectPolylines(), NULL);
  60.     SET_POLYLINE_GEOM_OBJ(PObj);          /* Mark it as polyline object. */
  61.     InsertObject(PObj);
  62. }
  63.  
  64. /*****************************************************************************
  65. *   Generate an axes system with length of 1 on each axis.             *
  66. *****************************************************************************/
  67. static struct PolygonStruct *GenAxesObjectPolylines(void)
  68. {
  69.     struct PolygonStruct *Pl, *PlHead;
  70.     struct VertexStruct *V;
  71.  
  72.     Pl = PlHead = AllocPolygon(0, 0, NULL, NULL);          /* X axis. */
  73.     Pl -> V = V = AllocVertex(0, 0, NULL, NULL);
  74.     V -> Pt[0] = 0.0;    V -> Pt[1] = 0.0;   V -> Pt[2] = 0.0;
  75.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  76.     V -> Pt[0] = 1.0;    V -> Pt[1] = 0.0;   V -> Pt[2] = 0.0;
  77.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  78.     V -> Pt[0] = 1.0;    V -> Pt[1] = 0.1;   V -> Pt[2] = 0.1;
  79.  
  80.     Pl -> Pnext = AllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;
  81.     Pl -> V = V = AllocVertex(0, 0, NULL, NULL);
  82.     V -> Pt[0] = 1.0;    V -> Pt[1] = 0.1;   V -> Pt[2] = 0.0;
  83.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  84.     V -> Pt[0] = 1.0;    V -> Pt[1] = 0.0;   V -> Pt[2] = 0.1;
  85.  
  86.     Pl -> Pnext = AllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;/* Y axis.*/
  87.     Pl -> V = V = AllocVertex(0, 0, NULL, NULL);
  88.     V -> Pt[0] = 0.0;    V -> Pt[1] = 0.0;   V -> Pt[2] = 0.0;
  89.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  90.     V -> Pt[0] = 0.0;    V -> Pt[1] = 1.0;   V -> Pt[2] = 0.0;
  91.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  92.     V -> Pt[0] = 0.0;    V -> Pt[1] = 1.0;   V -> Pt[2] = 0.06;
  93.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  94.     V -> Pt[0] = 0.04;    V -> Pt[1] = 1.0;   V -> Pt[2] = 0.1;
  95.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  96.     V -> Pt[0] = 0.0;    V -> Pt[1] = 1.0;   V -> Pt[2] = 0.06;
  97.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  98.     V -> Pt[0] =(-0.04);V -> Pt[1] = 1.0;   V -> Pt[2] = 0.1;
  99.  
  100.     Pl -> Pnext = AllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;/* Z axis.*/
  101.     Pl -> V = V = AllocVertex(0, 0, NULL, NULL);
  102.     V -> Pt[0] = 0.0;    V -> Pt[1] = 0.0;   V -> Pt[2] = 0.0;
  103.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  104.     V -> Pt[0] = 0.0;    V -> Pt[1] = 0.0;   V -> Pt[2] = 1.0;
  105.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  106.     V -> Pt[0] = 0.1;    V -> Pt[1] = 0.0;   V -> Pt[2] = 1.0;
  107.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  108.     V -> Pt[0] = 0.0;    V -> Pt[1] = 0.1;   V -> Pt[2] = 1.0;
  109.     V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
  110.     V -> Pt[0] = 0.1;    V -> Pt[1] = 0.1;   V -> Pt[2] = 1.0;
  111.  
  112.     return PlHead;
  113. }
  114.  
  115. /*****************************************************************************
  116. *   Get object by its name - scans the object linear list.             *
  117. * Note the termination is also on 1000 objects (simple debugging aid in case *
  118. * the Object list became circular), and a fatal error is produced.         *
  119. *****************************************************************************/
  120. struct ObjectStruct *GetObject(char *ObjName)
  121. {
  122.     int i = 0;
  123.     struct ObjectStruct *PObj = GlblObjList;
  124.  
  125.     while (PObj) {
  126.     if (strcmp(PObj->Name, ObjName) == 0) return PObj;
  127.     PObj = PObj -> Pnext;
  128.     if (i++ >= 1000)
  129.         FatalError("GetObject: Global Object list too big (>1000)\n");
  130.     }
  131.     return NULL;
  132. }
  133.  
  134. /*****************************************************************************
  135. *   Free Object - delete it from global active list and free all it memory   *
  136. *****************************************************************************/
  137. void FreeObject(ObjectStruct *PObj)
  138. {
  139.     DeleteObject(PObj, TRUE);
  140. }
  141.  
  142. /*****************************************************************************
  143. *   Delete object by its pointer - scans the object linear list.         *
  144. * Note the deleted record is free only if Free = TRUE.                 *
  145. *****************************************************************************/
  146. void DeleteObject(ObjectStruct *PObj, int Free)
  147. {
  148.     struct ObjectStruct *PObjScan = GlblObjList;
  149.  
  150.     if (GlblObjList == NULL) return;
  151.  
  152.     if (PObj == GlblObjList) {       /* If it is the first one - special case. */
  153.     GlblObjList = GlblObjList->Pnext;
  154.     if (Free) MyFree((char *) PObj, OBJECT_TYPE);
  155.     return;
  156.     }
  157.  
  158.     while (PObjScan->Pnext) {
  159.     if (PObj == PObjScan->Pnext) {
  160.         PObjScan->Pnext = PObjScan->Pnext->Pnext;/* Delete it from list. */
  161.         if (Free) MyFree((char *) PObj, OBJECT_TYPE);    /* And free it. */
  162.         return;
  163.     }
  164.     PObjScan = PObjScan->Pnext;
  165.     }
  166. }
  167.  
  168. /*****************************************************************************
  169. *   Insert object by its pointer - as first in object linear list.         *
  170. * Note it is assumed the object is not in the object list allready.         *
  171. *****************************************************************************/
  172. void InsertObject(ObjectStruct *PObj)
  173. {
  174.     PObj -> Pnext = GlblObjList;
  175.     GlblObjList = PObj;
  176. }
  177.  
  178. /*****************************************************************************
  179. *   Print some usefull info on the given object.                 *
  180. *****************************************************************************/
  181. void PrintObject(ObjectStruct *PObj)
  182. {
  183.     int i;
  184.     char Line[LINE_LEN_LONG];
  185.  
  186.     switch(PObj->ObjType) {
  187.     case UNDEF_OBJ:
  188.         sprintf(Line, "%-10s - Undefined type", PObj -> Name);
  189.         WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
  190.         break;
  191.     case GEOMETRIC_OBJ:
  192.         sprintf(Line, "%-10s - Geometric type", PObj -> Name);
  193.         WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
  194. #        ifdef DEBUG
  195.         {
  196.             PolygonStruct *Pl = PObj -> U.Pl;
  197.             VertexStruct *V, *VStart;
  198.  
  199.             while (Pl != NULL) {
  200.             printf("Polygon =\n");
  201.             V = VStart = Pl -> V;
  202.             do {
  203.                 printf("        %-12.9lf %-12.9lf %-12.9lf\n",
  204.                 V -> Pt[0], V -> Pt[1], V -> Pt[2]);
  205.                 V = V -> Pnext;
  206.             } while (V != VStart && V != NULL);
  207.  
  208.             Pl = Pl -> Pnext;
  209.             }
  210.         }
  211. #        endif /* DEBUG */
  212.         break;
  213.     case NUMERIC_OBJ:
  214. #        ifdef DOUBLE
  215.         sprintf(Line, "%-10s - Numeric   type = %-13lg",
  216. #        else
  217.         sprintf(Line, "%-10s - Numeric   type = %-13g",
  218. #        endif /* DOUBLE */
  219.                         PObj -> Name, PObj -> U.R);
  220.         WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
  221.         break;
  222.     case VECTOR_OBJ:
  223. #        ifdef DOUBLE
  224.         sprintf(Line, "%-10s - Vector    type = %-13g %-13g %-13g",
  225. #        else
  226.         sprintf(Line, "%-10s - Vector    type = %-13lg %-13lg %-13lg",
  227. #        endif /* DOUBLE */
  228.             PObj -> Name,
  229.             PObj -> U.Vec[0], PObj -> U.Vec[1], PObj -> U.Vec[2]);
  230.         WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
  231.         break;
  232.     case MATRIX_OBJ:
  233.         sprintf(Line, "%-10s - Matrix    type", PObj -> Name);
  234.         WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
  235.  
  236.         for (i=0; i<4; i++) {
  237. #        ifdef DOUBLE
  238.             sprintf(Line, "                %-13lg %-13lg %-13lg %-13lg",
  239. #        else
  240.             sprintf(Line, "                %-13g %-13g %-13g %-13g",
  241. #        endif /* DOUBLE */
  242.             PObj -> U.Mat[i][0], PObj -> U.Mat[i][1],
  243.             PObj -> U.Mat[i][2], PObj -> U.Mat[i][3]);
  244.  
  245.         WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
  246.         }
  247.         break;
  248.     case STRING_OBJ:
  249.         sprintf(Line, "%-10s - String    type = \"%s\"",
  250.             PObj -> Name, PObj -> U.Str);
  251.         WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
  252.         break;
  253.     case OBJ_LIST_OBJ:
  254.         sprintf(Line, "%-10s - Object List type",
  255.             PObj -> Name);
  256.         WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
  257.         i = 0;
  258.         sprintf(Line, "       ");
  259.         while (PObj -> U.PObjList[i] != NULL && i < MAX_OBJ_LIST) {
  260.         sprintf(&Line[strlen(Line)], "%12s",
  261.                     PObj -> U.PObjList[i++] -> Name);
  262.         if (i % 5 == 0) {
  263.             WndwInputWindowPutStrFS(Line, NO_COLOR, FALSE);
  264.             sprintf(Line, "       ");
  265.         }
  266.         }
  267.         if (i % 5 != 0) WndwInputWindowPutStrFS(Line, NO_COLOR, FALSE);
  268.         break;
  269.     default:
  270.         sprintf(Line, "%-10s - Obj type error, type = %d",
  271.                         PObj -> Name, PObj->ObjType);
  272.         WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
  273.         break;
  274.     }
  275. }
  276.  
  277. /*****************************************************************************
  278. *   Print some usefull info on all the given objects.                 *
  279. *****************************************************************************/
  280. void PrintObjectList(ObjectStruct *PObj)
  281. {
  282.     WndwInputWindowPutStrFS("", NO_COLOR, TRUE);
  283.  
  284.     while (PObj != NULL) {
  285.     PrintObject(PObj);
  286.     PObj = PObj -> Pnext;
  287.     }
  288. }
  289.  
  290. /*****************************************************************************
  291. *   Generate one geometric object:                         *
  292. *****************************************************************************/
  293. void SetGeomObjectColor(ObjectStruct *PObj, RealType *Color)
  294. {
  295.     if (!IS_GEOM_OBJ(PObj))
  296.     FatalError("Attempt to set color to a non geometric object");
  297.  
  298.     SET_OBJECT_COLOR(PObj, ((int) (*Color)));
  299. }
  300.  
  301. /*****************************************************************************
  302. *   Generate one geometric object:                         *
  303. *****************************************************************************/
  304. struct ObjectStruct *GenGeomObject(char *Name, PolygonStruct *Pl,
  305.                             ObjectStruct *Pnext)
  306. {
  307.     ObjectStruct *PObj;
  308.  
  309.     PObj = AllocObject(Name, GEOMETRIC_OBJ, Pnext);
  310.     SET_OBJECT_COLOR(PObj, WHITE);         /* Default color attribute. */
  311.     RST_POLYLINE_GEOM_OBJ(PObj);       /* Default - not polyline object. */
  312.  
  313.     PObj -> U.Pl = Pl;                 /* Link the union part of it... */
  314.  
  315.     return PObj;
  316. }
  317.  
  318. /*****************************************************************************
  319. *   Generate one numeric object:                         *
  320. *****************************************************************************/
  321. struct ObjectStruct *GenNumObject(char *Name, RealType *R, ObjectStruct *Pnext)
  322. {
  323.     ObjectStruct *PObj;
  324.  
  325.     PObj = AllocObject(Name, NUMERIC_OBJ, Pnext);
  326.  
  327.     PObj -> U.R = *R;                 /* Link the union part of it... */
  328.  
  329.     return PObj;
  330. }
  331.  
  332. /*****************************************************************************
  333. *   Generate one vector object:                             *
  334. *****************************************************************************/
  335. struct ObjectStruct *GenVecObject(char *Name, RealType *Vec0, RealType *Vec1,
  336.                     RealType *Vec2, ObjectStruct * Pnext)
  337. {
  338.     ObjectStruct *PObj;
  339.  
  340.     PObj = AllocObject(Name, VECTOR_OBJ, Pnext);
  341.  
  342.     PObj -> U.Vec[0] = *Vec0;             /* Link the union part of it... */
  343.     PObj -> U.Vec[1] = *Vec1;
  344.     PObj -> U.Vec[2] = *Vec2;
  345.  
  346.     return PObj;
  347. }
  348.  
  349. /*****************************************************************************
  350. *   Generate one matrix object:                             *
  351. *****************************************************************************/
  352. struct ObjectStruct *GenMatObject(char *Name, MatrixType Mat,
  353.                             ObjectStruct *Pnext)
  354. {
  355.     int i, j;
  356.     ObjectStruct *PObj;
  357.  
  358.     PObj = AllocObject(Name, MATRIX_OBJ, Pnext);
  359.  
  360.     for (i=0; i<4; i++)                 /* Link the union part of it... */
  361.     for (j=0; j<4; j++) PObj -> U.Mat[i][j] = Mat[i][j];
  362.  
  363.     return PObj;
  364. }
  365.  
  366. /*****************************************************************************
  367. *   Routine to create a whole new copy of an object Src into Dest.         *
  368. * if Dest is NULL, new object is allocated, otherwise Dest itself is updated *
  369. * If CopyAll then all the record is copied, otherwise, only its variant      *
  370. * element (i.e. no Name/Pnext coping) is been copied.                 *
  371. *****************************************************************************/
  372. struct ObjectStruct *CopyObject(ObjectStruct *Dest, ObjectStruct *Src,
  373.                                 int CopyAll)
  374. {
  375.     int index;
  376.     char Line[LINE_LEN];
  377.  
  378.     if (Dest == NULL)
  379.     Dest = AllocObject("", Src->ObjType, NULL);
  380.     else {
  381.     Dest->ObjType = Src->ObjType;
  382.     }
  383.  
  384.     if (Dest == Src) return Dest;    /* Called with same object - ignore. */
  385.  
  386.     if (CopyAll) {
  387.     strcpy(Dest->Name, Src->Name);
  388.     Dest->Pnext = Src->Pnext;     /* Maybe assigning NULL is better!? */
  389.     }
  390.  
  391.     switch (Src->ObjType) {
  392.     case GEOMETRIC_OBJ:
  393.         Dest->U.Pl = CopyPolygonList(Src->U.Pl);
  394.         COPY_GEOM_ATTRIB(Dest, Src);
  395.         break;
  396.     case NUMERIC_OBJ:
  397.         Dest->U.R = Src->U.R;
  398.         break;
  399.     case VECTOR_OBJ:
  400.         PT_COPY(Dest->U.Vec, Src->U.Vec);
  401.         break;
  402.     case MATRIX_OBJ:
  403.         MAT_COPY(Dest->U.Mat, Src->U.Mat);
  404.         break;
  405.     case STRING_OBJ:
  406.         strcpy(Dest->U.Str, Src->U.Str);
  407.         break;
  408.     case OBJ_LIST_OBJ:
  409.         GEN_COPY(Dest->U.PObjList, Src->U.PObjList,
  410.             MAX_OBJ_LIST * sizeof(ObjectStruct *));
  411.         index = 0;
  412.         while (index < MAX_OBJ_LIST &&
  413.            Dest -> U.PObjList[index] != NULL)
  414.         Dest -> U.PObjList[index++] -> Count++;    /* Inc. # of ref. */
  415.         break;
  416.     default:
  417.         sprintf(Line,
  418.         "CopyObject Attemp to copy undefined object %s type %d\n",
  419.         Src->Name, Src->ObjType);
  420.         FatalError(Line);
  421.     }
  422.     return Dest;
  423. }
  424.  
  425. /*****************************************************************************
  426. *   Routine to generate a new copy of an object polygon list.             *
  427. *****************************************************************************/
  428. struct PolygonStruct *CopyPolygonList(PolygonStruct *Src)
  429. {
  430.     struct PolygonStruct *Phead, *Ptail;
  431.  
  432.     if (Src == NULL) return NULL;
  433.  
  434.     /* Prepare the header of the new polygon list: */
  435.     Phead = Ptail = AllocPolygon(1, Src->Tags, CopyVList(Src->V), NULL);
  436.     PLANE_COPY(Ptail -> Plane, Src -> Plane);
  437.     Src = Src -> Pnext;
  438.  
  439.     while (Src != NULL) {
  440.     Ptail -> Pnext = AllocPolygon(Src->Count, Src->Tags,
  441.                         CopyVList(Src->V), NULL);
  442.     Ptail = Ptail -> Pnext;
  443.     PLANE_COPY(Ptail -> Plane, Src -> Plane);
  444.     Src = Src -> Pnext;
  445.     }
  446.  
  447.     return Phead;
  448. }
  449.  
  450. /*****************************************************************************
  451. *   Routine to generate a new copy of a polygon vertices list.             *
  452. *****************************************************************************/
  453. struct VertexStruct *CopyVList(VertexStruct *Src)
  454. {
  455.     struct VertexStruct *Phead, *Ptail, *SrcFirst = Src;
  456.  
  457.     if (Src == NULL) return NULL;
  458.  
  459.     /* Prepare the header of the new vertex list: */
  460.     Phead = Ptail = AllocVertex(Src -> Count, Src -> Tags, NULL, NULL);
  461.     PT_COPY(Phead -> Pt, Src -> Pt);
  462.     Src = Src -> Pnext;
  463.  
  464.     while (Src != SrcFirst && Src != NULL) {
  465.     Ptail -> Pnext = AllocVertex(Src -> Count, Src -> Tags, NULL, NULL);
  466.     Ptail = Ptail -> Pnext;
  467.     PT_COPY(Ptail -> Pt, Src -> Pt);
  468.  
  469.     Src = Src -> Pnext;
  470.     }
  471.  
  472.     if (Src == SrcFirst) Ptail -> Pnext = Phead;/* Make vertex list circular.*/
  473.  
  474.     return Phead;
  475. }
  476.