summaryrefslogtreecommitdiff
path: root/meme
diff options
context:
space:
mode:
authorWerner Almesberger <werner@almesberger.net>2016-02-15 21:13:47 (GMT)
committerWerner Almesberger <werner@almesberger.net>2016-02-15 21:13:47 (GMT)
commit64bd53f6a5413810dd8e36237cf5aaf9feee0be4 (patch)
tree3ec42f6762e9680c57c432314ab1467d09f73659 /meme
parentff87a9e52408776b5f7fc32889b85d74e09857a7 (diff)
downloadmisc-64bd53f6a5413810dd8e36237cf5aaf9feee0be4.zip
misc-64bd53f6a5413810dd8e36237cf5aaf9feee0be4.tar.gz
misc-64bd53f6a5413810dd8e36237cf5aaf9feee0be4.tar.bz2
meme/: non-interactive screen dumps with -D ...
Diffstat (limited to 'meme')
-rw-r--r--meme/README46
-rw-r--r--meme/gui.c89
-rw-r--r--meme/gui.h25
-rw-r--r--meme/meme.c101
4 files changed, 248 insertions, 13 deletions
diff --git a/meme/README b/meme/README
index 20148e7..def617b 100644
--- a/meme/README
+++ b/meme/README
@@ -5,8 +5,8 @@ Mesh measurement utility
Usage:
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>
+ headless-dump-options path-to-STL-file
+meme -s slice.gp [-n] path-to-STL-file
Mouse
@@ -139,6 +139,48 @@ position of the edge is calculated considering the shape of the
scanning needle. This is illustrated in needle.fig
+Headless screen dumps
+---------------------
+
+Non-interactive screen dumps (e.g., to generate documentation) can be
+taken with the -D option and its many sub-options:
+
+ -D xres yres
+
+ Draws the mesh on a canvas of the specified size and then dumps it,
+ as if pressing "D". If markers or an overlay have been specified,
+ they are displayed. No other items (cursor, profiles, etc.) are
+ shown.
+
+ -C cx cy
+
+ Show the cursor at the specified position.
+
+ -E z zoom
+
+ Enhance contrast by "zoom" levels around the height "z". This is
+ similar to contrast enhancement by pressing "C".
+
+ -M mx my
+
+ Move the middle of the canvas to the specified position (in model
+ coordinates).
+
+ -P
+
+ Show profiles. This is like toggling them on with "P".
+
+ -Z zoom
+
+ Set the zoom level. If "zoom" begins with a plus or minus sign, the
+ default zoom level is changed accordingly. I.e., "+1" auto-zooms to
+ show the whole mesh, then zooms in by one step.
+
+ To prevent negative numbers on the command line from being
+ mis-interpreted as options, they can be prefixed with a space, e.g.,
+ " -10"
+
+
Workflow
--------
diff --git a/meme/gui.c b/meme/gui.c
index 915ed3b..6cda8ca 100644
--- a/meme/gui.c
+++ b/meme/gui.c
@@ -191,6 +191,7 @@ static void calc_z_grad(int center, unsigned c_zoom)
int col;
uint8_t mid = DEPTH_RANGE >> 1;
+fprintf(stderr, "center %d zoom %u\n", center, c_zoom);
if (!zoom_z_grad)
zoom_z_grad = calloc(3*(z_max-z_min)+1, sizeof(Uint32));
for (i = 0; i <= 3*(z_max-z_min); i++) {
@@ -1057,13 +1058,26 @@ static void init_mouse_pos(void)
/* ----- Scaling ----------------------------------------------------------- */
-static void auto_scale(void)
+static void auto_center(void)
{
- x_orig = (x_min+x_max) >> 1;
- y_orig = (y_min+y_max) >> 1;
+ x_orig = (x_min + x_max) >> 1;
+ y_orig = (y_min + y_max) >> 1;
+}
+
+
+static void auto_zoom(bool full)
+{
+ float f = full ? 1 : 0.9;
+
+ for (zoom = 0; (x_max - x_min) >> zoom > xres * f ||
+ (y_max - y_min) >> zoom > yres * f; zoom++);
+}
+
- for (zoom = 0; (x_max-x_min) >> zoom > xres*0.9 ||
- (y_max-y_min) >> zoom > yres*0.9; zoom++);
+static void auto_scale(bool full)
+{
+ auto_center();
+ auto_zoom(full);
}
@@ -1385,7 +1399,7 @@ static bool event_loop(SDL_Surface **surf, const char *logfile,
break;
switch (event.key.keysym.unicode) {
case '*':
- auto_scale();
+ auto_scale(false);
return 0;
case '+':
zoom_in(mouse_x, mouse_y);
@@ -1415,6 +1429,67 @@ static bool event_loop(SDL_Surface **surf, const char *logfile,
}
+void gui_dump(struct overlay overlays[], unsigned n_overlays,
+ const struct dump_params *prm)
+{
+ SDL_Surface *surf;
+
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+ fprintf(stderr, "SDL_init: %s\n", SDL_GetError());
+ exit(1);
+ }
+ atexit(SDL_Quit);
+
+ surf = sdl_surface(SDL_SWSURFACE, prm->xres, prm->yres);
+
+ xres = surf->w;
+ yres = surf->h;
+
+ extrema();
+// init_mouse_pos();
+ init_z_grad();
+
+ if (prm->enhance) {
+ begin_contrast();
+ calc_z_grad(prm->enh_z - z_min, contrast_zoom - prm->enh_scale);
+ }
+ if (prm->middle) {
+ x_orig = prm->mx;
+ y_orig = prm->my;
+ } else {
+ auto_center();
+ }
+
+ if (!prm->zoom_abs)
+ auto_zoom(true);
+ if (prm->zoom_abs)
+ zoom = prm->zoom;
+ if (prm->zoom_rel)
+ zoom -= prm->zoom;
+
+ SDL_LockSurface(surf);
+ draw(surf);
+ draw_overlay(surf, n_overlays ? overlays : NULL);
+ draw_marker(surf);
+ SDL_UnlockSurface(surf);
+ SDL_UpdateRect(surf, 0, 0, 0, 0);
+
+ if (prm->cursor) {
+ cursor = find_nearest(prm->cx, prm->cy);
+ if (cursor) {
+ if (prm->profile) {
+ show_xz_profile(surf);
+ show_yz_profile(surf);
+ }
+ show_cursor(surf, cursor);
+ apply_changes(surf);
+ }
+ }
+
+ dump_screen(surf);
+}
+
+
void gui(const char *logfile, struct overlay overlays[], unsigned n_overlays)
{
SDL_Surface *surf;
@@ -1439,7 +1514,7 @@ void gui(const char *logfile, struct overlay overlays[], unsigned n_overlays)
extrema();
init_mouse_pos();
init_z_grad();
- auto_scale();
+ auto_scale(false);
if (n_overlays)
overlay = overlays;
diff --git a/meme/gui.h b/meme/gui.h
index 80e72cd..2c06558 100644
--- a/meme/gui.h
+++ b/meme/gui.h
@@ -13,6 +13,8 @@
#ifndef GUI_H
#define GUI_H
+#include <stdbool.h>
+
#include "overlay.h"
#include "marker.h"
@@ -20,6 +22,29 @@
extern struct marker marker;
+struct dump_params {
+ int xres, yres;
+
+ bool middle;
+ float mx, my;
+
+ bool zoom_abs; /* "zoom" contains a zoom value */
+ bool zoom_rel; /* add "zoom" to auto-zoom result */
+ int zoom;
+
+ bool cursor;
+ float cx, cy;
+
+ bool enhance;
+ float enh_z;
+ int enh_scale;
+
+ bool profile;
+};
+
+
+void gui_dump(struct overlay overlays[], unsigned n_overlays,
+ const struct dump_params *prm);
void gui(const char *logfile, struct overlay overlays[], unsigned n_overlays);
#endif /* !GUI_H */
diff --git a/meme/meme.c b/meme/meme.c
index 2f0c976..85e6c2c 100644
--- a/meme/meme.c
+++ b/meme/meme.c
@@ -66,6 +66,7 @@ static void usage(const char *name)
{
fprintf(stderr,
"usage: %s [-d dump.bmp] [-l logfile] [-m marker.gp] [-o overlay.gp ...]\n"
+" [-D xres yres [-C cx cy] [-E z zoom] [-M mx my] [-P] [-Z zoom]]\n"
" [file.stl]\n"
" %s -s plane.gp [-n] [file.stl]\n\n"
" -d dump.bmp\n"
@@ -77,7 +78,19 @@ static void usage(const char *name)
" -n when slicing, try to compensate for the scanning needle geometry\n"
" -o overlay.gp\n"
" display the specified overlays. The option can be repeated.\n"
-" -s slice the mesh with a plane. This is non-interactive.\n"
+" -s slice the mesh with a plane. This is non-interactive.\n\n"
+" -D xres yres\n"
+" non-interactively dump a screenshot of mesh and adornments\n"
+" -C cx cy\n"
+" show the cursor at the specified position\n"
+" -E z zoom\n"
+" enhance contrast around Z by the specified zoom factor\n"
+" -M mx my\n"
+" set the middle of the screen to the specified position\n"
+" -P show profiles\n"
+" -Z zoom\n"
+" set the specified zoom level. If prefixed with - or +, zoom out or\n"
+" in from default zoom\n"
, name, name);
exit(1);
}
@@ -92,8 +105,20 @@ int main(int argc, char **argv)
struct overlay overlays[N_OVERLAYS];
unsigned n_overlays = 0;
struct time t_load;
-
- while ((c = getopt(argc, argv, "d:l:m:no:s:")) != EOF)
+ int args = 0;
+ bool headless_dump = 0;
+ int dump_cursor = 0, dump_middle = 0, dump_enhance = 0, dump_zoom = 0;
+
+ struct dump_params prm = {
+ .middle = 0,
+ .zoom_abs = 0,
+ .zoom_rel = 0,
+ .cursor = 0,
+ .enhance = 0,
+ .profile = 0,
+ };
+
+ while ((c = getopt(argc, argv, "d:l:m:no:s:DCEMPZ")) != EOF)
switch (c) {
case 'd':
screen_dump_name = optarg;
@@ -119,10 +144,73 @@ int main(int argc, char **argv)
case 's':
slice = optarg;
break;
+ case 'D':
+ headless_dump = 1;
+ args += 2;
+ break;
+ case 'C':
+ if (!headless_dump)
+ usage(*argv);
+ prm.cursor = 1;
+ dump_cursor = args;
+ args += 2;
+ break;
+ case 'E':
+ if (!headless_dump)
+ usage(*argv);
+ prm.enhance = 1;
+ dump_enhance = args;
+ args += 2;
+ break;
+ case 'M':
+ if (!headless_dump)
+ usage(*argv);
+ prm.middle = 1;
+ dump_middle = args;
+ args += 2;
+ break;
+ case 'P':
+ if (!headless_dump)
+ usage(*argv);
+ prm.profile = 1;
+ break;
+ case 'Z':
+ if (!headless_dump)
+ usage(*argv);
+ dump_zoom = args;
+ args++;
+ break;
default:
usage(*argv);
}
+ if (headless_dump) {
+ if (argc - optind < args)
+ usage(*argv);
+ prm.xres = atoi(argv[optind]);
+ prm.yres = atoi(argv[optind + 1]);
+ if (prm.cursor)
+ overlay_xform(atof(argv[optind + dump_cursor]),
+ atof(argv[optind + dump_cursor + 1]),
+ &prm.cx, &prm.cy);
+ if (prm.enhance) {
+ prm.enh_z = atof(argv[optind + dump_enhance]) * 1000;
+ prm.enh_scale = atoi(argv[optind + dump_enhance + 1]);
+ }
+ if (prm.middle)
+ overlay_xform(atof(argv[optind + dump_middle]),
+ atof(argv[optind + dump_middle + 1]),
+ &prm.mx, &prm.my);
+ if (dump_zoom) {
+ prm.zoom = atof(argv[optind + dump_zoom]);
+ if (strchr("+-", *argv[optind + dump_zoom]))
+ prm.zoom_rel = 1;
+ else
+ prm.zoom_abs = 1;
+ }
+ optind += args;
+ }
+
switch (argc - optind) {
case 0:
time_start(&t_load);
@@ -144,7 +232,12 @@ int main(int argc, char **argv)
if (slice) {
slice_load(slice);
slice_run(slice_out, needle);
- exit(1);
+ exit(0);
+ }
+
+ if (headless_dump) {
+ gui_dump(overlays, n_overlays, &prm);
+ exit(0);
}
gui(logfile, overlays, n_overlays);