From 525e1557ec1a8e924b25a86c1efe61c93da21179 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Fri, 24 Sep 2010 00:43:56 -0300 Subject: [PATCH] Use two faces and show how they overlap (in progress) - solidify/face.h (face_z0): calculate height of z0 plane - solidify/level.c (draw_image): use face_z0 instead of open-coding the calculation - solidify/overlap.c (draw_image, point): moved per-point processing from draw_image() to point() - solidify/overlap.c (point): show differences between both faces - solidify/solidify.c (usage, main): load both faces - solidify/solidify.c (usage, main): accept distance between faces as third argument --- solidify/face.h | 6 ++++ solidify/level.c | 2 +- solidify/overlap.c | 85 ++++++++++++++++++++++++++++++++++----------- solidify/solidify.c | 7 ++-- 4 files changed, 76 insertions(+), 24 deletions(-) diff --git a/solidify/face.h b/solidify/face.h index fefc3de..4c6fac1 100644 --- a/solidify/face.h +++ b/solidify/face.h @@ -38,6 +38,12 @@ struct face { }; +static inline double face_z0(const struct face *f, int x, int y) +{ + return f->z_ref+f->fx*(x-f->sx/2)+f->fy*(y-f->sy/2); +} + + struct face *read_face(const char *name); #endif /* FACE_H */ diff --git a/solidify/level.c b/solidify/level.c index 5fe314c..20ea52b 100644 --- a/solidify/level.c +++ b/solidify/level.c @@ -42,7 +42,7 @@ static void draw_image(GtkWidget *widget, struct face *f) p += 3; continue; } - z0 = f->z_ref+f->fx*(x-f->sx/2)+f->fy*(y-f->sy/2); + z0 = face_z0(f, x, y); if (fabs(z-z0) < NEAR) { *p++ = 255*fabs(z-z0); *p++ = 255*fabs(z-z0); diff --git a/solidify/overlap.c b/solidify/overlap.c index 996cabf..a9dd805 100644 --- a/solidify/overlap.c +++ b/solidify/overlap.c @@ -73,12 +73,73 @@ static double zmix(struct face *f, double x, double y) } +static void point(const struct solid *s, int x, int y, guchar *p) +{ + double za, zb, z; + int xa = x+s->a->a->min_x; + int ya = y+s->a->a->min_y; + int yb = sy(s)-1-y+s->a->a->min_y; + + za = zmix(s->a, + xa*s->a->m.a[0][0]+ya*s->a->m.a[0][1]+s->a->m.b[0], + xa*s->a->m.a[1][0]+ya*s->a->m.a[1][1]+s->a->m.b[1]); + + zb = zmix(s->b, + xa*s->b->m.a[0][0]+yb*s->b->m.a[0][1]+s->b->m.b[0], + xa*s->b->m.a[1][0]+yb*s->b->m.a[1][1]+s->b->m.b[1]); + + if (za == UNDEF_F && zb == UNDEF_F) + return; + + if (za == UNDEF_F) { + z = 128.0*(zb-s->b->a->min_z)/(s->b->a->max_z-s->b->a->min_z); + if (z < 0) + z = 0; + if (z > 255) + z = 255; + p[0] = 255; + p[1] = z; + p[2] = z; + return; + } + if (zb == UNDEF_F) { + z = 128.0*(za-s->a->a->min_z)/(s->a->a->max_z-s->a->a->min_z); + if (z < 0) + z = 0; + if (z > 255) + z = 255; + p[0] = z; + p[1] = 255; + p[2] = z; + return; + } + + z = za; + za -= face_z0(s->a, xa, ya); + zb -= face_z0(s->b, xa, yb); + + if (za+zb < -s->dist) { + p[0] = 0; + p[1] = 0; + p[2] = 255; + return; + } + + z = 256.0*(z-s->a->a->min_z)/(s->a->a->max_z-s->a->a->min_z); + if (z < 0) + z = 0; + if (z > 255) + z = 255; + p[0] = z; + p[1] = z; + p[2] = z; +} + + static void draw_image(GtkWidget *widget, struct solid *s) { guchar *rgbbuf, *p; int x, y; - double z; - struct face *f = s->a; rgbbuf = p = calloc(sx(s)*sy(s), 3); if (!rgbbuf) { @@ -87,24 +148,8 @@ static void draw_image(GtkWidget *widget, struct solid *s) } for (y = sy(s)-1; y >= 0; y--) for (x = 0; x != sx(s) ; x++) { - int xa = x+f->a->min_x; - int ya = y+f->a->min_y; - - z = zmix(f, - xa*f->m.a[0][0]+ya*f->m.a[0][1]+f->m.b[0], - xa*f->m.a[1][0]+ya*f->m.a[1][1]+f->m.b[1]); - if (z == UNDEF_F) { - p += 3; - continue; - } - z = 256.0*(z-f->a->min_z)/(f->a->max_z-f->a->min_z); - if (z < 0) - z = 0; - if (z > 255) - z = 255; - *p++ = z; - *p++ = z; - *p++ = z; + point(s, x, y, p); + p += 3; } gdk_draw_rgb_image(widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], diff --git a/solidify/solidify.c b/solidify/solidify.c index 5fc358b..b306c1b 100644 --- a/solidify/solidify.c +++ b/solidify/solidify.c @@ -115,7 +115,7 @@ static void gui(void) static void usage(const char *name) { - fprintf(stderr, "usage: %s top XXXbottomXXX\n", name); + fprintf(stderr, "usage: %s top bottom dist\n", name); exit(1); } @@ -124,14 +124,15 @@ int main(int argc, char **argv) { gtk_init(&argc, &argv); switch (argc) { - case 2: + case 4: break; default: usage(*argv); } setlocale(LC_ALL, "C"); /* damage control */ solid.a = read_face(argv[1]); - solid.b = solid.a; + solid.b = read_face(argv[2]); + solid.dist = atof(argv[3])/0.025; /* @@@ hack */ gui(); return 0;