BRL-CAD
grid.c
Go to the documentation of this file.
1 /* G R I D . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1998-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @file libged/grid.c
21  *
22  * Routines that provide the basics for a snap to grid capability.
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <math.h>
29 #include <string.h>
30 
31 
32 #include "vmath.h"
33 
34 #include "./ged_private.h"
35 
36 
37 void
38 ged_snap_to_grid(struct ged *gedp, fastf_t *vx, fastf_t *vy)
39 {
40  int nh, nv; /* whole grid units */
41  point_t view_pt;
42  point_t view_grid_anchor;
43  fastf_t grid_units_h; /* eventually holds only fractional horizontal grid units */
44  fastf_t grid_units_v; /* eventually holds only fractional vertical grid units */
45  fastf_t sf;
46  fastf_t inv_sf;
47 
48  if (gedp->ged_gvp == GED_VIEW_NULL)
49  return;
50 
51  if (ZERO(gedp->ged_gvp->gv_grid.res_h) ||
52  ZERO(gedp->ged_gvp->gv_grid.res_v))
53  return;
54 
55  sf = gedp->ged_gvp->gv_scale*gedp->ged_wdbp->dbip->dbi_base2local;
56  inv_sf = 1 / sf;
57 
58  VSET(view_pt, *vx, *vy, 0.0);
59  VSCALE(view_pt, view_pt, sf); /* view_pt now in local units */
60 
61  MAT4X3PNT(view_grid_anchor, gedp->ged_gvp->gv_model2view, gedp->ged_gvp->gv_grid.anchor);
62  VSCALE(view_grid_anchor, view_grid_anchor, sf); /* view_grid_anchor now in local units */
63 
64  grid_units_h = (view_grid_anchor[X] - view_pt[X]) / (gedp->ged_gvp->gv_grid.res_h * gedp->ged_wdbp->dbip->dbi_base2local);
65  grid_units_v = (view_grid_anchor[Y] - view_pt[Y]) / (gedp->ged_gvp->gv_grid.res_v * gedp->ged_wdbp->dbip->dbi_base2local);
66  nh = grid_units_h;
67  nv = grid_units_v;
68 
69  grid_units_h -= nh; /* now contains only the fraction part */
70  grid_units_v -= nv; /* now contains only the fraction part */
71 
72  if (grid_units_h <= -0.5)
73  *vx = view_grid_anchor[X] - ((nh - 1) * gedp->ged_gvp->gv_grid.res_h * gedp->ged_wdbp->dbip->dbi_base2local);
74  else if (0.5 <= grid_units_h)
75  *vx = view_grid_anchor[X] - ((nh + 1) * gedp->ged_gvp->gv_grid.res_h * gedp->ged_wdbp->dbip->dbi_base2local);
76  else
77  *vx = view_grid_anchor[X] - (nh * gedp->ged_gvp->gv_grid.res_h * gedp->ged_wdbp->dbip->dbi_base2local);
78 
79  if (grid_units_v <= -0.5)
80  *vy = view_grid_anchor[Y] - ((nv - 1) * gedp->ged_gvp->gv_grid.res_v * gedp->ged_wdbp->dbip->dbi_base2local);
81  else if (0.5 <= grid_units_v)
82  *vy = view_grid_anchor[Y] - ((nv + 1) * gedp->ged_gvp->gv_grid.res_v * gedp->ged_wdbp->dbip->dbi_base2local);
83  else
84  *vy = view_grid_anchor[Y] - (nv * gedp->ged_gvp->gv_grid.res_v * gedp->ged_wdbp->dbip->dbi_base2local);
85 
86  *vx *= inv_sf;
87  *vy *= inv_sf;
88 }
89 
90 
91 HIDDEN void
92 grid_vsnap(struct ged *gedp)
93 {
94  point_t view_pt;
95  point_t model_pt;
96 
97  MAT_DELTAS_GET_NEG(model_pt, gedp->ged_gvp->gv_center);
98  MAT4X3PNT(view_pt, gedp->ged_gvp->gv_model2view, model_pt);
99  ged_snap_to_grid(gedp, &view_pt[X], &view_pt[Y]);
100  MAT4X3PNT(model_pt, gedp->ged_gvp->gv_view2model, view_pt);
101  MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, model_pt);
102  ged_view_update(gedp->ged_gvp);
103 }
104 
105 
106 HIDDEN void
107 grid_vls_print(struct ged *gedp)
108 {
109  bu_vls_printf(gedp->ged_result_str, "anchor = %g %g %g\n",
110  gedp->ged_gvp->gv_grid.anchor[0] * gedp->ged_wdbp->dbip->dbi_base2local,
111  gedp->ged_gvp->gv_grid.anchor[1] * gedp->ged_wdbp->dbip->dbi_base2local,
112  gedp->ged_gvp->gv_grid.anchor[2] * gedp->ged_wdbp->dbip->dbi_base2local);
113  bu_vls_printf(gedp->ged_result_str, "color = %d %d %d\n",
114  gedp->ged_gvp->gv_grid.color[0],
115  gedp->ged_gvp->gv_grid.color[1],
116  gedp->ged_gvp->gv_grid.color[2]);
117  bu_vls_printf(gedp->ged_result_str, "draw = %d\n", gedp->ged_gvp->gv_grid.draw);
118  bu_vls_printf(gedp->ged_result_str, "mrh = %d\n", gedp->ged_gvp->gv_grid.res_major_h);
119  bu_vls_printf(gedp->ged_result_str, "mrv = %d\n", gedp->ged_gvp->gv_grid.res_major_v);
120  bu_vls_printf(gedp->ged_result_str, "rh = %g\n", gedp->ged_gvp->gv_grid.res_h * gedp->ged_wdbp->dbip->dbi_base2local);
121  bu_vls_printf(gedp->ged_result_str, "rv = %g\n", gedp->ged_gvp->gv_grid.res_v * gedp->ged_wdbp->dbip->dbi_base2local);
122  bu_vls_printf(gedp->ged_result_str, "snap = %d\n", gedp->ged_gvp->gv_grid.snap);
123 }
124 
125 
126 HIDDEN void
127 grid_usage(struct ged *gedp, const char *argv0)
128 {
129  bu_vls_printf(gedp->ged_result_str, "Usage: %s\n", argv0);
130  bu_vls_printf(gedp->ged_result_str, "%s", " grid vname color [r g b] set or get the color\n");
131  bu_vls_printf(gedp->ged_result_str, "%s", " grid vname draw [0|1] set or get the draw parameter\n");
132  bu_vls_printf(gedp->ged_result_str, "%s", " grid vname help prints this help message\n");
133  bu_vls_printf(gedp->ged_result_str, "%s", " grid vname mrh [ival] set or get the major resolution (horizontal)\n");
134  bu_vls_printf(gedp->ged_result_str, "%s", " grid vname mrv [ival] set or get the major resolution (vertical)\n");
135  bu_vls_printf(gedp->ged_result_str, "%s", " grid vname rh [fval] set or get the resolution (horizontal)\n");
136  bu_vls_printf(gedp->ged_result_str, "%s", " grid vname rv [fval] set or get the resolution (vertical)\n");
137  bu_vls_printf(gedp->ged_result_str, "%s", " grid vname snap [0|1] set or get the snap parameter\n");
138  bu_vls_printf(gedp->ged_result_str, "%s", " grid vname vars print a list of all variables (i.e. var = val)\n");
139  bu_vls_printf(gedp->ged_result_str, "%s", " grid vname vsnap snaps the view center to the nearest grid point\n");
140 }
141 
142 
143 /*
144  * Note - this needs to be rewritten to accept keyword/value pairs so
145  * that multiple attributes can be set with a single command call.
146  */
147 int
148 ged_grid(struct ged *gedp, int argc, const char *argv[])
149 {
150  char *command;
151  char *parameter;
152  char **argp = (char **)argv;
153  double user_pt[3]; /* Value(s) provided by user */
154  int i;
155 
157  GED_CHECK_VIEW(gedp, GED_ERROR);
158  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
159 
160  /* initialize result */
161  bu_vls_trunc(gedp->ged_result_str, 0);
162 
163  if (argc == 1) {
164  grid_usage(gedp, argv[0]);
165  return GED_OK;
166  }
167 
168  if (argc < 2 || 5 < argc) {
169  grid_usage(gedp, argv[0]);
170  return GED_ERROR;
171  }
172 
173  command = (char *)argv[0];
174  parameter = (char *)argv[1];
175  argc -= 2;
176  argp += 2;
177 
178  for (i = 0; i < argc; ++i)
179  if (sscanf(argp[i], "%lf", &user_pt[i]) != 1) {
180  grid_usage(gedp, argv[0]);
181  return GED_ERROR;
182  }
183 
184  if (BU_STR_EQUAL(parameter, "draw")) {
185  if (argc == 0) {
186  bu_vls_printf(gedp->ged_result_str, "%d", gedp->ged_gvp->gv_grid.draw);
187  return GED_OK;
188  } else if (argc == 1) {
189  i = (int)user_pt[X];
190 
191  if (i)
192  gedp->ged_gvp->gv_grid.draw = 1;
193  else
194  gedp->ged_gvp->gv_grid.draw = 0;
195 
196  return GED_OK;
197  }
198 
199  bu_vls_printf(gedp->ged_result_str, "The '%s draw' command accepts 0 or 1 argument\n", command);
200  return GED_ERROR;
201  }
202 
203  if (BU_STR_EQUAL(parameter, "vsnap")) {
204  if (argc == 0) {
205  grid_vsnap(gedp);
206  return GED_OK;
207  }
208 
209  bu_vls_printf(gedp->ged_result_str, "The '%s vsnap' command accepts no arguments\n", command);
210  return GED_ERROR;
211  }
212 
213  if (BU_STR_EQUAL(parameter, "snap")) {
214  if (argc == 0) {
215  bu_vls_printf(gedp->ged_result_str, "%d", gedp->ged_gvp->gv_grid.snap);
216  return GED_OK;
217  } else if (argc == 1) {
218  i = (int)user_pt[X];
219 
220  if (i)
221  gedp->ged_gvp->gv_grid.snap = 1;
222  else
223  gedp->ged_gvp->gv_grid.snap = 0;
224 
225  return GED_OK;
226  }
227 
228  bu_vls_printf(gedp->ged_result_str, "The '%s snap' command accepts 0 or 1 argument\n", command);
229  return GED_ERROR;
230  }
231 
232  if (BU_STR_EQUAL(parameter, "rh")) {
233  if (argc == 0) {
234  bu_vls_printf(gedp->ged_result_str, "%g",
235  gedp->ged_gvp->gv_grid.res_h * gedp->ged_wdbp->dbip->dbi_base2local);
236  return GED_OK;
237  } else if (argc == 1) {
238  gedp->ged_gvp->gv_grid.res_h = user_pt[X] * gedp->ged_wdbp->dbip->dbi_local2base;
239 
240  return GED_OK;
241  }
242 
243  bu_vls_printf(gedp->ged_result_str, "The '%s rh' command accepts 0 or 1 argument\n", command);
244  return GED_ERROR;
245  }
246 
247  if (BU_STR_EQUAL(parameter, "rv")) {
248  if (argc == 0) {
249  bu_vls_printf(gedp->ged_result_str, "%g",
250  gedp->ged_gvp->gv_grid.res_v * gedp->ged_wdbp->dbip->dbi_base2local);
251  return GED_OK;
252  } else if (argc == 1) {
253  gedp->ged_gvp->gv_grid.res_v = user_pt[X] * gedp->ged_wdbp->dbip->dbi_local2base;
254 
255  return GED_OK;
256  }
257 
258  bu_vls_printf(gedp->ged_result_str, "The '%s rv' command accepts 0 or 1 argument\n", command);
259  return GED_ERROR;
260  }
261 
262  if (BU_STR_EQUAL(parameter, "mrh")) {
263  if (argc == 0) {
265  return GED_OK;
266  } else if (argc == 1) {
267  gedp->ged_gvp->gv_grid.res_major_h = (int)user_pt[X];
268 
269  return GED_OK;
270  }
271 
272  bu_vls_printf(gedp->ged_result_str, "The '%s mrh' command accepts 0 or 1 argument\n", command);
273  return GED_ERROR;
274  }
275 
276  if (BU_STR_EQUAL(parameter, "mrv")) {
277  if (argc == 0) {
279  return GED_OK;
280  } else if (argc == 1) {
281  gedp->ged_gvp->gv_grid.res_major_v = (int)user_pt[X];
282 
283  return GED_OK;
284  }
285 
286  bu_vls_printf(gedp->ged_result_str, "The '%s mrv' command accepts 0 or 1 argument\n", command);
287  return GED_ERROR;
288  }
289 
290  if (BU_STR_EQUAL(parameter, "anchor")) {
291  if (argc == 0) {
292  bu_vls_printf(gedp->ged_result_str, "%g %g %g",
293  gedp->ged_gvp->gv_grid.anchor[X] * gedp->ged_wdbp->dbip->dbi_base2local,
294  gedp->ged_gvp->gv_grid.anchor[Y] * gedp->ged_wdbp->dbip->dbi_base2local,
295  gedp->ged_gvp->gv_grid.anchor[Z] * gedp->ged_wdbp->dbip->dbi_base2local);
296  return GED_OK;
297  } else if (argc == 3) {
298  gedp->ged_gvp->gv_grid.anchor[0] = user_pt[X] * gedp->ged_wdbp->dbip->dbi_local2base;
299  gedp->ged_gvp->gv_grid.anchor[1] = user_pt[Y] * gedp->ged_wdbp->dbip->dbi_local2base;
300  gedp->ged_gvp->gv_grid.anchor[2] = user_pt[Z] * gedp->ged_wdbp->dbip->dbi_local2base;
301 
302  return GED_OK;
303  }
304 
305  bu_vls_printf(gedp->ged_result_str, "The '%s anchor' command requires 0 or 3 arguments\n", command);
306  return GED_ERROR;
307  }
308 
309  if (BU_STR_EQUAL(parameter, "color")) {
310  if (argc == 0) {
311  bu_vls_printf(gedp->ged_result_str, "%d %d %d",
312  gedp->ged_gvp->gv_grid.color[X],
313  gedp->ged_gvp->gv_grid.color[Y],
314  gedp->ged_gvp->gv_grid.color[Z]);
315  return GED_OK;
316  } else if (argc == 3) {
317  gedp->ged_gvp->gv_grid.color[0] = (int)user_pt[X];
318  gedp->ged_gvp->gv_grid.color[1] = (int)user_pt[Y];
319  gedp->ged_gvp->gv_grid.color[2] = (int)user_pt[Z];
320 
321  return GED_OK;
322  }
323 
324  bu_vls_printf(gedp->ged_result_str, "The '%s color' command requires 0 or 3 arguments\n", command);
325  return GED_ERROR;
326  }
327 
328  if (BU_STR_EQUAL(parameter, "vars")) {
329  grid_vls_print(gedp);
330  return GED_OK;
331  }
332 
333  if (BU_STR_EQUAL(parameter, "help")) {
334  grid_usage(gedp, argv[0]);
335  return GED_HELP;
336  }
337 
338  bu_vls_printf(gedp->ged_result_str, "%s: unrecognized command '%s'\n", argv[0], command);
339  grid_usage(gedp, argv[0]);
340 
341  return GED_ERROR;
342 }
343 
344 
345 /*
346  * Local Variables:
347  * mode: C
348  * tab-width: 8
349  * indent-tabs-mode: t
350  * c-file-style: "stroustrup"
351  * End:
352  * ex: shiftwidth=4 tabstop=8
353  */
#define GED_OK
Definition: ged.h:55
int color[3]
Definition: bview.h:114
mat_t gv_center
Definition: bview.h:221
int res_major_v
Definition: bview.h:113
Definition: ged.h:338
struct db_i * dbip
Definition: raytrace.h:1266
#define VSET(a, b, c, d)
Definition: color.c:53
void bu_vls_trunc(struct bu_vls *vp, int len)
Definition: vls.c:198
#define GED_CHECK_ARGC_GT_0(_gedp, _argc, _flags)
Definition: ged.h:202
HIDDEN void grid_vsnap(struct ged *gedp)
Definition: grid.c:92
fastf_t anchor[3]
Definition: bview.h:109
HIDDEN void grid_usage(struct ged *gedp, const char *argv0)
Definition: grid.c:127
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
void ged_view_update(struct bview *gvp)
Definition: vutil.c:33
#define GED_ERROR
Definition: ged.h:61
#define HIDDEN
Definition: common.h:86
struct bview * ged_gvp
Definition: ged.h:361
int res_major_h
Definition: bview.h:112
mat_t gv_view2model
Definition: bview.h:224
Definition: color.c:49
#define GED_CHECK_VIEW(_gedp, _flags)
Definition: ged.h:140
void ged_snap_to_grid(struct ged *gedp, fastf_t *vx, fastf_t *vy)
Definition: grid.c:38
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
fastf_t res_h
Definition: bview.h:110
struct bview_grid_state gv_grid
Definition: bview.h:249
fastf_t gv_scale
Definition: bview.h:211
int ged_grid(struct ged *gedp, int argc, const char *argv[])
Definition: grid.c:148
fastf_t res_v
Definition: bview.h:111
#define GED_VIEW_NULL
Definition: ged.h:75
struct bu_vls * ged_result_str
Definition: ged.h:357
double dbi_base2local
unit conversion factors
Definition: raytrace.h:808
HIDDEN void grid_vls_print(struct ged *gedp)
Definition: grid.c:107
#define ZERO(val)
Definition: units.c:38
mat_t gv_model2view
Definition: bview.h:222
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
#define GED_HELP
Definition: ged.h:62
Definition: color.c:51
double dbi_local2base
local2mm
Definition: raytrace.h:807
double fastf_t
Definition: defines.h:300
Definition: color.c:50
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126