BRL-CAD
rect.c
Go to the documentation of this file.
1 /* R E C T . 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/rect.c
21  *
22  * Rubber band rectangle.
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <string.h>
29 #include <math.h>
30 
31 
32 #include "vmath.h"
33 #include "fb.h"
34 
35 #include "./ged_private.h"
36 
37 
38 static void
39 usage(struct ged *gedp, const char *argv0)
40 {
41  bu_vls_printf(gedp->ged_result_str, "Usage: %s\n", argv0);
42  bu_vls_printf(gedp->ged_result_str, " rect vname bg [r g b] set or get the background color\n");
43  bu_vls_printf(gedp->ged_result_str, " rect vname color [r g b] set or get the color\n");
44  bu_vls_printf(gedp->ged_result_str, " rect vname cdim w h set or get the canvas dimension\n");
45  bu_vls_printf(gedp->ged_result_str, " rect vname dim w h set or get the rectangle dimension\n");
46  bu_vls_printf(gedp->ged_result_str, " rect vname draw [0|1] set or get the draw parameter\n");
47  bu_vls_printf(gedp->ged_result_str, " rect vname help prints this help message\n");
48  bu_vls_printf(gedp->ged_result_str, " rect vname lstyle [0|1] set or get the line style, 0 - solid, 1 - dashed\n");
49  bu_vls_printf(gedp->ged_result_str, " rect vname lwidth w set or get the line width\n");
50  bu_vls_printf(gedp->ged_result_str, " rect vname pos x y set or get the rectangle position\n");
51  bu_vls_printf(gedp->ged_result_str, " rect vname rt port render the geometry within the rectangular area\n");
52  bu_vls_printf(gedp->ged_result_str, " rect vname vars print a list of all variables (i.e. var = val)\n");
53  bu_vls_printf(gedp->ged_result_str, " rect vname zoom zoom view to tangle position\n");
54 }
55 
56 
57 static void
58 rect_vls_print(struct ged *gedp)
59 {
60  bu_vls_printf(gedp->ged_result_str, "bg = %d %d %d\n",
61  gedp->ged_gvp->gv_rect.bg[0],
62  gedp->ged_gvp->gv_rect.bg[1],
63  gedp->ged_gvp->gv_rect.bg[2]);
64  bu_vls_printf(gedp->ged_result_str, "cdim = %d %d\n",
65  gedp->ged_gvp->gv_rect.cdim[X],
66  gedp->ged_gvp->gv_rect.cdim[Y]);
67  bu_vls_printf(gedp->ged_result_str, "color = %d %d %d\n",
68  gedp->ged_gvp->gv_rect.color[0],
69  gedp->ged_gvp->gv_rect.color[1],
70  gedp->ged_gvp->gv_rect.color[2]);
71  bu_vls_printf(gedp->ged_result_str, "dim = %d %d\n",
72  gedp->ged_gvp->gv_rect.dim[X],
73  gedp->ged_gvp->gv_rect.dim[Y]);
74  bu_vls_printf(gedp->ged_result_str, "draw = %d\n", gedp->ged_gvp->gv_rect.draw);
75  bu_vls_printf(gedp->ged_result_str, "lstyle = %d\n", gedp->ged_gvp->gv_rect.line_style);
76  bu_vls_printf(gedp->ged_result_str, "lwidth = %d\n", gedp->ged_gvp->gv_rect.line_width);
77  bu_vls_printf(gedp->ged_result_str, "pos = %d %d\n",
78  gedp->ged_gvp->gv_rect.pos[X],
79  gedp->ged_gvp->gv_rect.pos[Y]);
80 }
81 
82 
83 /*
84  * Given position and dimensions in image coordinates, calculate
85  * position and dimensions in normalized view coordinates.
86  */
87 static void
88 rect_image2view(struct bview_interactive_rect_state *grsp)
89 {
90  grsp->x = (grsp->pos[X] / (fastf_t)grsp->cdim[X] - 0.5) * 2.0;
91  grsp->y = ((0.5 - (grsp->cdim[Y] - grsp->pos[Y]) / (fastf_t)grsp->cdim[Y]) / grsp->aspect * 2.0);
92  grsp->width = grsp->dim[X] * 2.0 / (fastf_t)grsp->cdim[X];
93  grsp->height = grsp->dim[Y] * 2.0 / (fastf_t)grsp->cdim[X];
94 }
95 
96 
97 /*
98  * Adjust the rubber band rectangle to have the same aspect ratio as the window.
99  */
100 static void
101 rect_adjust_for_zoom(struct bview_interactive_rect_state *grsp)
102 {
103  fastf_t width, height;
104 
105  if (grsp->width >= 0.0)
106  width = grsp->width;
107  else
108  width = -grsp->width;
109 
110  if (grsp->height >= 0.0)
111  height = grsp->height;
112  else
113  height = -grsp->height;
114 
115  if (width >= height) {
116  if (grsp->height >= 0.0)
117  grsp->height = width / grsp->aspect;
118  else
119  grsp->height = -width / grsp->aspect;
120  } else {
121  if (grsp->width >= 0.0)
122  grsp->width = height * grsp->aspect;
123  else
124  grsp->width = -height * grsp->aspect;
125  }
126 }
127 
128 
129 static int
130 rect_rt(struct ged *gedp, int port)
131 {
132  int xmin, xmax;
133  int ymin, ymax;
134 
136 
137  /* initialize result in case we need to report something here */
138  bu_vls_trunc(gedp->ged_result_str, 0);
139 
140  if (ZERO(gedp->ged_gvp->gv_rect.width) &&
141  ZERO(gedp->ged_gvp->gv_rect.height))
142  return GED_OK;
143 
144  if (port < 0) {
145  bu_vls_printf(gedp->ged_result_str, "rect_rt: invalid port number - %d\n", port);
146  return GED_ERROR;
147  }
148 
149  xmin = gedp->ged_gvp->gv_rect.pos[X];
150  ymin = gedp->ged_gvp->gv_rect.pos[Y];
151 
152  if (gedp->ged_gvp->gv_rect.dim[X] >= 0) {
153  xmax = xmin + gedp->ged_gvp->gv_rect.dim[X];
154  } else {
155  xmax = xmin;
156  xmin += gedp->ged_gvp->gv_rect.dim[X];
157  }
158 
159  if (gedp->ged_gvp->gv_rect.dim[Y] >= 0) {
160  ymax = ymin + gedp->ged_gvp->gv_rect.dim[Y];
161  } else {
162  ymax = ymin;
163  ymin += gedp->ged_gvp->gv_rect.dim[Y];
164  }
165 
166  {
167  int ret;
168  struct bu_vls wvls = BU_VLS_INIT_ZERO;
169  struct bu_vls nvls = BU_VLS_INIT_ZERO;
170  struct bu_vls vvls = BU_VLS_INIT_ZERO;
171  struct bu_vls fvls = BU_VLS_INIT_ZERO;
172  struct bu_vls jvls = BU_VLS_INIT_ZERO;
173  struct bu_vls cvls = BU_VLS_INIT_ZERO;
174  char *av[14];
175 
176  bu_vls_printf(&wvls, "%d", gedp->ged_gvp->gv_rect.cdim[X]);
177  bu_vls_printf(&nvls, "%d", gedp->ged_gvp->gv_rect.cdim[Y]);
178  bu_vls_printf(&vvls, "%lf", gedp->ged_gvp->gv_rect.aspect);
179  bu_vls_printf(&fvls, "%d", port);
180  bu_vls_printf(&jvls, "%d, %d, %d, %d", xmin, ymin, xmax, ymax);
181  bu_vls_printf(&cvls, "%d/%d/%d",
182  gedp->ged_gvp->gv_rect.bg[0],
183  gedp->ged_gvp->gv_rect.bg[1],
184  gedp->ged_gvp->gv_rect.bg[2]);
185 
186  av[0] = "rt";
187  av[1] = "-w";
188  av[2] = bu_vls_addr(&wvls);
189  av[3] = "-n";
190  av[4] = bu_vls_addr(&nvls);
191  av[5] = "-V";
192  av[6] = bu_vls_addr(&vvls);
193  av[7] = "-F";
194  av[8] = bu_vls_addr(&fvls);
195  av[9] = "-j";
196  av[10] = bu_vls_addr(&jvls);
197  av[11] = "-C";
198  av[12] = bu_vls_addr(&cvls);
199  av[13] = (char *)0;
200 
201  ret = ged_rt(gedp, 13, (const char **)av);
202 
203  bu_vls_free(&wvls);
204  bu_vls_free(&nvls);
205  bu_vls_free(&vvls);
206  bu_vls_free(&fvls);
207  bu_vls_free(&jvls);
208  bu_vls_free(&cvls);
209 
210  return ret;
211  }
212 }
213 
214 
215 static int
216 rect_zoom(struct ged *gedp)
217 {
218  fastf_t width, height;
219  fastf_t sf;
220  point_t old_model_center;
221  point_t new_model_center;
222  point_t old_view_center;
223  point_t new_view_center;
224 
226  GED_CHECK_VIEW(gedp, GED_ERROR);
227 
228  /* initialize result */
229  bu_vls_trunc(gedp->ged_result_str, 0);
230 
231  if (ZERO(gedp->ged_gvp->gv_rect.width) &&
232  ZERO(gedp->ged_gvp->gv_rect.height))
233  return GED_OK;
234 
235  rect_adjust_for_zoom(&gedp->ged_gvp->gv_rect);
236 
237  /* find old view center */
238  MAT_DELTAS_GET_NEG(old_model_center, gedp->ged_gvp->gv_center);
239  MAT4X3PNT(old_view_center, gedp->ged_gvp->gv_model2view, old_model_center);
240 
241  /* calculate new view center */
242  VSET(new_view_center,
243  gedp->ged_gvp->gv_rect.x + gedp->ged_gvp->gv_rect.width / 2.0,
244  gedp->ged_gvp->gv_rect.y + gedp->ged_gvp->gv_rect.height / 2.0,
245  old_view_center[Z]);
246 
247  /* find new model center */
248  MAT4X3PNT(new_model_center, gedp->ged_gvp->gv_view2model, new_view_center);
249 
250  /* zoom in to fill rectangle */
251  if (gedp->ged_gvp->gv_rect.width >= 0.0)
252  width = gedp->ged_gvp->gv_rect.width;
253  else
254  width = -gedp->ged_gvp->gv_rect.width;
255 
256  if (gedp->ged_gvp->gv_rect.height >= 0.0)
257  height = gedp->ged_gvp->gv_rect.height;
258  else
259  height = -gedp->ged_gvp->gv_rect.height;
260 
261  if (width >= height)
262  sf = width / 2.0;
263  else
264  sf = height / 2.0 * gedp->ged_gvp->gv_rect.aspect;
265 
266  if (sf <= SMALL_FASTF || INFINITY < sf)
267  return GED_OK;
268 
269  /* set the new model center */
270  MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, new_model_center);
271  gedp->ged_gvp->gv_scale *= sf;
272  ged_view_update(gedp->ged_gvp);
273 
274  return GED_OK;
275 }
276 
277 
278 /*
279  * Note - this needs to be rewritten to accept keyword/value pairs so
280  * that multiple attributes can be set with a single command call.
281  */
282 int
283 ged_rect(struct ged *gedp,
284  int argc,
285  const char *argv[])
286 {
287  char *command;
288  char *parameter;
289  char **argp = (char **)argv;
290  point_t user_pt; /* Value(s) provided by user */
291  int i;
292 
294  GED_CHECK_VIEW(gedp, GED_ERROR);
295  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
296 
297  /* initialize result */
298  bu_vls_trunc(gedp->ged_result_str, 0);
299 
300  if (argc < 2 || 5 < argc) {
301  usage(gedp, argv[0]);
302  return GED_ERROR;
303  }
304 
305  command = (char *)argv[0];
306  parameter = (char *)argv[1];
307  argc -= 2;
308  argp += 2;
309 
310  for (i = 0; i < argc; ++i) {
311  double scan;
312 
313  if (sscanf(argp[i], "%lf", &scan) != 1) {
314  usage(gedp, argv[0]);
315  return GED_ERROR;
316  }
317 
318  user_pt[i] = scan;
319  }
320 
321  if (BU_STR_EQUAL(parameter, "draw")) {
322  if (argc == 0) {
323  bu_vls_printf(gedp->ged_result_str, "%d", gedp->ged_gvp->gv_rect.draw);
324  return GED_OK;
325  } else if (argc == 1) {
326  i = (int)user_pt[X];
327 
328  if (i)
329  gedp->ged_gvp->gv_rect.draw = 1;
330  else
331  gedp->ged_gvp->gv_rect.draw = 0;
332 
333  return GED_OK;
334  }
335 
336  bu_vls_printf(gedp->ged_result_str, "The '%s draw' command accepts 0 or 1 argument\n", command);
337  return GED_ERROR;
338  }
339 
340  if (BU_STR_EQUAL(parameter, "cdim")) {
341  if (argc == 0) {
342  bu_vls_printf(gedp->ged_result_str, "%d %d",
343  gedp->ged_gvp->gv_rect.cdim[X],
344  gedp->ged_gvp->gv_rect.cdim[Y]);
345  return GED_OK;
346  } else if (argc == 2) {
347  gedp->ged_gvp->gv_rect.cdim[X] = user_pt[X];
348  gedp->ged_gvp->gv_rect.cdim[Y] = user_pt[Y];
349  gedp->ged_gvp->gv_rect.aspect = (fastf_t)gedp->ged_gvp->gv_rect.cdim[X] / gedp->ged_gvp->gv_rect.cdim[Y];
350 
351  rect_image2view(&gedp->ged_gvp->gv_rect);
352 
353  return GED_OK;
354  }
355 
356  bu_vls_printf(gedp->ged_result_str, "The '%s cdim' command requires 0 or 2 arguments\n", command);
357  return GED_ERROR;
358  }
359 
360  if (BU_STR_EQUAL(parameter, "dim")) {
361  if (argc == 0) {
362  bu_vls_printf(gedp->ged_result_str, "%d %d",
363  gedp->ged_gvp->gv_rect.dim[X],
364  gedp->ged_gvp->gv_rect.dim[Y]);
365  return GED_OK;
366  } else if (argc == 2) {
367  gedp->ged_gvp->gv_rect.dim[X] = user_pt[X];
368  gedp->ged_gvp->gv_rect.dim[Y] = user_pt[Y];
369 
370  rect_image2view(&gedp->ged_gvp->gv_rect);
371 
372  return GED_OK;
373  }
374 
375  bu_vls_printf(gedp->ged_result_str, "The '%s dim' command requires 0 or 2 arguments\n", command);
376  return GED_ERROR;
377  }
378 
379  if (BU_STR_EQUAL(parameter, "pos")) {
380  if (argc == 0) {
381  bu_vls_printf(gedp->ged_result_str, "%d %d",
382  gedp->ged_gvp->gv_rect.pos[X],
383  gedp->ged_gvp->gv_rect.pos[Y]);
384  return GED_OK;
385  } else if (argc == 2) {
386  gedp->ged_gvp->gv_rect.pos[X] = user_pt[X];
387  gedp->ged_gvp->gv_rect.pos[Y] = user_pt[Y];
388 
389  rect_image2view(&gedp->ged_gvp->gv_rect);
390 
391  return GED_OK;
392  }
393 
394  bu_vls_printf(gedp->ged_result_str, "The '%s pos' command requires 0 or 2 arguments\n", command);
395  return GED_ERROR;
396  }
397 
398  if (BU_STR_EQUAL(parameter, "bg")) {
399  if (argc == 0) {
400  bu_vls_printf(gedp->ged_result_str, "%d %d %d",
401  gedp->ged_gvp->gv_rect.bg[X],
402  gedp->ged_gvp->gv_rect.bg[Y],
403  gedp->ged_gvp->gv_rect.bg[Z]);
404  return GED_OK;
405  } else if (argc == 3) {
406  gedp->ged_gvp->gv_rect.bg[0] = (int)user_pt[X];
407  gedp->ged_gvp->gv_rect.bg[1] = (int)user_pt[Y];
408  gedp->ged_gvp->gv_rect.bg[2] = (int)user_pt[Z];
409 
410  return GED_OK;
411  }
412 
413  bu_vls_printf(gedp->ged_result_str, "The '%s bg' command requires 0 or 3 arguments\n", command);
414  return GED_ERROR;
415  }
416 
417  if (BU_STR_EQUAL(parameter, "color")) {
418  if (argc == 0) {
419  bu_vls_printf(gedp->ged_result_str, "%d %d %d",
420  gedp->ged_gvp->gv_rect.color[X],
421  gedp->ged_gvp->gv_rect.color[Y],
422  gedp->ged_gvp->gv_rect.color[Z]);
423  return GED_OK;
424  } else if (argc == 3) {
425  gedp->ged_gvp->gv_rect.color[0] = (int)user_pt[X];
426  gedp->ged_gvp->gv_rect.color[1] = (int)user_pt[Y];
427  gedp->ged_gvp->gv_rect.color[2] = (int)user_pt[Z];
428 
429  return GED_OK;
430  }
431 
432  bu_vls_printf(gedp->ged_result_str, "The '%s color' command requires 0 or 3 arguments\n", command);
433  return GED_ERROR;
434  }
435 
436  if (BU_STR_EQUAL(parameter, "lstyle")) {
437  if (argc == 0) {
439  return GED_OK;
440  } else if (argc == 1) {
441  i = (int)user_pt[X];
442 
443  if (i <= 0)
444  gedp->ged_gvp->gv_rect.line_style = 0;
445  else
446  gedp->ged_gvp->gv_rect.line_style = 1;
447 
448  return GED_OK;
449  }
450 
451  bu_vls_printf(gedp->ged_result_str, "The '%s lstyle' command accepts 0 or 1 argument\n", command);
452  return GED_ERROR;
453  }
454 
455  if (BU_STR_EQUAL(parameter, "lwidth")) {
456  if (argc == 0) {
458  return GED_OK;
459  } else if (argc == 1) {
460  i = (int)user_pt[X];
461 
462  if (i <= 0)
463  gedp->ged_gvp->gv_rect.line_width = 0;
464  else
465  gedp->ged_gvp->gv_rect.line_width = i;
466 
467  return GED_OK;
468  }
469 
470  bu_vls_printf(gedp->ged_result_str, "The '%s lwidth' command accepts 0 or 1 argument\n", command);
471  return GED_ERROR;
472  }
473 
474  if (BU_STR_EQUAL(parameter, "rt")) {
475  if (argc == 1)
476  return rect_rt(gedp, (int)user_pt[X]);
477 
478  bu_vls_printf(gedp->ged_result_str, "The '%s rt' command accepts 1 argument\n", command);
479  return GED_ERROR;
480  }
481 
482  if (BU_STR_EQUAL(parameter, "zoom")) {
483  if (argc == 0)
484  return rect_zoom(gedp);
485 
486  bu_vls_printf(gedp->ged_result_str, "The '%s zoom' command accepts no arguments\n", command);
487  return GED_ERROR;
488  }
489 
490  if (BU_STR_EQUAL(parameter, "vars")) {
491  rect_vls_print(gedp);
492  return GED_OK;
493  }
494 
495  if (BU_STR_EQUAL(parameter, "help")) {
496  usage(gedp, command);
497  return GED_HELP;
498  }
499 
500  bu_vls_printf(gedp->ged_result_str, "%s: unrecognized command '%s'\n", command, parameter);
501  usage(gedp, command);
502 
503  return GED_ERROR;
504 }
505 
506 
507 /*
508  * Local Variables:
509  * mode: C
510  * tab-width: 8
511  * indent-tabs-mode: t
512  * c-file-style: "stroustrup"
513  * End:
514  * ex: shiftwidth=4 tabstop=8
515  */
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_OK
Definition: ged.h:55
mat_t gv_center
Definition: bview.h:221
Definition: ged.h:338
#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
#define SMALL_FASTF
Definition: defines.h:342
Header file for the BRL-CAD common definitions.
void ged_view_update(struct bview *gvp)
Definition: vutil.c:33
ustring width
#define GED_ERROR
Definition: ged.h:61
struct bview_interactive_rect_state gv_rect
Definition: bview.h:254
struct bview * ged_gvp
Definition: ged.h:361
mat_t gv_view2model
Definition: bview.h:224
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
Definition: color.c:49
#define GED_CHECK_VIEW(_gedp, _flags)
Definition: ged.h:140
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
int ged_rect(struct ged *gedp, int argc, const char *argv[])
Definition: rect.c:283
int ged_rt(struct ged *gedp, int argc, const char *argv[])
Definition: rt.c:450
fastf_t gv_scale
Definition: bview.h:211
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
struct bu_vls * ged_result_str
Definition: ged.h:357
#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
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
Definition: vls.h:56
double fastf_t
Definition: defines.h:300
Definition: color.c:50
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126