home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * "Irit" - the 3d polygonal solid modeller. *
- * *
- * Written by: Gershon Elber Ver 0.2, Mar. 1990 *
- ******************************************************************************
- * Module to handle the objects list - fetch, insert, delete etc... *
- *****************************************************************************/
-
- /* #define DEBUG Output goes to stdout if defined. */
-
- #ifdef __MSDOS__
- #include <graphics.h>
- #endif /* __MSDOS__ */
-
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #include "program.h"
- #include "objects.h"
- #include "allocatg.h"
- #include "geomat3d.h"
- #include "windowsg.h"
-
- #ifndef __MSDOS__
- #include "xgraphic.h"
- #endif /* __MSDOS__ */
-
- static struct PolygonStruct *GenAxesObjectPolylines(void);
-
- /*****************************************************************************
- * Routine to set up all the predefined objects - objects that the system *
- * must have all the time, like global transformation matrix. *
- *****************************************************************************/
- void SetUpPredefObjects(void)
- {
- RealType R;
- MatrixType Mat1, Mat2;
- struct ObjectStruct *PObj;
-
- /* 90 - 35.2644 = 54.7356 */
- MatGenMatRotX1(DEG2RAD(-54.7356), Mat1); /* Generate default view trans. */
- MatGenMatRotZ1(M_PI+M_PI/4, Mat2); /* which is isometric view. */
- MatMultTwo4by4(Mat2, Mat2, Mat1);
- PObj = GenMatObject("VIEW_MAT", Mat2, NULL);
- InsertObject(PObj);
-
- R = DEFAULT_RESOLUTION;
- PObj = GenNumObject("RESOLUTION", &R, NULL);
- InsertObject(PObj);
-
- R = DEFAULT_INTERNAL;
- PObj = GenNumObject("INTERNAL", &R, NULL);
- InsertObject(PObj);
-
- R = DEFAULT_INTERCRV;
- PObj = GenNumObject("INTERCRV", &R, NULL);
- InsertObject(PObj);
-
- PObj = GenGeomObject("AXES", GenAxesObjectPolylines(), NULL);
- SET_POLYLINE_GEOM_OBJ(PObj); /* Mark it as polyline object. */
- InsertObject(PObj);
- }
-
- /*****************************************************************************
- * Generate an axes system with length of 1 on each axis. *
- *****************************************************************************/
- static struct PolygonStruct *GenAxesObjectPolylines(void)
- {
- struct PolygonStruct *Pl, *PlHead;
- struct VertexStruct *V;
-
- Pl = PlHead = AllocPolygon(0, 0, NULL, NULL); /* X axis. */
- Pl -> V = V = AllocVertex(0, 0, NULL, NULL);
- V -> Pt[0] = 0.0; V -> Pt[1] = 0.0; V -> Pt[2] = 0.0;
- V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
- V -> Pt[0] = 1.0; V -> Pt[1] = 0.0; V -> Pt[2] = 0.0;
- V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
- V -> Pt[0] = 1.0; V -> Pt[1] = 0.1; V -> Pt[2] = 0.1;
-
- Pl -> Pnext = AllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;
- Pl -> V = V = AllocVertex(0, 0, NULL, NULL);
- V -> Pt[0] = 1.0; V -> Pt[1] = 0.1; V -> Pt[2] = 0.0;
- V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
- V -> Pt[0] = 1.0; V -> Pt[1] = 0.0; V -> Pt[2] = 0.1;
-
- Pl -> Pnext = AllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;/* Y axis.*/
- Pl -> V = V = AllocVertex(0, 0, NULL, NULL);
- V -> Pt[0] = 0.0; V -> Pt[1] = 0.0; V -> Pt[2] = 0.0;
- V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
- V -> Pt[0] = 0.0; V -> Pt[1] = 1.0; V -> Pt[2] = 0.0;
- V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
- V -> Pt[0] = 0.0; V -> Pt[1] = 1.0; V -> Pt[2] = 0.06;
- V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
- V -> Pt[0] = 0.04; V -> Pt[1] = 1.0; V -> Pt[2] = 0.1;
- V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
- V -> Pt[0] = 0.0; V -> Pt[1] = 1.0; V -> Pt[2] = 0.06;
- V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
- V -> Pt[0] =(-0.04);V -> Pt[1] = 1.0; V -> Pt[2] = 0.1;
-
- Pl -> Pnext = AllocPolygon(0, 0, NULL, NULL); Pl = Pl -> Pnext;/* Z axis.*/
- Pl -> V = V = AllocVertex(0, 0, NULL, NULL);
- V -> Pt[0] = 0.0; V -> Pt[1] = 0.0; V -> Pt[2] = 0.0;
- V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
- V -> Pt[0] = 0.0; V -> Pt[1] = 0.0; V -> Pt[2] = 1.0;
- V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
- V -> Pt[0] = 0.1; V -> Pt[1] = 0.0; V -> Pt[2] = 1.0;
- V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
- V -> Pt[0] = 0.0; V -> Pt[1] = 0.1; V -> Pt[2] = 1.0;
- V -> Pnext = AllocVertex(0, 0, NULL, NULL); V = V -> Pnext;
- V -> Pt[0] = 0.1; V -> Pt[1] = 0.1; V -> Pt[2] = 1.0;
-
- return PlHead;
- }
-
- /*****************************************************************************
- * Get object by its name - scans the object linear list. *
- * Note the termination is also on 1000 objects (simple debugging aid in case *
- * the Object list became circular), and a fatal error is produced. *
- *****************************************************************************/
- struct ObjectStruct *GetObject(char *ObjName)
- {
- int i = 0;
- struct ObjectStruct *PObj = GlblObjList;
-
- while (PObj) {
- if (strcmp(PObj->Name, ObjName) == 0) return PObj;
- PObj = PObj -> Pnext;
- if (i++ >= 1000)
- FatalError("GetObject: Global Object list too big (>1000)\n");
- }
- return NULL;
- }
-
- /*****************************************************************************
- * Free Object - delete it from global active list and free all it memory *
- *****************************************************************************/
- void FreeObject(ObjectStruct *PObj)
- {
- DeleteObject(PObj, TRUE);
- }
-
- /*****************************************************************************
- * Delete object by its pointer - scans the object linear list. *
- * Note the deleted record is free only if Free = TRUE. *
- *****************************************************************************/
- void DeleteObject(ObjectStruct *PObj, int Free)
- {
- struct ObjectStruct *PObjScan = GlblObjList;
-
- if (GlblObjList == NULL) return;
-
- if (PObj == GlblObjList) { /* If it is the first one - special case. */
- GlblObjList = GlblObjList->Pnext;
- if (Free) MyFree((char *) PObj, OBJECT_TYPE);
- return;
- }
-
- while (PObjScan->Pnext) {
- if (PObj == PObjScan->Pnext) {
- PObjScan->Pnext = PObjScan->Pnext->Pnext;/* Delete it from list. */
- if (Free) MyFree((char *) PObj, OBJECT_TYPE); /* And free it. */
- return;
- }
- PObjScan = PObjScan->Pnext;
- }
- }
-
- /*****************************************************************************
- * Insert object by its pointer - as first in object linear list. *
- * Note it is assumed the object is not in the object list allready. *
- *****************************************************************************/
- void InsertObject(ObjectStruct *PObj)
- {
- PObj -> Pnext = GlblObjList;
- GlblObjList = PObj;
- }
-
- /*****************************************************************************
- * Print some usefull info on the given object. *
- *****************************************************************************/
- void PrintObject(ObjectStruct *PObj)
- {
- int i;
- char Line[LINE_LEN_LONG];
-
- switch(PObj->ObjType) {
- case UNDEF_OBJ:
- sprintf(Line, "%-10s - Undefined type", PObj -> Name);
- WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
- break;
- case GEOMETRIC_OBJ:
- sprintf(Line, "%-10s - Geometric type", PObj -> Name);
- WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
- # ifdef DEBUG
- {
- PolygonStruct *Pl = PObj -> U.Pl;
- VertexStruct *V, *VStart;
-
- while (Pl != NULL) {
- printf("Polygon =\n");
- V = VStart = Pl -> V;
- do {
- printf(" %-12.9lf %-12.9lf %-12.9lf\n",
- V -> Pt[0], V -> Pt[1], V -> Pt[2]);
- V = V -> Pnext;
- } while (V != VStart && V != NULL);
-
- Pl = Pl -> Pnext;
- }
- }
- # endif /* DEBUG */
- break;
- case NUMERIC_OBJ:
- # ifdef DOUBLE
- sprintf(Line, "%-10s - Numeric type = %-13lg",
- # else
- sprintf(Line, "%-10s - Numeric type = %-13g",
- # endif /* DOUBLE */
- PObj -> Name, PObj -> U.R);
- WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
- break;
- case VECTOR_OBJ:
- # ifdef DOUBLE
- sprintf(Line, "%-10s - Vector type = %-13g %-13g %-13g",
- # else
- sprintf(Line, "%-10s - Vector type = %-13lg %-13lg %-13lg",
- # endif /* DOUBLE */
- PObj -> Name,
- PObj -> U.Vec[0], PObj -> U.Vec[1], PObj -> U.Vec[2]);
- WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
- break;
- case MATRIX_OBJ:
- sprintf(Line, "%-10s - Matrix type", PObj -> Name);
- WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
-
- for (i=0; i<4; i++) {
- # ifdef DOUBLE
- sprintf(Line, " %-13lg %-13lg %-13lg %-13lg",
- # else
- sprintf(Line, " %-13g %-13g %-13g %-13g",
- # endif /* DOUBLE */
- PObj -> U.Mat[i][0], PObj -> U.Mat[i][1],
- PObj -> U.Mat[i][2], PObj -> U.Mat[i][3]);
-
- WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
- }
- break;
- case STRING_OBJ:
- sprintf(Line, "%-10s - String type = \"%s\"",
- PObj -> Name, PObj -> U.Str);
- WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
- break;
- case OBJ_LIST_OBJ:
- sprintf(Line, "%-10s - Object List type",
- PObj -> Name);
- WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
- i = 0;
- sprintf(Line, " ");
- while (PObj -> U.PObjList[i] != NULL && i < MAX_OBJ_LIST) {
- sprintf(&Line[strlen(Line)], "%12s",
- PObj -> U.PObjList[i++] -> Name);
- if (i % 5 == 0) {
- WndwInputWindowPutStrFS(Line, NO_COLOR, FALSE);
- sprintf(Line, " ");
- }
- }
- if (i % 5 != 0) WndwInputWindowPutStrFS(Line, NO_COLOR, FALSE);
- break;
- default:
- sprintf(Line, "%-10s - Obj type error, type = %d",
- PObj -> Name, PObj->ObjType);
- WndwInputWindowPutStrFS(Line, NO_COLOR, TRUE);
- break;
- }
- }
-
- /*****************************************************************************
- * Print some usefull info on all the given objects. *
- *****************************************************************************/
- void PrintObjectList(ObjectStruct *PObj)
- {
- WndwInputWindowPutStrFS("", NO_COLOR, TRUE);
-
- while (PObj != NULL) {
- PrintObject(PObj);
- PObj = PObj -> Pnext;
- }
- }
-
- /*****************************************************************************
- * Generate one geometric object: *
- *****************************************************************************/
- void SetGeomObjectColor(ObjectStruct *PObj, RealType *Color)
- {
- if (!IS_GEOM_OBJ(PObj))
- FatalError("Attempt to set color to a non geometric object");
-
- SET_OBJECT_COLOR(PObj, ((int) (*Color)));
- }
-
- /*****************************************************************************
- * Generate one geometric object: *
- *****************************************************************************/
- struct ObjectStruct *GenGeomObject(char *Name, PolygonStruct *Pl,
- ObjectStruct *Pnext)
- {
- ObjectStruct *PObj;
-
- PObj = AllocObject(Name, GEOMETRIC_OBJ, Pnext);
- SET_OBJECT_COLOR(PObj, WHITE); /* Default color attribute. */
- RST_POLYLINE_GEOM_OBJ(PObj); /* Default - not polyline object. */
-
- PObj -> U.Pl = Pl; /* Link the union part of it... */
-
- return PObj;
- }
-
- /*****************************************************************************
- * Generate one numeric object: *
- *****************************************************************************/
- struct ObjectStruct *GenNumObject(char *Name, RealType *R, ObjectStruct *Pnext)
- {
- ObjectStruct *PObj;
-
- PObj = AllocObject(Name, NUMERIC_OBJ, Pnext);
-
- PObj -> U.R = *R; /* Link the union part of it... */
-
- return PObj;
- }
-
- /*****************************************************************************
- * Generate one vector object: *
- *****************************************************************************/
- struct ObjectStruct *GenVecObject(char *Name, RealType *Vec0, RealType *Vec1,
- RealType *Vec2, ObjectStruct * Pnext)
- {
- ObjectStruct *PObj;
-
- PObj = AllocObject(Name, VECTOR_OBJ, Pnext);
-
- PObj -> U.Vec[0] = *Vec0; /* Link the union part of it... */
- PObj -> U.Vec[1] = *Vec1;
- PObj -> U.Vec[2] = *Vec2;
-
- return PObj;
- }
-
- /*****************************************************************************
- * Generate one matrix object: *
- *****************************************************************************/
- struct ObjectStruct *GenMatObject(char *Name, MatrixType Mat,
- ObjectStruct *Pnext)
- {
- int i, j;
- ObjectStruct *PObj;
-
- PObj = AllocObject(Name, MATRIX_OBJ, Pnext);
-
- for (i=0; i<4; i++) /* Link the union part of it... */
- for (j=0; j<4; j++) PObj -> U.Mat[i][j] = Mat[i][j];
-
- return PObj;
- }
-
- /*****************************************************************************
- * Routine to create a whole new copy of an object Src into Dest. *
- * if Dest is NULL, new object is allocated, otherwise Dest itself is updated *
- * If CopyAll then all the record is copied, otherwise, only its variant *
- * element (i.e. no Name/Pnext coping) is been copied. *
- *****************************************************************************/
- struct ObjectStruct *CopyObject(ObjectStruct *Dest, ObjectStruct *Src,
- int CopyAll)
- {
- int index;
- char Line[LINE_LEN];
-
- if (Dest == NULL)
- Dest = AllocObject("", Src->ObjType, NULL);
- else {
- Dest->ObjType = Src->ObjType;
- }
-
- if (Dest == Src) return Dest; /* Called with same object - ignore. */
-
- if (CopyAll) {
- strcpy(Dest->Name, Src->Name);
- Dest->Pnext = Src->Pnext; /* Maybe assigning NULL is better!? */
- }
-
- switch (Src->ObjType) {
- case GEOMETRIC_OBJ:
- Dest->U.Pl = CopyPolygonList(Src->U.Pl);
- COPY_GEOM_ATTRIB(Dest, Src);
- break;
- case NUMERIC_OBJ:
- Dest->U.R = Src->U.R;
- break;
- case VECTOR_OBJ:
- PT_COPY(Dest->U.Vec, Src->U.Vec);
- break;
- case MATRIX_OBJ:
- MAT_COPY(Dest->U.Mat, Src->U.Mat);
- break;
- case STRING_OBJ:
- strcpy(Dest->U.Str, Src->U.Str);
- break;
- case OBJ_LIST_OBJ:
- GEN_COPY(Dest->U.PObjList, Src->U.PObjList,
- MAX_OBJ_LIST * sizeof(ObjectStruct *));
- index = 0;
- while (index < MAX_OBJ_LIST &&
- Dest -> U.PObjList[index] != NULL)
- Dest -> U.PObjList[index++] -> Count++; /* Inc. # of ref. */
- break;
- default:
- sprintf(Line,
- "CopyObject Attemp to copy undefined object %s type %d\n",
- Src->Name, Src->ObjType);
- FatalError(Line);
- }
- return Dest;
- }
-
- /*****************************************************************************
- * Routine to generate a new copy of an object polygon list. *
- *****************************************************************************/
- struct PolygonStruct *CopyPolygonList(PolygonStruct *Src)
- {
- struct PolygonStruct *Phead, *Ptail;
-
- if (Src == NULL) return NULL;
-
- /* Prepare the header of the new polygon list: */
- Phead = Ptail = AllocPolygon(1, Src->Tags, CopyVList(Src->V), NULL);
- PLANE_COPY(Ptail -> Plane, Src -> Plane);
- Src = Src -> Pnext;
-
- while (Src != NULL) {
- Ptail -> Pnext = AllocPolygon(Src->Count, Src->Tags,
- CopyVList(Src->V), NULL);
- Ptail = Ptail -> Pnext;
- PLANE_COPY(Ptail -> Plane, Src -> Plane);
- Src = Src -> Pnext;
- }
-
- return Phead;
- }
-
- /*****************************************************************************
- * Routine to generate a new copy of a polygon vertices list. *
- *****************************************************************************/
- struct VertexStruct *CopyVList(VertexStruct *Src)
- {
- struct VertexStruct *Phead, *Ptail, *SrcFirst = Src;
-
- if (Src == NULL) return NULL;
-
- /* Prepare the header of the new vertex list: */
- Phead = Ptail = AllocVertex(Src -> Count, Src -> Tags, NULL, NULL);
- PT_COPY(Phead -> Pt, Src -> Pt);
- Src = Src -> Pnext;
-
- while (Src != SrcFirst && Src != NULL) {
- Ptail -> Pnext = AllocVertex(Src -> Count, Src -> Tags, NULL, NULL);
- Ptail = Ptail -> Pnext;
- PT_COPY(Ptail -> Pt, Src -> Pt);
-
- Src = Src -> Pnext;
- }
-
- if (Src == SrcFirst) Ptail -> Pnext = Phead;/* Make vertex list circular.*/
-
- return Phead;
- }
-