libbubulle/bubulles.c
2023-03-30 05:04:17 +02:00

355 lines
8.2 KiB
C

/*
---------- bubulles.c ----------------------------
some functions for managing bubulles in a 3D space.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bubulles.h"
#include "edges.h"
/* --------------------------------------------------------------------- */
int bubulles_version(int k)
{
fprintf(stderr, "###\n### LIBBB %s v %d / %s %s\n###\n",
__FILE__, LIBBB_VERSION, __DATE__, __TIME__);
if (k) {
bubulles_sizeof(k);
}
return 0;
}
/* --------------------------------------------------------------------- */
void bubulles_sizeof(int k)
{
if (k & 0x01) printf(" sizeof structs\n");
printf("%-15s %4lu\n", "XYZ", sizeof(XYZ));
printf("%-15s %4lu\n", "RGBA", sizeof(RGBA));
printf("%-15s %4lu\n", "Bubulle", sizeof(Bubulle));
printf("%-15s %4lu\n", "BBList", sizeof(BBList));
printf("%-15s %4lu\n", "AnEdge", sizeof(AnEdge));
printf("%-15s %4lu\n", "EdgeList", sizeof(EdgeList));
puts("");
}
/* --------------------------------------------------------------------- */
BBList * alloc_bubulles(char *name, int sz, int unused)
{
BBList *bblptr;
Bubulle *array;
#if DEBUG_LEVEL
fprintf(stderr, "+++ %s '%s' %d 0x%X\n", __func__, name, sz, unused);
#endif
if (NULL==(bblptr = calloc(1, sizeof(BBList)))) {
fprintf(stderr, "no mem available in %s\n", __func__);
return NULL;
}
if ( (NULL != name) && (strlen(name) < SZ_BUBULLE_TEXT) )
strcpy(bblptr->name, name);
else
strcpy(bblptr->name, "noname");
bblptr->fidx = 0;
bblptr->size = sz;
bblptr->flags = 0;
if (NULL==(array = calloc(sz, sizeof(Bubulle)))) {
fprintf(stderr, "no mem available in %s\n", __func__);
free(bblptr);
return NULL;
}
bblptr->bbs = array;
#if DEBUG_LEVEL
fprintf(stderr, "\tbblptr is at %p\n", bblptr);
#endif
return bblptr;
}
/* --------------------------------------------------------------------- */
int free_bubulles(BBList *bbl, int k)
{
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d )\n", __func__, bbl, k);
#endif
if (NULL == bbl->bbs) {
fprintf(stderr, "%s : array ptr is null\n", __func__);
#if MUST_ABORT
abort();
#endif
return 1;
}
free(bbl->bbs);
/* it's safe to erase the metadata header (nsa) */
memset(bbl, 0, sizeof(BBList));
/* release a clean memory */ free(bbl);
return 0;
}
/* --------------------------------------------------------------------- */
Bubulle * bubulle_getaddr(BBList *where, int idx)
{
#if DEBUG_LEVEL > 1
fprintf(stderr, ">>> %s ( %p %d )\n", __func__, where, idx);
#endif
if ( (idx < 0) || (idx > where->fidx) ) {
fprintf(stderr, "%s : idx %d out of range on %p\n",
__func__, idx, where);
#if MUST_ABORT
abort();
#endif
return NULL;
}
return ( &where->bbs[idx] );
}
/* --------------------------------------------------------------------- */
int print_bublist_desc(BBList *bbl, int opts)
{
printf("------- bblist at %p\n", bbl);
printf("\tname \t'%s'\n", bbl->name);
printf("\tsize\t%6d\n\tfidx\t%6d\n", bbl->size, bbl->fidx);
if (opts & 0x01) {
printf("\txyz\t%f %f %f\n",
bbl->position.x, bbl->position.y, bbl->position.z);
}
printf("\tflags\t0x%08lX\n", bbl->flags);
printf("\tarray\t%p\n", bbl->bbs);
puts(""); fflush(stdout);
return 0;
}
/* --------------------------------------------------------------------- */
int push_bubulle(BBList *where, Bubulle *what)
{
#if DEBUG_LEVEL > 1
fprintf(stderr, "%s : %p --> %p\n", __func__, what, where);
fprintf(stderr, "XYZ %f %f %f\n", what->p.x, what->p.y, what->p.z);
#endif
if (where->fidx >= where->size) {
/* this is a very bad fatal error */
fprintf(stderr, "%s : overflow in BBList at %p\n", __func__, where);
#if MUST_ABORT
abort();
#endif
return -1;
}
memcpy(&where->bbs[where->fidx], what, sizeof(Bubulle));
where->fidx++;
return 0;
}
/* --------------------------------------------------------------------- */
int poke_bubulle(BBList *where, Bubulle *what, int idx)
{
if ((idx < 0) || (idx > where->size)) {
#if DEBUG_LEVEL
fprintf(stderr, "%s : idx %d out of range\n", __func__, idx);
#endif
return -1;
}
#if DEBUG_LEVEL
fprintf(stderr, "%s : %p --> %p+%d\n", __func__, what, where, idx);
fprintf(stderr, "src XYZ %f %f %f\n", what->p.x, what->p.y, what->p.z);
#endif
memcpy(&where->bbs[idx], what, sizeof(Bubulle));
return 0;
}
/* --------------------------------------------------------------------- */
int peek_bubulle(BBList *from, Bubulle *to, int idx)
{
if (NULL==from) {
fprintf(stderr, "in %s, *from is null\n", __func__);
#if MUST_ABORT
abort();
#endif
return -5;
}
if ((idx < 0) || (idx > from->size)) {
#if DEBUG_LEVEL
fprintf(stderr, "%s : idx %d out of range\n", __func__, idx);
#endif
return -1;
}
memcpy(to, &from->bbs[idx], sizeof(Bubulle));
return 0;
}
/* --------------------------------------------------------------------- */
/* flags :
* 0x0001 print diameter
* 0x0002 print graylevel
* 0x0004 print RGB values
*/
int fprint_bubulles(FILE *fp, char *title, BBList *bbl, int opts)
{
int idx;
Bubulle *ar;
if (NULL == bbl) {
fprintf(stderr, "in %s, *bbl is NULL\n", __func__);
#if MUST_ABORT
abort();
#endif
return -5;
}
ar = bbl->bbs;
#if DEBUG_LEVEL > 1
fprintf(stderr, "*** %s : array at %p, sz %d\n", __func__, ar, bbl->size);
#endif
for (idx=0; idx<bbl->fidx; idx++) {
fprintf(fp, "%12.6f %12.6f %12.6f",
ar[idx].p.x, ar[idx].p.y, ar[idx].p.z);
if (opts & 0x01) fprintf(fp, " %12.6f", ar[idx].d);
if (opts & 0x02) fprintf(fp, " %6d", ar[idx].gray);
fputs("\n", fp);
}
fflush(fp);
return 0;
}
/* --------------------------------------------------------------------- */
int niceprint_bubulle(Bubulle *what, int unused)
{
printf("----------------------- @ %p -----------------\n", what);
printf("xyzd %11.6f %11.6f %11.6f %11.6f\n",
what->p.x, what->p.y, what->p.z, what->d);
printf("diam %11.6f gray %5d\n", what->d, what->gray);
printf("rgba %11.6f %11.6f %11.6f %11.6f\n",
what->col.r, what->col.g, what->col.b, what->col.a);
puts("----------------------------------------------------------");
return 0;
}
/* --------------------------------------------------------------------- */
int cleanfill_my_bublist(BBList *what, int k)
{
Bubulle *ar;
int idx;
if (NULL == what) {
fprintf(stderr, "SHIT HAPPEN IN %s\n", __func__);
#if MUST_ABORT
abort();
#endif
return -5;
}
ar = what->bbs; /* get the bubble array addr */
#if DEBUG_LEVEL > 2
fprintf(stderr, "*O* %s array at %p, sz %d\n",
__func__, ar, what->size);
#endif
for (idx=0; idx<what->size; idx++) {
memset(&ar[idx], 0, sizeof(Bubulle));
ar[idx].kvalue = 1.0;
}
what->fidx = what->size - 1;
return 0;
}
/* --------------------------------------------------------------------- */
/*
* this is the WTF function * see tbb.c
*/
int bubulles_to_data(char *fname, char *title, BBList *bbl, int k)
{
FILE *fp;
int retval;
if (NULL==(fp=fopen(fname, "w"))) {
perror(fname);
return -1;
}
retval = fprint_bubulles(fp, title, bbl, k);
if (retval) {
fprintf(stderr, "something strange (%d) happen in %s\n",
retval, __func__);
}
fclose(fp);
return retval;
}
/* --------------------------------------------------------------------- */
/******* BOUNDING BOXES *******/
int bounding_box(Bubulle *boubs, int nbre, BBox *bbox)
{
int idx;
bbox->minX = bbox->minY = bbox->minZ = 9e99;
bbox->maxX = bbox->maxY = bbox->maxZ = -9e99;
for (idx=0; idx<nbre; idx++) {
if (boubs[idx].p.x > bbox->maxX) bbox->maxX = boubs[idx].p.x;
else if (boubs[idx].p.x < bbox->minX) bbox->minX = boubs[idx].p.x;
if (boubs[idx].p.y > bbox->maxY) bbox->maxY = boubs[idx].p.y;
else if (boubs[idx].p.y < bbox->minY) bbox->minY = boubs[idx].p.y;
if (boubs[idx].p.z > bbox->maxZ) bbox->maxZ = boubs[idx].p.z;
else if (boubs[idx].p.z < bbox->minZ) bbox->minZ = boubs[idx].p.z;
}
return 0;
}
/* --------------------------------------------------------------------- */
int print_bbox(BBox *bbox, int k)
{
if (NULL==bbox) {
fprintf(stderr, "in %s, *bbox is NULL\n", __func__);
#if MUST_ABORT
abort();
#endif
return -5;
}
printf("%9.6f %9.6f %9.6f %9.6f %9.6f %9.6f\n",
bbox->minX, bbox->minY, bbox->minZ,
bbox->maxX, bbox->maxY, bbox->maxZ);
return 0;
}
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */