/* * solidify.c - Merge two opposing faces of a part into a solid * * Written 2010 by Werner Almesberger * Copyright 2010 Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include #include #include #include #include "face.h" #include "solid.h" #include "style.h" #include "level.h" #include "overlap.h" static struct solid solid; static const struct face *active; static GtkWidget *canvas; static void clicked(GtkButton *button, gpointer user_data) { struct face *face = user_data; if (active == face) return; gtk_widget_destroy(gtk_bin_get_child(GTK_BIN(canvas))); if (face) level(canvas, face); else overlap(canvas, &solid); active = face; gtk_widget_show_all(canvas); } static GtkWidget *gui_buttons(void) { GtkWidget *vbox, *but; vbox = gtk_vbox_new(FALSE, 0); but = gtk_button_new_with_label("A"); gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(but), "clicked", G_CALLBACK(clicked), solid.a); but = gtk_button_new_with_label("B"); gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(but), "clicked", G_CALLBACK(clicked), solid.b); but = gtk_button_new_with_label("A+B"); gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(but), "clicked", G_CALLBACK(clicked), NULL); return vbox; } static gboolean key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data) { if (event->keyval == 'q') gtk_main_quit(); return TRUE; } static void gui(void) { GtkWidget *root, *hbox, *buttons; root = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(root), GTK_WIN_POS_CENTER); hbox = gtk_hbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(root), hbox); canvas = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(hbox), canvas, FALSE, FALSE, 0); /* initialize root->window */ gtk_widget_show_all(root); buttons = gui_buttons(); gtk_box_pack_start(GTK_BOX(hbox), buttons, FALSE, FALSE, 0); level(canvas, solid.a); active = solid.a; init_style(root->window); gtk_widget_show_all(root); g_signal_connect(G_OBJECT(root), "key-press-event", G_CALLBACK(key_press_event), NULL); g_signal_connect(G_OBJECT(root), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_main(); } static void usage(const char *name) { fprintf(stderr, "usage: %s top bottom dist\n", name); exit(1); } int main(int argc, char **argv) { gtk_init(&argc, &argv); setlocale(LC_ALL, "C"); /* damage control */ switch (argc) { case 4: break; default: usage(*argv); } solid.a = read_face(argv[1]); solid.b = read_face(argv[2]); if (solid.a->x_step != solid.a->x_step || solid.a->y_step != solid.a->y_step || solid.a->z_step != solid.a->z_step) { fprintf(stderr, "both faces must have the same resolution\n"); exit(1); } solid.dist = atof(argv[3])/solid.a->z_step; gui(); if (!isatty(1)) povray(&solid); return 0; }