/* solid.c: routines for manipulating BREP_SOLID structs */ #include "brep.h" #include "private.h" #include "pools.h" #ifndef NOPOOLS static POOL *solidPool = (POOL *)NULL; #define NEWSOLID() (BREP_SOLID *)NewPoolCell(sizeof(BREP_SOLID), 0, "brep solids", &solidPool) #define DISPOSESOLID(ptr) Dispose((unsigned char *)(ptr), &solidPool) #else /* NOPOOLS */ #define NEWSOLID() (BREP_SOLID *)Alloc(sizeof(BREP_SOLID)) #define DISPOSESOLID(ptr) Free((char *)ptr, sizeof(BREP_SOLID)) #endif /* NOPOOLS */ /* callback functions for manipulating BREP_SOLIDs */ static BREP_CALLBACK_FUNC brep_close_solid_callback = (BREP_CALLBACK_FUNC)NULL, brep_destroy_solid_callback = (BREP_CALLBACK_FUNC)NULL, brep_create_solid_callback = (BREP_CALLBACK_FUNC)NULL; /* set the CreateSolid callback routine */ BREP_CALLBACK_FUNC BrepSetCreateSolidCallback(BREP_CALLBACK_FUNC func) { BREP_CALLBACK_FUNC oldfunc = brep_create_solid_callback; brep_create_solid_callback = func; return oldfunc; } /* set the CloseSolid callback routine */ BREP_CALLBACK_FUNC BrepSetCloseSolidCallback(BREP_CALLBACK_FUNC func) { BREP_CALLBACK_FUNC oldfunc = brep_close_solid_callback; brep_close_solid_callback = func; return oldfunc; } /* set the DestroySolid callback routine */ BREP_CALLBACK_FUNC BrepSetDestroySolidCallback(BREP_CALLBACK_FUNC func) { BREP_CALLBACK_FUNC oldfunc = brep_destroy_solid_callback; brep_destroy_solid_callback = func; return oldfunc; } /* creates an empty solid */ BREP_SOLID *BrepCreateSolid(void *client_data) { BREP_SOLID *solid; solid = NEWSOLID(); solid->vertices = BrepCreateVertexOctree(); solid->shells = (BREP_SHELL *)NULL; /* notify the user that the solid is created */ solid->client_data = client_data; if (brep_create_solid_callback) solid->client_data = brep_create_solid_callback(solid); return solid; } /* performs various actions to be done when the boundary representation of * the solid has been completely specified. */ void BrepCloseSolid(BREP_SOLID *solid) { /* notify the user that the shells are complete */ BrepSolidIterateShells(solid, BrepCloseShell); /* notify the user that the solid is complete */ if (brep_close_solid_callback) solid->client_data = brep_close_solid_callback(solid); } /* execute func for every shell in the solid */ void BrepSolidIterateShells(BREP_SOLID *solid, void (*func)(BREP_SHELL *)) { BrepIterate((BREP_RING *)solid->shells, (void (*)(BREP_RING *))func); } void BrepSolidIterateShells1A(BREP_SOLID *solid, void (*func)(BREP_SHELL *, void *), void *parm) { BrepIterate1A((BREP_RING *)solid->shells, (void (*)(BREP_RING *, void *))func, parm); } void BrepSolidIterateShells2A(BREP_SOLID *solid, void (*func)(BREP_SHELL *, void *, void *), void *parm1, void *parm2) { BrepIterate2A((BREP_RING *)solid->shells, (void (*)(BREP_RING *, void *, void *))func, parm1, parm2); } /* destroys the shells in a solid */ static void BrepSolidDestroyShells(BREP_SHELL *first) { BREP_SHELL *shell, *prev; if (first) { for (shell = first->prev; shell != first; shell = prev) { prev = shell->prev; BrepDestroyShell(shell); } BrepDestroyShell(first); } } #ifdef NEVER /* destroys all the vertices in a solid, this does not happen automatically when * destroying a solid. Or is it? */ static void BrepSolidDestroyVertices(BREP_SOLID *solid) { BrepIterateVertices(solid->vertices, BrepDestroyVertex); } #endif /*NEVER*/ /* releases all memory associated with the solid */ void BrepDestroySolid(BREP_SOLID *solid) { /* inverse operations of BrepCreateSolid, and in reverse order */ /* first let the user dispose of the client data */ if (brep_destroy_solid_callback) brep_destroy_solid_callback(solid); /* next dispose of the shells in the solid */ BrepSolidDestroyShells(solid->shells); /* next dispose of the vertex octree */ BrepDestroyVertices(solid->vertices); /* finally dispose of the BREP_SOLID structure itself */ DISPOSESOLID(solid); }