mirror of
git://projects.qi-hardware.com/ben-scans.git
synced 2024-11-22 03:14:39 +02:00
Introduce a solid data type and use it, mainly in overlap()
- solidify/solid.h: definition of a solid made from two opposing faces - solidify/overlap.h (overlap), solidify/overlap.c (draw_image, scroll_event, overlap): operate on solid instead of face - solidify/overlap.c (sx, sy, draw_image, overlap): helper functions sx() and sy() to determine canvas size - solidify/overlap.c (BORDER, sx, sy): added a border around the piece, to help with positioning - solidify/solidify.c (clicked, gui_buttons, gui, main): use solid instead of faces
This commit is contained in:
parent
b8bba1d3ab
commit
1fa23c574e
@ -18,10 +18,24 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#include "face.h"
|
#include "face.h"
|
||||||
|
#include "solid.h"
|
||||||
#include "overlap.h"
|
#include "overlap.h"
|
||||||
|
|
||||||
|
|
||||||
#define UNDEF_F HUGE_VAL
|
#define UNDEF_F HUGE_VAL
|
||||||
|
#define BORDER 10 /* pixels around the minimum drawing area */
|
||||||
|
|
||||||
|
|
||||||
|
static int sx(const struct solid *s)
|
||||||
|
{
|
||||||
|
return (s->a->sx > s->b->sx ? s->a->sx : s->b->sx)+2*BORDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int sy(const struct solid *s)
|
||||||
|
{
|
||||||
|
return (s->a->sy > s->b->sy ? s->a->sy : s->b->sy)+2*BORDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static double ramp(int z0, double w0, int z1, double w1)
|
static double ramp(int z0, double w0, int z1, double w1)
|
||||||
@ -59,19 +73,20 @@ static double zmix(struct face *f, double x, double y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void draw_image(GtkWidget *widget, struct face *f)
|
static void draw_image(GtkWidget *widget, struct solid *s)
|
||||||
{
|
{
|
||||||
guchar *rgbbuf, *p;
|
guchar *rgbbuf, *p;
|
||||||
int x, y;
|
int x, y;
|
||||||
double z;
|
double z;
|
||||||
|
struct face *f = s->a;
|
||||||
|
|
||||||
rgbbuf = p = calloc(f->sx*f->sy, 3);
|
rgbbuf = p = calloc(sx(s)*sy(s), 3);
|
||||||
if (!rgbbuf) {
|
if (!rgbbuf) {
|
||||||
perror("calloc");
|
perror("calloc");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
for (y = f->sy-1; y >= 0; y--)
|
for (y = sy(s)-1; y >= 0; y--)
|
||||||
for (x = 0; x != f->sx ; x++) {
|
for (x = 0; x != sx(s) ; x++) {
|
||||||
int xa = x+f->a->min_x;
|
int xa = x+f->a->min_x;
|
||||||
int ya = y+f->a->min_y;
|
int ya = y+f->a->min_y;
|
||||||
|
|
||||||
@ -93,7 +108,7 @@ static void draw_image(GtkWidget *widget, struct face *f)
|
|||||||
}
|
}
|
||||||
gdk_draw_rgb_image(widget->window,
|
gdk_draw_rgb_image(widget->window,
|
||||||
widget->style->fg_gc[GTK_STATE_NORMAL],
|
widget->style->fg_gc[GTK_STATE_NORMAL],
|
||||||
0, 0, f->sx, f->sy, GDK_RGB_DITHER_MAX, rgbbuf, f->sx*3);
|
0, 0, sx(s), sy(s), GDK_RGB_DITHER_MAX, rgbbuf, sx(s)*3);
|
||||||
free(rgbbuf);
|
free(rgbbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +139,8 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
|
|||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
GtkWidget *da = gtk_bin_get_child(GTK_BIN(widget));
|
GtkWidget *da = gtk_bin_get_child(GTK_BIN(widget));
|
||||||
struct face *f = data;
|
struct solid *s = data;
|
||||||
|
struct face *f = s->a;
|
||||||
int dx = event->x-f->sx/2;
|
int dx = event->x-f->sx/2;
|
||||||
int dy = event->y-f->sy/2;
|
int dy = event->y-f->sy/2;
|
||||||
double r = hypot(dx, dy);
|
double r = hypot(dx, dy);
|
||||||
@ -134,11 +150,11 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
|
|||||||
switch (event->direction) {
|
switch (event->direction) {
|
||||||
case GDK_SCROLL_UP:
|
case GDK_SCROLL_UP:
|
||||||
rotate(&f->m, r);
|
rotate(&f->m, r);
|
||||||
draw_image(da, f);
|
draw_image(da, s);
|
||||||
break;
|
break;
|
||||||
case GDK_SCROLL_DOWN:
|
case GDK_SCROLL_DOWN:
|
||||||
rotate(&f->m, -r);
|
rotate(&f->m, -r);
|
||||||
draw_image(da, f);
|
draw_image(da, s);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* ignore */;
|
/* ignore */;
|
||||||
@ -156,22 +172,20 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void overlap(GtkWidget *canvas, struct face *f)
|
void overlap(GtkWidget *canvas, struct solid *s)
|
||||||
{
|
{
|
||||||
GtkWidget *evbox, *da;
|
GtkWidget *evbox, *da;
|
||||||
|
|
||||||
evbox = gtk_event_box_new();
|
evbox = gtk_event_box_new();
|
||||||
da = gtk_drawing_area_new();
|
da = gtk_drawing_area_new();
|
||||||
gtk_widget_set_size_request(da, f->sx, f->sy);
|
gtk_widget_set_size_request(da, sx(s), sy(s));
|
||||||
gtk_container_add(GTK_CONTAINER(canvas), evbox);
|
gtk_container_add(GTK_CONTAINER(canvas), evbox);
|
||||||
gtk_container_add(GTK_CONTAINER(evbox), da);
|
gtk_container_add(GTK_CONTAINER(evbox), da);
|
||||||
|
|
||||||
draw_image(da, f);
|
draw_image(da, s);
|
||||||
|
|
||||||
g_signal_connect(G_OBJECT(evbox), "scroll-event",
|
g_signal_connect(G_OBJECT(evbox), "scroll-event",
|
||||||
G_CALLBACK(scroll_event), f);
|
G_CALLBACK(scroll_event), s);
|
||||||
g_signal_connect(G_OBJECT(da), "expose-event",
|
g_signal_connect(G_OBJECT(da), "expose-event",
|
||||||
G_CALLBACK(expose_event), f);
|
G_CALLBACK(expose_event), s);
|
||||||
|
|
||||||
return evbox;
|
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "solid.h"
|
||||||
|
|
||||||
void overlap(GtkWidget *canvas, struct face *face);
|
|
||||||
|
void overlap(GtkWidget *canvas, struct solid *solid);
|
||||||
|
|
||||||
#endif /* !OVERLAP_H */
|
#endif /* !OVERLAP_H */
|
||||||
|
21
solidify/solid.h
Normal file
21
solidify/solid.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* solid.h - Data structure and handling of a solid made of two opposing faces
|
||||||
|
*
|
||||||
|
* Written 2010 by Werner Almesberger
|
||||||
|
* Copyright 2010 by 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SOLID_H
|
||||||
|
#define SOLID_H
|
||||||
|
|
||||||
|
struct solid {
|
||||||
|
struct face *a, *b;
|
||||||
|
double dist;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* SOLID_H */
|
@ -17,11 +17,12 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#include "face.h"
|
#include "face.h"
|
||||||
|
#include "solid.h"
|
||||||
#include "level.h"
|
#include "level.h"
|
||||||
#include "overlap.h"
|
#include "overlap.h"
|
||||||
|
|
||||||
|
|
||||||
static struct face *face_a, *face_b;
|
static struct solid solid;
|
||||||
static const struct face *active;
|
static const struct face *active;
|
||||||
static GtkWidget *canvas;
|
static GtkWidget *canvas;
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ static void clicked(GtkButton *button, gpointer user_data)
|
|||||||
if (face)
|
if (face)
|
||||||
level(canvas, face);
|
level(canvas, face);
|
||||||
else
|
else
|
||||||
overlap(canvas, face_a);
|
overlap(canvas, &solid);
|
||||||
active = face;
|
active = face;
|
||||||
|
|
||||||
gtk_widget_show_all(canvas);
|
gtk_widget_show_all(canvas);
|
||||||
@ -54,12 +55,12 @@ static GtkWidget *gui_buttons(void)
|
|||||||
but = gtk_button_new_with_label("A");
|
but = gtk_button_new_with_label("A");
|
||||||
gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0);
|
gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0);
|
||||||
g_signal_connect(G_OBJECT(but), "clicked",
|
g_signal_connect(G_OBJECT(but), "clicked",
|
||||||
G_CALLBACK(clicked), face_a);
|
G_CALLBACK(clicked), solid.a);
|
||||||
|
|
||||||
but = gtk_button_new_with_label("B");
|
but = gtk_button_new_with_label("B");
|
||||||
gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0);
|
gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0);
|
||||||
g_signal_connect(G_OBJECT(but), "clicked",
|
g_signal_connect(G_OBJECT(but), "clicked",
|
||||||
G_CALLBACK(clicked), face_b);
|
G_CALLBACK(clicked), solid.b);
|
||||||
|
|
||||||
but = gtk_button_new_with_label("A+B");
|
but = gtk_button_new_with_label("A+B");
|
||||||
gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0);
|
gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0);
|
||||||
@ -98,8 +99,8 @@ static void gui(void)
|
|||||||
buttons = gui_buttons();
|
buttons = gui_buttons();
|
||||||
gtk_box_pack_start(GTK_BOX(hbox), buttons, FALSE, FALSE, 0);
|
gtk_box_pack_start(GTK_BOX(hbox), buttons, FALSE, FALSE, 0);
|
||||||
|
|
||||||
level(canvas, face_a);
|
level(canvas, solid.a);
|
||||||
active = face_a;
|
active = solid.a;
|
||||||
|
|
||||||
gtk_widget_show_all(root);
|
gtk_widget_show_all(root);
|
||||||
|
|
||||||
@ -129,8 +130,8 @@ int main(int argc, char **argv)
|
|||||||
usage(*argv);
|
usage(*argv);
|
||||||
}
|
}
|
||||||
setlocale(LC_ALL, "C"); /* damage control */
|
setlocale(LC_ALL, "C"); /* damage control */
|
||||||
face_a = read_face(argv[1]);
|
solid.a = read_face(argv[1]);
|
||||||
face_b = face_a;
|
solid.b = solid.a;
|
||||||
gui();
|
gui();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user