home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * "Irit" - the 3d polygonal solid modeller. *
- * *
- * Written by: Gershon Elber Ver 0.2, Mar. 1990 *
- ******************************************************************************
- * Dynamic allocation module of "Irit" - the 3d polygonal solid modeller. *
- *****************************************************************************/
-
- /* #define DEBUG Print more messages in free/allocating. */
-
- #ifdef __MSDOS__
- #include <alloc.h>
- #include <time.h>
- #endif /* __MSDOS__ */
-
- #include <stdio.h>
- #include <string.h>
- #include "program.h"
- #include "allocate.h"
- #include "attribut.h"
- #include "ctrl-brk.h"
- #include "graphgen.h"
- #include "windows.h"
-
- #define MAGIC_FREE_NUM 1234567890L /* Used in DEBUG mode to mark free. */
-
- #define ALLOCATE_NUM 100 /* Number of objects to allocate at once. */
-
- #ifdef __MSDOS__
- /* Used to say when to update core left on screen: */
- static time_t LastTimeAlloc = 0;
- #endif /* __MSDOS__ */
-
- /* Used for fast reallocation of most common object types: */
- static VertexStruct *VertexFreedList = NULL;
- static PolygonStruct *PolygonFreedList = NULL;
- static ObjectStruct *ObjectFreedList = NULL;
-
- static void FreePolygonList(PolygonStruct * PPoly);
- static void FreeVertexList(VertexStruct * VFirst);
-
- /*****************************************************************************
- * My Routine to allocate dynamic memory. All program requests must call this *
- * routine (no direct call to malloc). Dies if no memory. *
- * In order to reduce the overhead of the allocation, basic objects are *
- * allocated in ALLOCATE_NUM number of objects blocks. *
- *****************************************************************************/
- char *MyMalloc(unsigned int Size, AllocateStructType Type)
- {
- char *p;
- int i;
-
- # ifdef __MSDOS__
- if (time(NULL) != LastTimeAlloc) {
- if (GlblWasCtrlBrk) FatalError(NULL); /* Jump to main loop. */
- WndwStatusWindowUpdate(); /* Print free memory. */
- LastTimeAlloc = time(NULL);
- }
- # endif /* __MSDOS__ */
-
- switch (Type) {
- case ALLOC_VERTEX:
- # ifdef DEBUG
- fprintf(stderr, "MyMalloc: Allocate vertex type");
- # endif /* DEBUG */
- if (VertexFreedList != NULL) {
- p = (char *) VertexFreedList;
- VertexFreedList = VertexFreedList -> Pnext;
- }
- else {
- VertexStruct *V;
-
- /* Allocate ALLOCATE_NUM objects, returns first one as new */
- /* and chain together the rest of them into the free list. */
- p = malloc(Size * ALLOCATE_NUM);
- V = (VertexStruct *) p;
- if (V != NULL) {
- for (i = 1; i < ALLOCATE_NUM-1; i++) V[i].Pnext = &V[i+1];
- V[ALLOCATE_NUM-1].Pnext = NULL;
- VertexFreedList = &V[1];
- }
- }
- break;
- case ALLOC_POLYGON:
- # ifdef DEBUG
- fprintf(stderr, "MyMalloc: Allocate polygon type");
- # endif /* DEBUG */
- if (PolygonFreedList != NULL) {
- p = (char *) PolygonFreedList;
- PolygonFreedList = PolygonFreedList -> Pnext;
- }
- else {
- PolygonStruct *V;
-
- /* Allocate ALLOCATE_NUM objects, returns first one as new */
- /* and chain together the rest of them into the free list. */
- p = malloc(Size * ALLOCATE_NUM);
- V = (PolygonStruct *) p;
- if (V != NULL) {
- for (i = 1; i < ALLOCATE_NUM-1; i++) V[i].Pnext = &V[i+1];
- V[ALLOCATE_NUM-1].Pnext = NULL;
- PolygonFreedList = &V[1];
- }
- }
- break;
- case ALLOC_OBJECT:
- # ifdef DEBUG
- fprintf(stderr, "MyMalloc: Allocate object type");
- # endif /* DEBUG */
- if (ObjectFreedList != NULL) {
- p = (char *) ObjectFreedList;
- ObjectFreedList = ObjectFreedList -> Pnext;
- }
- else {
- ObjectStruct *V;
-
- /* Allocate ALLOCATE_NUM objects, returns first one as new */
- /* and chain together the rest of them into the free list. */
- p = malloc(Size * ALLOCATE_NUM);
- V = (ObjectStruct *) p;
- if (V != NULL) {
- for (i = 1; i < ALLOCATE_NUM-1; i++) V[i].Pnext = &V[i+1];
- V[ALLOCATE_NUM-1].Pnext = NULL;
- ObjectFreedList = &V[1];
- }
- }
- break;
- default:
- # ifdef DEBUG
- fprintf(stderr, "MyMalloc: Allocate undefined Type %d", Type);
- # endif /* DEBUG */
- p = malloc(Size);
- break;
- }
-
- # ifdef DEBUG
- fprintf(stderr, " (Size = %d, ptr = %p)\n", Size, p);
- # endif /* DEBUG */
-
- if (p != NULL) return p;
-
- WndwInputWindowPutStr("Not enough memory - program cannt continue");
- GlblFatalError = TRUE;
- /* Long jump to main intraction loop - irit.c module */
- longjmp(GlblLongJumpBuffer, 2);
-
- return NULL; /* Only makes warnings silent... */
- }
-
- /*****************************************************************************
- * Routine to free a given structure, which is not needed any more *
- * Note usually only object will be given directly to MyFree which *
- * recursively free its structure... *
- * Also, it is perfectly legal to call with NULL to MyFree... *
- *****************************************************************************/
- void MyFree(char *p, AllocateStructType Type)
- {
- int index;
- char Line[LINE_LEN];
- ObjectStruct *PObj;
-
- # ifdef __MSDOS__
- if (time(NULL) != LastTimeAlloc) {
- if (GlblWasCtrlBrk) FatalError(NULL); /* Jump to main loop. */
- WndwStatusWindowUpdate(); /* Print free memory. */
- LastTimeAlloc = time(NULL);
- }
- # endif /* __MSDOS__ */
-
- if (p == NULL) return;
-
- # ifdef DEBUG
- /* The following might fail if a record is freed without any usage! */
- if (*((long *) p) == MAGIC_FREE_NUM)
- FatalError("MyFree:Free the same record twice, dies");
- *((long *) p) = MAGIC_FREE_NUM; /* And set it for next time... */
- # endif /* DEBUG */
-
- switch (Type) {
- case ALLOC_VERTEX:
- # ifdef DEBUG
- fprintf(stderr, "MyFree: free vertex type\n");
- # endif /* DEBUG */
- FreeVertexList((VertexStruct *) p);
- break;
- case ALLOC_POLYGON:
- # ifdef DEBUG
- fprintf(stderr, "MyFree: free polygon type\n");
- # endif /* DEBUG */
- FreePolygonList((PolygonStruct *) p);
- break;
- case ALLOC_OBJECT:
- # ifdef DEBUG
- fprintf(stderr, "MyFree: free object type\n");
- # endif /* DEBUG */
- PObj = (ObjectStruct *) p;
- if (PObj -> Count > 1) {
- /* Do not free object - just decrease its reference count. */
- PObj -> Count--;
- break;
- }
- switch (((ObjectStruct *) p) -> ObjType) {
- case UNDEF_OBJ:
- break;
- case POLY_OBJ: /* Free the polygon list. */
- MyFree((char *) (PObj -> U.Pl.P), ALLOC_POLYGON);
- ReleaseStrAttrib(PObj);
- break;
- case NUMERIC_OBJ:
- case VECTOR_OBJ:
- case CTLPT_OBJ:
- case MATRIX_OBJ:
- case STRING_OBJ:
- break;
- case OBJ_LIST_OBJ: /* Need to dereference elements in list. */
- index = 0;
- while (index < MAX_OBJ_LIST &&
- PObj -> U.PObjList[index] != NULL) {
- if (PObj -> U.PObjList[index] -> Count-- == 1)
- MyFree((char *) (PObj -> U.PObjList[index]),
- ALLOC_OBJECT);
- index++;
- }
- break;
- case CURVE_OBJ:
- CagdCrvFree(PObj -> U.Crv.Crv);
- if (PObj -> U.Crv.PLPolys)
- CagdPolylineFree(PObj -> U.Crv.PLPolys);
- if (PObj -> U.Crv.CtlPoly)
- CagdPolylineFree(PObj -> U.Crv.CtlPoly);
- ReleaseStrAttrib(PObj);
- break;
- case SURFACE_OBJ:
- CagdSrfFree(PObj -> U.Srf.Srf);
- if (PObj -> U.Srf.PLPolys)
- CagdPolylineFreeList(PObj -> U.Srf.PLPolys);
- if (PObj -> U.Srf.CtlMesh)
- CagdPolylineFreeList(PObj -> U.Srf.CtlMesh);
- if (PObj -> U.Srf.Polygons)
- MyFree((char *) PObj -> U.Srf.Polygons, ALLOC_OBJECT);
- ReleaseStrAttrib(PObj);
- break;
- default: /* Kill the program - something is WRONG! */
- sprintf(Line,
- "MyFree: Attempt to free undefined Object type %d",
- PObj -> ObjType);
- FatalError(Line);
- break;
- }
- /* Add it to global freed object list: */
- PObj -> Pnext = ObjectFreedList;
- ObjectFreedList = PObj;
- break;
- default:
- # ifdef DEBUG
- fprintf(stderr, "MyFree: Free undefined Type %d\n", Type);
- # endif /* DEBUG */
- free(p);
- break;
- }
- }
-
- /*****************************************************************************
- * Routine to free a polygon list each consists of circular vertex list. *
- *****************************************************************************/
- static void FreePolygonList(PolygonStruct *PPoly)
- {
- PolygonStruct *Ptemp, *PPolyHead = PPoly;
-
- # ifdef DEBUG
- fprintf(stderr, "FreePolygonList: free polygon list\n");
- # endif /* DEBUG */
-
- while (PPoly) {
- FreeVertexList(PPoly -> V);
- Ptemp = PPoly;
- PPoly = PPoly -> Pnext;
- }
-
- /* Now chain this new list to the global freed polygon list: */
- Ptemp -> Pnext = PolygonFreedList;
- PolygonFreedList = PPolyHead;
- }
-
- /*****************************************************************************
- * Routine to free a circular vertex list - one polygon contour. *
- *****************************************************************************/
- static void FreeVertexList(VertexStruct *VFirst)
- {
- VertexStruct *V = VFirst, *Vtemp;
-
- # ifdef DEBUG
- fprintf(stderr, "FreeVertexList: free vertex list\n");
- # endif /* DEBUG */
-
- if (VFirst == NULL) return;
-
- do {
- Vtemp = V;
- V = V -> Pnext;
- }
- while (V != NULL && V != VFirst); /* Both - circular or NULL terminated. */
-
- /* Now chain this new list to the global freed vertex list: */
- Vtemp -> Pnext = VertexFreedList;
- VertexFreedList = VFirst;
- }
-
- /*****************************************************************************
- * Allocate one Vertex Structure: *
- *****************************************************************************/
- VertexStruct * AllocVertex(ByteType Count, ByteType Tags,
- PolygonStruct * PAdj, VertexStruct * Pnext)
- {
- VertexStruct *p;
-
- p = (VertexStruct *) MyMalloc(sizeof(VertexStruct), ALLOC_VERTEX);
-
- p -> Normal[0] = p -> Normal[1] = p -> Normal[2] = 0.0;
- p -> Count = Count;
- p -> Tags = Tags;
- p -> Pnext = Pnext;
- p -> PAdj = PAdj;
-
- return p;
- }
-
- /*****************************************************************************
- * Allocate one Polygon Structure: *
- *****************************************************************************/
- PolygonStruct * AllocPolygon(ByteType Count, ByteType Tags,
- VertexStruct * V, PolygonStruct * Pnext)
- {
- PolygonStruct *p;
-
- p = (PolygonStruct *) MyMalloc(sizeof(PolygonStruct), ALLOC_POLYGON);
-
- p -> Plane[0] = p -> Plane[1] = p -> Plane[2] = p -> Plane[3] = 0.0;
- p -> Count = Count;
- p -> Tags = Tags;
- p -> V = V;
- p -> Pnext = Pnext;
-
- return p;
- }
-
- /*****************************************************************************
- * Allocate one Object Structure: *
- *****************************************************************************/
- ObjectStruct * AllocObject(char *Name, IritObjectType ObjType,
- ObjectStruct * Pnext)
- {
- ObjectStruct *p;
-
- p = (ObjectStruct *) MyMalloc(sizeof(ObjectStruct), ALLOC_OBJECT);
-
- strcpy(p -> Name, Name);
- p -> ObjType = ObjType;
- p -> Count = 1;
- p -> Pnext = Pnext;
- p -> U.Pl.P = NULL; /* To be on the safe size... */
- p -> U.Crv.PLPolys = NULL;
- p -> U.Crv.CtlPoly = NULL;
- p -> U.Srf.PLPolys = NULL;
- p -> U.Srf.CtlMesh = NULL;
- p -> U.Srf.Polygons = NULL;
- p -> U.Attr.NumStrAttribs = 0;
-
- return p;
- }
-