summaryrefslogtreecommitdiff
path: root/meme
diff options
context:
space:
mode:
authorWerner Almesberger <werner@almesberger.net>2016-02-14 03:54:57 (GMT)
committerWerner Almesberger <werner@almesberger.net>2016-02-14 03:55:32 (GMT)
commitd5afcf56635da6a906dc7343fed6576720b809ba (patch)
tree7bf699aadec0e766347b175f8dd3510c10c82293 /meme
parent72e6384adec350a300e7c508ee027f3ec8b5857c (diff)
downloadmisc-d5afcf56635da6a906dc7343fed6576720b809ba.zip
misc-d5afcf56635da6a906dc7343fed6576720b809ba.tar.gz
misc-d5afcf56635da6a906dc7343fed6576720b809ba.tar.bz2
meme/: add marker system (for documentation); option -m marker.gp to add markers
Diffstat (limited to 'meme')
-rw-r--r--meme/Makefile2
-rw-r--r--meme/README17
-rw-r--r--meme/gui.c57
-rw-r--r--meme/gui.h8
-rw-r--r--meme/marker.c158
-rw-r--r--meme/marker.h36
-rw-r--r--meme/meme.c9
7 files changed, 280 insertions, 7 deletions
diff --git a/meme/Makefile b/meme/Makefile
index 5022e38..d702c2c 100644
--- a/meme/Makefile
+++ b/meme/Makefile
@@ -14,7 +14,7 @@ include Makefile.c-common
CFLAGS = -Wall -Wshadow -g -O9
OBJS = meme.o stl.o mesh.o gui.o time.o plane.o text.o gaux.o overlay.o \
- slice.o screen.o
+ slice.o screen.o marker.o
CFLAGS += $(shell sdl-config --cflags)
LDLIBS = $(shell sdl-config --libs) -lSDL_gfx -lSDL_Pango -lgsl -lgslcblas -lm
diff --git a/meme/README b/meme/README
index a157389..81e6fa8 100644
--- a/meme/README
+++ b/meme/README
@@ -4,7 +4,8 @@ Mesh measurement utility
Usage:
-meme [-d dump.bmp] [-l logfile] [-o overlay.gp ...] <path-to-STL-file>
+meme [-d dump.bmp] [-l logfile] [-m marker.gp] [-o overlay.gp ...]
+ <path-to-STL-file>
meme -s slice.gp [-n] <path-to-STL-file>
@@ -99,6 +100,20 @@ selected with the numeric keys, starting with 1.
To better visualize overlays, the mesh can be toggled by pressing M.
+Marker
+------
+
+Makers are similar to overlays and are used to indicate measurements or
+to mark features in the mesh. Markers are read from the file specified
+with the -m option.
+
+A marker only consisting of text is defined with the line
+x y text
+
+A marker indicating a measurement between points A and B is defined with
+ax ay bx by text
+
+
Slicing
-------
diff --git a/meme/gui.c b/meme/gui.c
index 4133db6..239ac3c 100644
--- a/meme/gui.c
+++ b/meme/gui.c
@@ -23,6 +23,7 @@
#include "time.h"
#include "mesh.h"
#include "overlay.h"
+#include "marker.h"
#include "plane.h"
#include "gaux.h"
#include "screen.h"
@@ -49,11 +50,14 @@
#define EQUAL_RGBA 0xf080ffff
#define OVERLAY_MIX_RGBA 0xffc01060
#define OVERLAY_ALONE_RGBA 0xffc010ff
+#define MARKER_LINE_RGBA 0x00ff00ff
#define DEPTH_RANGE 0xc0
#define DEPTH_OFFSET 0x30
+struct marker marker;
+
static int x_orig, y_orig;
static Sint16 xres, yres;
static int x_min, x_max, y_min, y_max, z_min, z_max;
@@ -897,7 +901,6 @@ static void marker_next(void)
/* ----- Overlay ----------------------------------------------------------- */
-
static Sint16 ovl_x, ovl_y;
static int ovl_ok;
@@ -939,6 +942,56 @@ static void draw_overlay(SDL_Surface *s, const struct overlay *over)
}
+/* ----- Markers ----------------------------------------------------------- */
+
+
+#define TEXT_OFFSET_X -4
+#define TEXT_OFFSET_Y -5
+#define TEXT_DIST 10
+
+
+static void marker_line(void *user, int xa, int ya, int xb, int yb)
+{
+ SDL_Surface *s = user;
+ Sint16 ax = 0, ay = 0, bx = 0, by = 0;
+
+ if (coord(xa, ya, &ax, &ay) && coord(xb, yb, &bx, &by) <= 0)
+ return;
+ aalineColor(s, ax, ay, bx, by, MARKER_LINE_RGBA);
+}
+
+
+static void marker_text(void *user, int x, int y, float nx, float ny,
+ const char *txt)
+{
+ SDL_Surface *s = user;
+ Sint16 xx = 0, yy = 0;
+ SDL_Surface *t;
+ SDL_Rect r;
+
+ if (coord(x, y, &xx, &yy) <= 0)
+ return;
+
+ t = text(txt);
+ r.x = xx + TEXT_OFFSET_X + TEXT_DIST * nx;
+ r.y = yy + TEXT_OFFSET_Y + TEXT_DIST * ny;
+
+ r.w = t->w;
+ r.h = t->h;
+ if (SDL_BlitSurface(t, NULL, s, &r)) {
+ fprintf(stderr, "SDL_BlitSurface: %s \n", SDL_GetError());
+ exit(1);
+ }
+ SDL_FreeSurface(t);
+}
+
+
+static void draw_marker(SDL_Surface *s)
+{
+ marker_draw(&marker, marker_line, marker_text, s);
+}
+
+
/* ----- Last mouse position ---------------------------------------------- */
@@ -1269,6 +1322,7 @@ static bool event_loop(SDL_Surface **surf, const char *logfile,
case SDLK_r:
for (i = 0; i != n_overlays; i++)
overlay_reload(overlays + i);
+ marker_reload(&marker);
return 0;
case SDLK_1:
if (n_overlays)
@@ -1359,6 +1413,7 @@ fprintf(stderr, "%.3f s @ zoom %d\n", time_ms(&t)/1000.0, zoom);
if (show_overlay)
draw_overlay(surf, overlay);
SDL_UnlockSurface(surf);
+ draw_marker(surf);
SDL_UpdateRect(surf, 0, 0, 0, 0);
show_markers(surf);
diff --git a/meme/gui.h b/meme/gui.h
index 05f1226..80e72cd 100644
--- a/meme/gui.h
+++ b/meme/gui.h
@@ -1,8 +1,8 @@
/*
* gui.c - User interface
*
- * Written 2014-2015 by Werner Almesberger
- * Copyright 2014-2015 by Werner Almesberger
+ * Written 2014-2016 by Werner Almesberger
+ * Copyright 2014-2016 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
@@ -14,6 +14,10 @@
#define GUI_H
#include "overlay.h"
+#include "marker.h"
+
+
+extern struct marker marker;
void gui(const char *logfile, struct overlay overlays[], unsigned n_overlays);
diff --git a/meme/marker.c b/meme/marker.c
new file mode 100644
index 0000000..bedb638
--- /dev/null
+++ b/meme/marker.c
@@ -0,0 +1,158 @@
+/*
+ * marker.c - Markers
+ *
+ * Written 2016 by Werner Almesberger
+ * Copyright 2016 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "util.h"
+#include "marker.h"
+
+
+struct mark {
+ float xa, ya, xb, yb;
+ const char *s;
+ struct mark *next;
+};
+
+
+void marker_draw(const struct marker *marker,
+ void (*line)(void *user, int xa, int ya, int xb, int yb),
+ void (*text)(void *user, int x, int y, float nx, float ny, const char *txt),
+ void *user)
+{
+ const struct mark *mark;
+ float dx, dy, x, y;
+ float d;
+
+ for (mark = marker->markers; mark; mark = mark->next) {
+ if (mark->xa == mark->xb && mark->ya == mark->yb) {
+ text(user, mark->xa, mark->ya, 0, 0, mark->s);
+ continue;
+ }
+ dx = mark->xb - mark->xa;
+ dy = mark->yb - mark->ya;
+ d = hypotf(dx, dy);
+ x = (mark->xa + mark->xb) / 2.0;
+ y = (mark->ya + mark->yb) / 2.0;
+ line(user, mark->xa, mark->ya, mark->xb, mark->yb);
+ text(user, x, y, dy / d, -dx / d, mark->s);
+ }
+}
+
+
+static void marker_load_file(struct marker *marker, FILE *file,
+ void (*xform)(float x, float y, float *res_x, float *res_y))
+{
+ int lineno = 0;
+ char buf[1024];
+ int n;
+ double xa, ya, xb, yb;
+ char *s;
+ struct mark *mark;
+
+ marker->markers = NULL;
+ while (fgets(buf, sizeof(buf), file)) {
+ lineno++;
+ if (*buf == '#')
+ continue;
+ n = sscanf(buf, "%lf %lf %lf %lf %ms\n",
+ &xa, &ya, &xb, &yb, &s);
+ if (n != 5)
+ n = sscanf(buf, "%lf %lf %ms\n", &xa, &ya, &s);
+ switch (n) {
+ case -1:
+ continue;
+ case 3:
+ case 5:
+ break;
+ default:
+ fprintf(stderr, "invalid data at line %d\n", lineno);
+ exit(1);
+ }
+
+ mark = alloc_type(struct mark);
+ mark->next = marker->markers;
+ if (xform) {
+ xform(xa, ya, &mark->xa, &mark->ya);
+ } else {
+ mark->xa = xa;
+ mark->ya = ya;
+ }
+ mark->s = s;
+
+ if (n == 3) {
+ mark->xb = mark->xa;
+ mark->yb = mark->ya;
+ } else {
+ if (xform) {
+ xform(xb, yb, &mark->xb, &mark->yb);
+ } else {
+ mark->xb = xb;
+ mark->yb = yb;
+ }
+ }
+ marker->markers = mark;
+ }
+}
+
+
+static void marker_do_load(struct marker *marker)
+{
+ FILE *file;
+
+ file = fopen(marker->name, "r");
+ if (!file) {
+ perror(marker->name);
+ exit(1);
+ }
+ marker_load_file(marker, file, marker->xform);
+ fclose(file);
+}
+
+
+static void free_marker(struct marker *marker)
+{
+ struct mark *mark, *next;
+
+ while (marker->markers) {
+ mark = marker->markers;
+ next = mark->next;
+ free((void *) mark->s);
+ free(mark);
+ marker->markers = next;
+ }
+}
+
+
+void marker_reload(struct marker *marker)
+{
+ if (!marker->name)
+ return;
+ free_marker(marker);
+ marker_do_load(marker);
+}
+
+
+void marker_load(struct marker *marker, const char *name,
+ void (*xform)(float x, float y, float *res_x, float *res_y))
+{
+ marker->name = strdup(name);
+ if (!marker->name) {
+ perror("strdup");
+ exit(1);
+ }
+ marker->xform = xform;
+ marker_do_load(marker);
+}
diff --git a/meme/marker.h b/meme/marker.h
new file mode 100644
index 0000000..4992779
--- /dev/null
+++ b/meme/marker.h
@@ -0,0 +1,36 @@
+/*
+ * marker.h - Markers
+ *
+ * Written 2016 by Werner Almesberger
+ * Copyright 2016 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 MARKER_H
+#define MARKER_H
+
+struct mark;
+
+struct marker {
+ const char *name;
+ void (*xform)(float x, float y, float *res_x, float *res_y);
+ struct mark *markers;
+};
+
+
+void marker_draw(const struct marker *marker,
+ void (*line)(void *user, int xa, int ya, int xb, int yb),
+ void (*text)(void *user, int x, int y, float nx, float ny, const char *txt),
+ void *user);
+
+void marker_reload(struct marker *marker);
+
+void marker_load(struct marker *marker, const char *name,
+ void (*xform)(float x, float y, float *res_x, float *res_y));
+
+#endif /* !MARKER_H */
diff --git a/meme/meme.c b/meme/meme.c
index 3bb7b80..f759cc7 100644
--- a/meme/meme.c
+++ b/meme/meme.c
@@ -22,6 +22,7 @@
#include "stl.h"
#include "screen.h"
#include "overlay.h"
+#include "marker.h"
#include "slice.h"
#include "gui.h"
@@ -64,7 +65,8 @@ static void overlay_xform(float x, float y, float *res_x, float *res_y)
static void usage(const char *name)
{
fprintf(stderr,
-"usage: %s [-d dump.bmp] [-l logfile] [-o overlay.gp ...] [file.stl]\n"
+"usage: %s [-d dump.bmp] [-l logfile] [-m marker.gp] [-o overlay.gp ...]\n"
+" [file.stl]\n"
" %s -s plane.gp [-n] [file.stl]\n",
name, name);
exit(1);
@@ -81,7 +83,7 @@ int main(int argc, char **argv)
unsigned n_overlays = 0;
struct time t_load;
- while ((c = getopt(argc, argv, "d:l:no:s:")) != EOF)
+ while ((c = getopt(argc, argv, "d:l:m:no:s:")) != EOF)
switch (c) {
case 'd':
screen_dump_name = optarg;
@@ -89,6 +91,9 @@ int main(int argc, char **argv)
case 'l':
logfile = optarg;
break;
+ case 'm':
+ marker_load(&marker, optarg, overlay_xform);
+ break;
case 'n':
needle = 1;
break;