From 4e4e9f6c4cc373cecd3d444b5f7787dd05944da7 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Sun, 16 Aug 2020 23:17:04 -1000 Subject: [PATCH 01/25] Enable painting the xz and yz back-walls in 3-D let +g set xy plan color, while +x and +y optionally set the other two side. --- src/gmt_init.c | 45 +++++++++++++++++++++++++++++++++++---------- src/gmt_plot.c | 38 +++++++++++++++++++++++++++----------- src/gmt_project.h | 4 ++-- src/grdimage.c | 6 +++--- src/psbasemap.c | 4 ++-- src/pscoast.c | 8 ++++---- src/psrose.c | 8 ++++---- src/psternary.c | 6 +++--- 8 files changed, 80 insertions(+), 39 deletions(-) diff --git a/src/gmt_init.c b/src/gmt_init.c index 07a4cce33d7..ab2e5b5df93 100644 --- a/src/gmt_init.c +++ b/src/gmt_init.c @@ -3749,7 +3749,7 @@ GMT_LOCAL int gmtinit_parse4_B_option (struct GMT_CTRL *GMT, char *in) { gmtinit_handle_dosfile (GMT, in, 0); /* Temporarily replace DOS files like X:/ with X;/ to avoid colon trouble */ #endif - for (i = (int)strlen(in) - 1, ignore = false; !GMT->current.map.frame.paint && !error && i >= 0; i--) { /** Look for +gcurrent.map.frame.paint[GMT_Z] && !error && i >= 0; i--) { /** Look for +g/ */ @@ -3775,9 +3775,9 @@ GMT_LOCAL int gmtinit_parse4_B_option (struct GMT_CTRL *GMT, char *in) { #ifdef _WIN32 gmtinit_handle_dosfile (GMT, out1, 1); /* Undo any DOS files like X;/ back to X:/ */ #endif - if (gmt_getfill (GMT, out1, &GMT->current.map.frame.fill)) error++; + if (gmt_getfill (GMT, out1, &GMT->current.map.frame.fill[GMT_Z])) error++; if (!error) { - GMT->current.map.frame.paint = true; + GMT->current.map.frame.paint[GMT_Z] = true; g = i; in[g] = '\0'; /* Chop off +g for now */ } @@ -4003,6 +4003,7 @@ bool gmtlib_B_is_frame (struct GMT_CTRL *GMT, char *in) { /*! . */ GMT_LOCAL int gmtinit_parse5_B_frame_setting (struct GMT_CTRL *GMT, char *in) { + bool blank[2] = {false, false}; unsigned int pos = 0, k, error = 0; char p[GMT_BUFSIZ] = {""}, text[GMT_BUFSIZ] = {""}, *mod = NULL; double pole[2]; @@ -4018,8 +4019,9 @@ GMT_LOCAL int gmtinit_parse5_B_frame_setting (struct GMT_CTRL *GMT, char *in) { /* OK, here we are pretty sure this is a frame -B statement */ strncpy (text, in, GMT_BUFSIZ-1); - gmt_handle5_plussign (GMT, text, "bginot", 0); /* Temporarily change double plus-signs to double ASCII 1 to avoid + angst */ + gmt_handle5_plussign (GMT, text, "bginotxy", 0); /* Temporarily change double plus-signs to double ASCII 1 to avoid + angst */ GMT->current.map.frame.header[0] = '\0'; + gmt_M_memset (GMT->current.map.frame.paint, 3U, bool); if ((mod = strchr (text, '+'))) { /* Find start of modifiers, if any */ while ((gmt_strtok (mod, "+", &pos, p))) { /* Parse any + statements */ @@ -4028,11 +4030,11 @@ GMT_LOCAL int gmtinit_parse5_B_frame_setting (struct GMT_CTRL *GMT, char *in) { GMT->current.map.frame.draw_box = true; break; case 'g': /* Paint the basemap interior */ - if (p[1] == 0 || gmt_getfill (GMT, &p[1], &GMT->current.map.frame.fill)) { + if (p[1] == 0 || gmt_getfill (GMT, &p[1], &GMT->current.map.frame.fill[GMT_Z])) { GMT_Report (GMT->parent, GMT_MSG_ERROR, "Bad +g argument %s\n", &p[1]); error++; } - GMT->current.map.frame.paint = true; + GMT->current.map.frame.paint[GMT_Z] = true; break; case 'i': /* Turn on internal annotation for radiual or longitudinal axes when there is no other place to annotate */ GMT->current.map.frame.internal_annot = 1; /* Longitude/angle */ @@ -4082,6 +4084,22 @@ GMT_LOCAL int gmtinit_parse5_B_frame_setting (struct GMT_CTRL *GMT, char *in) { gmtlib_enforce_rgb_triplets (GMT, GMT->current.map.frame.header, GMT_LEN256); /* If @; is used, make sure the color information passed on to ps_text is in r/b/g format */ } break; + case 'x': /* Paint the basemap xz-plane for 3-D plots */ + if (p[1] && gmt_getfill (GMT, &p[1], &GMT->current.map.frame.fill[GMT_X])) { + GMT_Report (GMT->parent, GMT_MSG_ERROR, "Bad +x argument %s\n", &p[1]); + error++; + } + blank[GMT_X] = !p[1]; + GMT->current.map.frame.paint[GMT_X] = true; + break; + case 'y': /* Paint the basemap yz-plane for 3-D plots */ + if (p[1] && gmt_getfill (GMT, &p[1], &GMT->current.map.frame.fill[GMT_Y])) { + GMT_Report (GMT->parent, GMT_MSG_ERROR, "Bad +y argument %s\n", &p[1]); + error++; + } + blank[GMT_X] = !p[1]; + GMT->current.map.frame.paint[GMT_Y] = true; + break; default: GMT_Report (GMT->parent, GMT_MSG_ERROR, "Option -B: Unrecognized frame modifier %s\n", p); error++; @@ -4091,6 +4109,12 @@ GMT_LOCAL int gmtinit_parse5_B_frame_setting (struct GMT_CTRL *GMT, char *in) { *mod = '\0'; /* Separate the modifiers from the frame selectors */ } + if (GMT->current.map.frame.paint[GMT_Z]) { + if (GMT->current.map.frame.paint[GMT_X] && blank[GMT_X]) /* Just +x means same as z-fill */ + gmt_M_memcpy (&GMT->current.map.frame.fill[GMT_X], &GMT->current.map.frame.fill[GMT_Z], 1U, struct GMT_FILL); + if (GMT->current.map.frame.paint[GMT_Y] && blank[GMT_Y]) /* Just +x means same as z-fill */ + gmt_M_memcpy (&GMT->current.map.frame.fill[GMT_Y], &GMT->current.map.frame.fill[GMT_Z], 1U, struct GMT_FILL); + } /* Now parse the frame choices, if any */ error += gmtinit_decode5_wesnz (GMT, text, true); @@ -4105,6 +4129,7 @@ void gmt_init_B (struct GMT_CTRL *GMT) { for (k = 0; k < 6; k++) GMT->current.map.frame.axis[no].item[k].parent = no; if (GMT->current.proj.xyz_projection[no] == GMT_TIME) GMT->current.map.frame.axis[no].type = GMT_TIME; } + gmt_M_memset (GMT->current.map.frame.paint, 3U, bool); GMT->common.B.string[0][0] = GMT->common.B.string[1][0] = '\0'; GMT->current.map.frame.init = true; GMT->current.map.frame.draw = false; @@ -12635,11 +12660,11 @@ GMT_LOCAL struct GMT_CTRL *gmtinit_begin_module_sub (struct GMTAPI_CTRL *API, co GMT->common.p.active = GMT->common.s.active = GMT->common.t.active = GMT->common.colon.active = false; gmt_M_memset (GMT->common.b.ncol, 2, int); - /* Initialize bg fill to white although we don't use it until GMT->current.map.frame.paint = true; + /* Initialize bg fill to white although we don't use it until GMT->current.map.frame.paint[GMT_Z] = true; But needed when using images with an transparency layer. */ - GMT->current.map.frame.fill.rgb[0] = GMT->current.map.frame.fill.rgb[1] = GMT->current.map.frame.fill.rgb[2] = 1.0; + GMT->current.map.frame.fill[GMT_Z].rgb[0] = GMT->current.map.frame.fill[GMT_Z].rgb[1] = GMT->current.map.frame.fill[GMT_Z].rgb[2] = 1.0; *Ccopy = Csave; /* Pass back out for safe-keeping by the module until gmt_end_module is called */ @@ -14303,8 +14328,8 @@ void gmt_end_module (struct GMT_CTRL *GMT, struct GMT_CTRL *Ccopy) { gmtinit_free_user_media (GMT); /* Free user-specified media formats */ /* Reset frame fill painting */ - Ccopy->current.map.frame.paint = GMT->current.map.frame.paint; - gmt_M_memcpy (Ccopy->current.map.frame.fill.rgb, GMT->current.map.frame.fill.rgb, 3, double); + Ccopy->current.map.frame.paint[GMT_Z] = GMT->current.map.frame.paint[GMT_Z]; + gmt_M_memcpy (Ccopy->current.map.frame.fill[GMT_Z].rgb, GMT->current.map.frame.fill[GMT_Z].rgb, 3, double); /* GMT_IO */ diff --git a/src/gmt_plot.c b/src/gmt_plot.c index 3045b99e86e..046ae29eaab 100644 --- a/src/gmt_plot.c +++ b/src/gmt_plot.c @@ -1556,6 +1556,21 @@ GMT_LOCAL void gmtplot_map_symbol_ns (struct GMT_CTRL *GMT, struct PSL_CTRL *PSL if (nc) gmt_M_free (GMT, xings); } +GMT_LOCAL void gmtplot_z_walls (struct GMT_CTRL *GMT, struct PSL_CTRL *PSL, double zmin, double zmax, int plane) { + double xx[4], yy[4]; + + if (!GMT->current.map.frame.paint[plane]) return; + fprintf (stderr, "Plot plane %d\n", plane); + xx[0] = xx[3] = (plane == GMT_Y) ? GMT->current.proj.rect[XLO] : GMT->current.proj.rect[YLO]; + xx[1] = xx[2] = (plane == GMT_Y) ? GMT->current.proj.rect[XHI] : GMT->current.proj.rect[YHI]; + PSL_command (GMT->PSL, "V\n"); + gmt_setfill (GMT, &GMT->current.map.frame.fill[plane], 1); + yy[0] = yy[1] = gmt_z_to_zz (GMT, zmin); + yy[2] = yy[3] = gmt_z_to_zz (GMT, zmax); + PSL_plotpolygon (PSL, xx, yy, 4); + PSL_command (GMT->PSL, "U\n"); +} + GMT_LOCAL void gmtplot_z_gridlines (struct GMT_CTRL *GMT, struct PSL_CTRL *PSL, double zmin, double zmax, int plane) { unsigned int k, i, nz, item[2] = {GMT_GRID_UPPER, GMT_GRID_LOWER}; double dz, zz, min, max, *z = NULL; @@ -1563,7 +1578,6 @@ GMT_LOCAL void gmtplot_z_gridlines (struct GMT_CTRL *GMT, struct PSL_CTRL *PSL, min = (plane == GMT_Y) ? GMT->current.proj.rect[XLO] : GMT->current.proj.rect[YLO]; max = (plane == GMT_Y) ? GMT->current.proj.rect[XHI] : GMT->current.proj.rect[YHI]; - for (k = 0; k < 2; k++) { if (fabs (GMT->current.setting.map_grid_cross_size[k]) > 0.0) continue; @@ -2628,9 +2642,11 @@ GMT_LOCAL bool gmtplot_is_fancy_boundary (struct GMT_CTRL *GMT) { GMT_LOCAL void gmtplot_vertical_wall (struct GMT_CTRL *GMT, struct PSL_CTRL *PSL, int quadrant, double *nesw, bool back) { int plane = (quadrant + 1) % 2; gmt_plane_perspective (GMT, plane, nesw[quadrant % 4]); - PSL_plotbox (PSL, nesw[(quadrant+1)%4], GMT->current.proj.zmin, nesw[(quadrant+3)%4], GMT->current.proj.zmax); - if (back) + if (back) { + gmtplot_z_walls (GMT, PSL, GMT->common.R.wesn[ZLO], GMT->common.R.wesn[ZHI], 1-plane); gmtplot_z_gridlines (GMT, PSL, GMT->common.R.wesn[ZLO], GMT->common.R.wesn[ZHI], plane); + } + PSL_plotbox (PSL, nesw[(quadrant+1)%4], GMT->current.proj.zmin, nesw[(quadrant+3)%4], GMT->current.proj.zmax); } GMT_LOCAL void gmtplot_timestamp (struct GMT_CTRL *GMT, struct PSL_CTRL *PSL, double x, double y, unsigned int justify, char *U_label) { @@ -7578,10 +7594,10 @@ struct PSL_CTRL *gmt_plotinit (struct GMT_CTRL *GMT, struct GMT_OPTION *options) PSL = GMT->PSL; /* Shorthand */ - if (GMT->current.map.frame.paint) { /* Must squirrel this away for now since we may call psbasemap during the movie-indicators below */ + if (GMT->current.map.frame.paint[GMT_Z]) { /* Must squirrel this away for now since we may call psbasemap during the movie-indicators below */ do_paint = true; - gmt_M_memcpy (&fill, &GMT->current.map.frame.fill, 1U, struct GMT_FILL); - GMT->current.map.frame.paint = false; /* Turn off for now */ + gmt_M_memcpy (&fill, &GMT->current.map.frame.fill[GMT_Z], 1U, struct GMT_FILL); + GMT->current.map.frame.paint[GMT_Z] = false; /* Turn off for now */ } PSL->internal.verbose = GMT->current.setting.verbose; /* Inherit verbosity level from GMT */ @@ -8024,21 +8040,21 @@ struct PSL_CTRL *gmt_plotinit (struct GMT_CTRL *GMT, struct GMT_OPTION *options) PSL_command (PSL, "}!\n"); } if (do_paint) { /* Reset any canvas coloring here */ - GMT->current.map.frame.paint = true; - gmt_M_memcpy (&GMT->current.map.frame.fill, &fill, 1U, struct GMT_FILL); + GMT->current.map.frame.paint[GMT_Z] = true; + gmt_M_memcpy (&GMT->current.map.frame.fill[GMT_Z], &fill, 1U, struct GMT_FILL); } return (PSL); } void gmt_plotcanvas (struct GMT_CTRL *GMT) { - if (GMT->current.map.frame.paint) { /* Paint the inside of the map with specified fill */ + if (GMT->current.map.frame.paint[GMT_Z]) { /* Paint the inside of the map (xy plane) with specified fill */ double *x = NULL, *y = NULL; uint64_t np; bool donut; - PSL_comment (GMT->PSL, "Fill the canvas %s\n", gmtlib_putfill (GMT, &GMT->current.map.frame.fill)); + PSL_comment (GMT->PSL, "Fill the canvas %s\n", gmtlib_putfill (GMT, &GMT->current.map.frame.fill[GMT_Z])); np = gmt_map_clip_path (GMT, &x, &y, &donut); - gmt_setfill (GMT, &GMT->current.map.frame.fill, 0); + gmt_setfill (GMT, &GMT->current.map.frame.fill[GMT_Z], 0); PSL_plotpolygon (GMT->PSL, x, y, (int)((1 + donut) * np)); gmt_M_free (GMT, x); gmt_M_free (GMT, y); diff --git a/src/gmt_project.h b/src/gmt_project.h index 0f09e0181c9..509e1771bd9 100644 --- a/src/gmt_project.h +++ b/src/gmt_project.h @@ -503,13 +503,13 @@ struct GMT_PLOT_AXIS { /* Information for one time axis */ struct GMT_PLOT_FRAME { /* Various parameters for plotting of time axis boundaries */ struct GMT_PLOT_AXIS axis[3]; /* One each for x, y, and z */ char header[GMT_LEN256]; /* Plot title */ - struct GMT_FILL fill; /* Fill for the basemap inside, if paint == true */ + struct GMT_FILL fill[3]; /* Fill for the basemap inside for planes x,y,z, if paint == true */ bool plotted_header; /* true if header has been plotted */ bool init; /* true if -B was used at all */ bool set; /* true if -B was used to set any increments */ bool draw; /* true if -B was used, even -B0, as sign to draw axes */ bool drawz; /* true if -B was used, even -Bz0, as sign to draw z axes */ - bool paint; /* true if -B +g was used */ + bool paint[3]; /* true if -B +x[], +y[], +g was used */ bool draw_box; /* true if a 3-D Z-box is desired */ bool no_frame; /* true if we just want gridlines but no frame, i.e +n was used */ bool check_side; /* true if lon and lat annotations should be on x and y axis only */ diff --git a/src/grdimage.c b/src/grdimage.c index 7bb1c7eb99f..2cc31908795 100644 --- a/src/grdimage.c +++ b/src/grdimage.c @@ -1260,9 +1260,9 @@ EXTERN_MSC int GMT_grdimage (void *V_API, int mode, void *args) { But what would it take to have a user selected bg color? */ double o, t; /* o - opacity, t = transparency */ o = Img_proj->data[node_RGBA] / 255.0; t = 1 - o; - rgb[0] = o * rgb[0] + t * GMT->current.map.frame.fill.rgb[0]; - rgb[1] = o * rgb[1] + t * GMT->current.map.frame.fill.rgb[1]; - rgb[2] = o * rgb[2] + t * GMT->current.map.frame.fill.rgb[2]; + rgb[0] = o * rgb[0] + t * GMT->current.map.frame.fill[GMT_Z].rgb[0]; + rgb[1] = o * rgb[1] + t * GMT->current.map.frame.fill[GMT_Z].rgb[1]; + rgb[2] = o * rgb[2] + t * GMT->current.map.frame.fill[GMT_Z].rgb[2]; node_RGBA++; } } diff --git a/src/psbasemap.c b/src/psbasemap.c index e0c7b670827..72335ffd077 100644 --- a/src/psbasemap.c +++ b/src/psbasemap.c @@ -192,8 +192,8 @@ static int parse (struct GMT_CTRL *GMT, struct PSBASEMAP_CTRL *Ctrl, struct GMT_ case 'G': /* Set canvas color */ if (gmt_M_compat_check (GMT, 4)) { GMT_Report (API, GMT_MSG_COMPAT, "Option -G is deprecated; -B...+g%s was set instead, use this in the future.\n", opt->arg); - GMT->current.map.frame.paint = true; - if (gmt_getfill (GMT, opt->arg, &GMT->current.map.frame.fill)) { + GMT->current.map.frame.paint[GMT_Z] = true; + if (gmt_getfill (GMT, opt->arg, &GMT->current.map.frame.fill[GMT_Z])) { gmt_fill_syntax (GMT, 'G', NULL, " "); n_errors++; } diff --git a/src/pscoast.c b/src/pscoast.c index 0557a777a0a..d99a50bedc1 100644 --- a/src/pscoast.c +++ b/src/pscoast.c @@ -149,8 +149,8 @@ static void *New_Ctrl (struct GMT_CTRL *GMT) { /* Allocate and initialize a new C->A.info.high = GSHHS_MAX_LEVEL; /* Include all GSHHS levels */ C->D.set = 'l'; /* Low-resolution coastline data */ - if (GMT->current.map.frame.paint) /* Default Ocean color = Frame background color */ - C->S.fill = GMT->current.map.frame.fill; + if (GMT->current.map.frame.paint[GMT_Z]) /* Default Ocean color = Frame background color */ + C->S.fill = GMT->current.map.frame.fill[GMT_Z]; else gmt_init_fill (GMT, &C->S.fill, 1.0, 1.0, 1.0); /* Default Ocean color = white */ C->C.fill[LAKE] = C->C.fill[RIVER] = C->S.fill; /* Default Lake/Riverlake color = Ocean color */ @@ -932,8 +932,8 @@ EXTERN_MSC int GMT_pscoast (void *V_API, int mode, void *args) { clobber_background = true; recursive = false; if (!Ctrl->S.active) { /* Since we are painting wet areas we must now reset them to white */ - if (GMT->current.map.frame.paint) /* Let ocean color match cancas fill color */ - fill[0] = GMT->current.map.frame.fill; + if (GMT->current.map.frame.paint[GMT_Z]) /* Let ocean color match cancas fill color */ + fill[0] = GMT->current.map.frame.fill[GMT_Z]; else gmt_init_fill (GMT, &fill[0], 1.0, 1.0, 1.0); /* Default Ocean color = white */ } diff --git a/src/psrose.c b/src/psrose.c index 56b1d305948..0b220dcb5bf 100644 --- a/src/psrose.c +++ b/src/psrose.c @@ -743,8 +743,8 @@ EXTERN_MSC int GMT_psrose (void *V_API, int mode, void *args) { Return (GMT_PROJECTION_ERROR); } - if (GMT->current.map.frame.paint) { /* Until psrose uses a polar projection we must bypass the basemap fill and do it ourself here */ - GMT->current.map.frame.paint = false; /* Turn off so gmt_plotinit won't fill */ + if (GMT->current.map.frame.paint[GMT_Z]) { /* Until psrose uses a polar projection we must bypass the basemap fill and do it ourself here */ + GMT->current.map.frame.paint[GMT_Z] = false; /* Turn off so gmt_plotinit won't fill */ do_fill = true; } if ((PSL = gmt_plotinit (GMT, options)) == NULL) Return (GMT_RUNTIME_ERROR); @@ -779,14 +779,14 @@ EXTERN_MSC int GMT_psrose (void *V_API, int mode, void *args) { if (do_fill) { /* Until psrose uses a polar projection we must bypass the basemap fill and do it ourself here */ double dim = 2.0 * Ctrl->S.scale; - GMT->current.map.frame.paint = true; /* Restore original setting */ + GMT->current.map.frame.paint[GMT_Z] = true; /* Restore original setting */ if (half_only) { /* Clip the bottom half of the circle */ double xc[4], yc[4]; xc[0] = xc[3] = -Ctrl->S.scale; xc[1] = xc[2] = Ctrl->S.scale; yc[0] = yc[1] = 0.0; yc[2] = yc[3] = Ctrl->S.scale; PSL_beginclipping (PSL, xc, yc, 4, GMT->session.no_rgb, 3); } - gmt_setfill (GMT, &GMT->current.map.frame.fill, 0); + gmt_setfill (GMT, &GMT->current.map.frame.fill[GMT_Z], 0); PSL_plotsymbol (PSL, 0.0, 0.0, &dim, PSL_CIRCLE); if (half_only) PSL_endclipping (PSL, 1); /* Reduce polygon clipping by one level */ } diff --git a/src/psternary.c b/src/psternary.c index 1201d7fbe92..635d56335b6 100644 --- a/src/psternary.c +++ b/src/psternary.c @@ -426,10 +426,10 @@ EXTERN_MSC int GMT_psternary (void *V_API, int mode, void *args) { * axis arguments. We also must handle the canvas filling separately. The three axis are 60 degrees * relative to each other and we do this directly with PSL calls. */ - if (GMT->current.map.frame.paint) { /* Paint the inside of the map with specified fill */ - gmt_setfill (GMT, &GMT->current.map.frame.fill, 0); + if (GMT->current.map.frame.paint[GMT_Z]) { /* Paint the inside of the map with specified fill */ + gmt_setfill (GMT, &GMT->current.map.frame.fill[GMT_Z], 0); PSL_plotpolygon (PSL, tri_x, tri_y, 4); - GMT->current.map.frame.paint = false; + GMT->current.map.frame.paint[GMT_Z] = false; } /* Count how many of the three sides will be drawn */ if (GMT->current.map.frame.side[S_SIDE]) n_sides++; /* The bottom (a) side */ From 360437f73dae8b1168988ff8c1e49a0c0630869e Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Mon, 17 Aug 2020 19:48:39 -1000 Subject: [PATCH 02/25] Allow the 3-D box not to be plotted on top of figure Until now, the +b did twh things: Turned on 3-D backwalls if gridlines were requested and draw the 3-D box, sometimes overprinting the main illustration. This PR adds +B as an alternative. Same as +b but does not draw the 3-D box outline. --- src/gmt_init.c | 30 +++++++++++++++++------------- src/gmt_plot.c | 24 +++++++++++++++--------- src/gmt_project.h | 8 +++++++- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/gmt_init.c b/src/gmt_init.c index cb882b35bc3..f0376afbe37 100644 --- a/src/gmt_init.c +++ b/src/gmt_init.c @@ -2473,14 +2473,14 @@ GMT_LOCAL bool gmtinit_true_false_or_error (char *value, bool *answer) { } /*! . */ -GMT_LOCAL int gmtinit_decode4_wesnz (struct GMT_CTRL *GMT, const char *in, unsigned int side[], bool *draw_box, int part) { +GMT_LOCAL int gmtinit_decode4_wesnz (struct GMT_CTRL *GMT, const char *in, unsigned int side[], unsigned int *draw_box, int part) { /* Scans the WESNZwesnz+ flags at the end of string "in" and sets the side/drawbox parameters * and returns the length of the remaining string. Assumes any +g has been removed from in. */ int i, k, orig_i; - unsigned int side_orig[5]; - bool go = true, orig_draw_box = *draw_box; + unsigned int side_orig[5], orig_draw_box = *draw_box; + bool go = true; GMT->current.map.frame.set_frame[part]++; if (GMT->current.map.frame.set_frame[GMT_PRIMARY] > 1 || GMT->current.map.frame.set_frame[GMT_SECONDARY] > 1) { @@ -2496,7 +2496,7 @@ GMT_LOCAL int gmtinit_decode4_wesnz (struct GMT_CTRL *GMT, const char *in, unsig for (k = 0; go && i >= 0 && strchr ("WESNZwesnz+", in[i]); i--) { if (k == 0 && part == 0) { /* Wipe out default values when the first flag is found */ for (k = 0; k < 5; k++) side[k] = 0; - *draw_box = false; + *draw_box = GMT_3D_NONE; } if (in[i] == 's') { /* Since s can mean both "draw south axis" and "seconds", check further */ if (side[S_SIDE]) go = false; /* If S was set already then s probably means seconds */ @@ -2518,7 +2518,7 @@ GMT_LOCAL int gmtinit_decode4_wesnz (struct GMT_CTRL *GMT, const char *in, unsig case 'n': side[N_SIDE] |= GMT_AXIS_BARB; break; case 'z': side[Z_SIDE] |= GMT_AXIS_BARB; break; /* Draw 3-D box */ - case '+': *draw_box = true; break; + case '+': *draw_box = GMT_3D_BOX; break; } } if (i >= 0 && in[i] == ',') i--; /* Special case for -BCcustomfile,WESNwesn to avoid the filename being parsed for WESN */ @@ -3948,12 +3948,14 @@ GMT_LOCAL int gmtinit_decode5_wesnz (struct GMT_CTRL *GMT, const char *in, bool /* Draw 3-D box */ case '+': if (in[k+1] == 'b') /* Got +b appended to MAP_FRAME_AXES, possibly */ - GMT->current.map.frame.draw_box = true; + GMT->current.map.frame.draw_box = GMT_3D_BOX; + else if (in[k+1] == 'B') /* Got +b appended to MAP_FRAME_AXES, possibly */ + GMT->current.map.frame.draw_box = GMT_3D_WALL; else if (in[k+1] == 'n') /* Got +n appended to MAP_FRAME_AXES, means no frame nor annotations desired */ GMT->current.map.frame.no_frame = true; else if (gmt_M_compat_check (GMT, 4)) { GMT_Report (GMT->parent, GMT_MSG_COMPAT, "Modifier + in MAP_FRAME_AXES is deprecated; use +b instead.\n"); - GMT->current.map.frame.draw_box = true; + GMT->current.map.frame.draw_box = GMT_3D_BOX; } else { GMT_Report (GMT->parent, GMT_MSG_ERROR, "Modifier + in MAP_FRAME_AXES not recognized.\n"); @@ -4018,14 +4020,17 @@ GMT_LOCAL int gmtinit_parse5_B_frame_setting (struct GMT_CTRL *GMT, char *in) { /* OK, here we are pretty sure this is a frame -B statement */ strncpy (text, in, GMT_BUFSIZ-1); - gmt_handle5_plussign (GMT, text, "bginot", 0); /* Temporarily change double plus-signs to double ASCII 1 to avoid + angst */ + gmt_handle5_plussign (GMT, text, "bBginot", 0); /* Temporarily change double plus-signs to double ASCII 1 to avoid + angst */ GMT->current.map.frame.header[0] = '\0'; if ((mod = strchr (text, '+'))) { /* Find start of modifiers, if any */ while ((gmt_strtok (mod, "+", &pos, p))) { /* Parse any + statements */ switch (p[0]) { case 'b': /* Activate 3-D box and x-z, y-z gridlines (if selected) */ - GMT->current.map.frame.draw_box = true; + GMT->current.map.frame.draw_box = GMT_3D_BOX; + break; + case 'B': /* Activate 3-D box and x-z, y-z gridlines (if selected) */ + GMT->current.map.frame.draw_box = GMT_3D_WALL; break; case 'g': /* Paint the basemap interior */ if (p[1] == 0 || gmt_getfill (GMT, &p[1], &GMT->current.map.frame.fill)) { @@ -5835,7 +5840,7 @@ void gmt_conf (struct GMT_CTRL *GMT) { /* MAP_FRAME_AXES */ strcpy (GMT->current.setting.map_frame_axes, "WESNZ"); for (i = 0; i < 5; i++) GMT->current.map.frame.side[i] = 0; /* Unset default settings */ - GMT->current.map.frame.draw_box = false; + GMT->current.map.frame.draw_box = GMT_3D_NONE; error += gmtinit_decode5_wesnz (GMT, "WESNZ", false); /* MAP_DEFAULT_PEN */ error += gmt_getpen (GMT, "default,black", &GMT->current.setting.map_default_pen); @@ -6545,8 +6550,7 @@ void gmtlib_explain_options (struct GMT_CTRL *GMT, char *options) { gmt_message (GMT, "\t To prepend a prefix to each annotation (e.g., $ 10, $ 20 ...), add +p.\n"); gmt_message (GMT, "\t To append a unit to each annotation (e.g., 5 km, 10 km ...), add +u.\n"); gmt_message (GMT, "\t Cartesian x-axis takes optional +a for slanted or +an for orthogonal annotations [+ap].\n"); - gmt_message (GMT, "\t Cartesian y-axis takes optional +ap for parallel annotations [+an].\n"); - gmt_message (GMT, "\t Cartesian z-axis takes optional +an for parallel annotations [+an].\n"); + gmt_message (GMT, "\t Cartesian y- and z-axes take optional +ap for parallel annotations [+an].\n"); gmt_message (GMT, "\t Geographic axes take optional +f for \"fancy\" annotations with W|E|S|N suffices.\n"); gmt_message (GMT, "\t To label an axis, add +l