diff --git a/solidify/Makefile b/solidify/Makefile index 4e021b9..ab6ef27 100644 --- a/solidify/Makefile +++ b/solidify/Makefile @@ -1,7 +1,7 @@ CFLAGS=-Wall -g `pkg-config --cflags gtk+-2.0` LDFLAGS=-lm `pkg-config --libs gtk+-2.0` -OBJS=array.o face.o level.o solidify.o +OBJS=array.o face.o histo.o level.o solidify.o .PHONY: all clean diff --git a/solidify/face.c b/solidify/face.c index 2f52f89..d057ba6 100644 --- a/solidify/face.c +++ b/solidify/face.c @@ -5,6 +5,7 @@ #include "util.h" #include "array.h" +#include "histo.h" #include "face.h" @@ -12,13 +13,32 @@ struct face *read_face(const char *name) { FILE *file; struct face *f; + struct histo *h; float x, y, z; int xi, yi, zi; - file = strcmp(name, "-") ? fopen(name, "r") : stdin; - if (!file) { - perror(name); - exit(1); + if (!strcmp(name, "-")) { + file = stdin; + } else { + int len; + + len = strlen(name); + if (len > 4 && !strcmp(name+len-4, ".bz2")) { + char tmp[1000]; /* @@@ enough */ + + sprintf(tmp, "bzcat \"%s\"", name); + file = popen(tmp, "r"); + if (!file) { + perror(tmp); + exit(1); + } + } else { + file = fopen(name, "r"); + if (!file) { + perror(name); + exit(1); + } + } } f = alloc_type(struct face); f->a = new_array(); @@ -30,11 +50,14 @@ struct face *read_face(const char *name) zi = round(z*40.0); set(f->a, xi, yi, zi); } - (void) fclose(file); + if (file != stdin) + (void) fclose(file); f->sx = f->a->max_x-f->a->min_x+1; f->sy = f->a->max_y-f->a->min_y+1; - f->z_ref = (f->a->min_z+f->a->max_z)/2; + h = make_histo(f->a); + f->z_ref = f->a->min_z+median(h); + free_histo(h); fprintf(stderr, "%d-%d / %d-%d / %d-%d\n", f->a->min_x, f->a->max_x, f->a->min_y, f->a->max_y, f->a->min_z, f->a->max_z); diff --git a/solidify/histo.c b/solidify/histo.c new file mode 100644 index 0000000..c1e9153 --- /dev/null +++ b/solidify/histo.c @@ -0,0 +1,39 @@ +#include "util.h" +#include "array.h" +#include "histo.h" + + +struct histo *make_histo(struct array *a) +{ + int i; + struct histo *h; + + h = alloc_type(struct histo); + h->n = a->max_z-a->min_z+1; + h->b = alloc_size(h->n*sizeof(int)); + for (i = 0; i != h->n; i++) + h->b[i] = 0; + for (i = 0; i != (a->max_x-a->min_x+1)*(a->max_y-a->min_y+1); i++) + if (a->data[i] != UNDEF) + h->b[a->data[i]-a->min_z]++; + return h; +} + + +void free_histo(struct histo *h) +{ + free(h); +} + + +int median(const struct histo *h) +{ + int tot = 0, sum = 0; + int i; + + for (i = 0; i != h->n; i++) + tot += h->b[i]; + for (i = 0; sum < tot/2; i++) + sum += h->b[i]; + return i-1; +} diff --git a/solidify/histo.h b/solidify/histo.h new file mode 100644 index 0000000..cef3c9b --- /dev/null +++ b/solidify/histo.h @@ -0,0 +1,17 @@ +#ifndef HISTO_H +#define HISTO_H + +#include "array.h" + + +struct histo { + int n; /* number of bins */ + int *b; /* bins */ +}; + + +struct histo *make_histo(struct array *a); +void free_histo(struct histo *h); +int median(const struct histo *h); + +#endif /* HISTO_H */