BRL-CAD
edarb.c
Go to the documentation of this file.
1 /* E D A R B . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1985-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/edarb.c
21  *
22  */
23 
24 #include "common.h"
25 
26 #include <stdlib.h>
27 #include <ctype.h>
28 #include <string.h>
29 
30 #include "bu/cmd.h"
31 #include "rt/arb_edit.h"
32 #include "ged_private.h"
33 
34 /*
35  * An ARB edge is moved by finding the direction of the line
36  * containing the edge and the 2 "bounding" planes. The new edge is
37  * found by intersecting the new line location with the bounding
38  * planes. The two "new" planes thus defined are calculated and the
39  * affected points are calculated by intersecting planes. This keeps
40  * ALL faces planar.
41  *
42  */
43 static int
44 editarb(struct ged *gedp, struct rt_arb_internal *arb, int type, int edge, vect_t pos_model, int newedge)
45 {
46  int ret;
47  fastf_t peqn[7][4];
48  struct bu_vls error_msg = BU_VLS_INIT_ZERO;
49 
50  if (rt_arb_calc_planes(&error_msg, arb, type, peqn, &gedp->ged_wdbp->wdb_tol)) {
51  bu_vls_printf(gedp->ged_result_str, "%s. Cannot calculate plane equations for faces\n", bu_vls_addr(&error_msg));
52  bu_vls_free(&error_msg);
53  return GED_ERROR;
54  }
55  bu_vls_free(&error_msg);
56  ret = arb_edit(arb, peqn, edge, newedge, pos_model, &gedp->ged_wdbp->wdb_tol);
57  if (!ret) {
58  return GED_OK;
59  } else {
60  /* Error handling */
61  bu_vls_printf(gedp->ged_result_str, "Error editing arb\n");
62  return GED_ERROR;
63  }
64 }
65 
66 
67 /* Extrude command - project an arb face */
68 /* Format: extrude face distance */
69 static int
70 edarb_extrude(void *data, int argc, const char *argv[])
71 {
72  struct ged *gedp = (struct ged *)data;
73  int type;
74  struct directory *dp;
75  struct rt_db_internal intern;
76  struct rt_arb_internal *arb;
77  int face;
78  fastf_t dist;
79  fastf_t peqn[7][4];
80  static const char *usage = "arb face distance";
81 
82  /* must be wanting help */
83  if (argc == 2) {
84  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0], argv[1], usage);
85  return GED_HELP;
86  }
87 
88  if (argc != 5) {
89  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0], argv[1], usage);
90  return GED_ERROR;
91  }
92 
93  GED_DB_LOOKUP(gedp, dp, (char *)argv[2], LOOKUP_QUIET, GED_ERROR);
94  GED_DB_GET_INTERNAL(gedp, &intern, dp, (matp_t)NULL, &rt_uniresource, GED_ERROR);
95 
96  if (intern.idb_type != ID_ARB8) {
97  bu_vls_printf(gedp->ged_result_str, "%s %s: solid type must be ARB\n", argv[0], argv[1]);
98  rt_db_free_internal(&intern);
99  return GED_ERROR;
100  }
101 
102  type = rt_arb_std_type(&intern, &gedp->ged_wdbp->wdb_tol);
103  if (type != 8 && type != 6 && type != 4) {
104  bu_vls_printf(gedp->ged_result_str, "ARB%d: extrusion of faces not allowed\n", type);
105  rt_db_free_internal(&intern);
106  return GED_ERROR;
107  }
108 
109  arb = (struct rt_arb_internal *)intern.idb_ptr;
110  RT_ARB_CK_MAGIC(arb);
111 
112  face = atoi(argv[3]);
113 
114  /* get distance to project face */
115  dist = atof(argv[4]);
116 
117  /* convert from the local unit (as input) to the base unit */
118  dist = dist * gedp->ged_wdbp->dbip->dbi_local2base;
119 
120  if (arb_extrude(arb, face, dist, &gedp->ged_wdbp->wdb_tol, peqn)) {
121  bu_vls_printf(gedp->ged_result_str, "ARB%d: error extruding face\n", type);
122  rt_db_free_internal(&intern);
123  return GED_ERROR;
124  }
125 
126  GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
127  rt_db_free_internal(&intern);
128 
129  return GED_OK;
130 }
131 
132 
133 /* Mirface command - mirror an arb face */
134 /* Format: mirror face axis */
135 int
136 edarb_mirface(void *data, int argc, const char *argv[])
137 {
138  struct ged *gedp = (struct ged *)data;
139  struct directory *dp;
140  struct rt_db_internal intern;
141  struct rt_arb_internal *arb;
142  static int face;
143  fastf_t peqn[7][4];
144  static const char *usage = "arb face axis";
145 
146  /* must be wanting help */
147  if (argc == 2) {
148  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0], argv[1], usage);
149  return GED_HELP;
150  }
151 
152  if (argc != 5) {
153  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0], argv[1], usage);
154  return GED_ERROR;
155  }
156 
157  GED_DB_LOOKUP(gedp, dp, (char *)argv[2], LOOKUP_QUIET, GED_ERROR);
158  GED_DB_GET_INTERNAL(gedp, &intern, dp, (matp_t)NULL, &rt_uniresource, GED_ERROR);
159 
160  if (intern.idb_type != ID_ARB8) {
161  bu_vls_printf(gedp->ged_result_str, "%s %s: solid type must be ARB\n", argv[0], argv[1]);
162  rt_db_free_internal(&intern);
163  return GED_ERROR;
164  }
165 
166  arb = (struct rt_arb_internal *)intern.idb_ptr;
167  RT_ARB_CK_MAGIC(arb);
168 
169  face = atoi(argv[3]);
170 
171  if (arb_mirror_face_axis(arb, peqn, face, argv[4], &gedp->ged_wdbp->wdb_tol)) {
172  bu_vls_printf(gedp->ged_result_str, "ERROR: mirror operation failed\n");
173  rt_db_free_internal(&intern);
174  return GED_ERROR;
175  }
176 
177  GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
178  rt_db_free_internal(&intern);
179 
180  return GED_OK;
181 }
182 
183 
184 /* Edgedir command: define the direction of an arb edge being moved
185  * Format: edgedir deltax deltay deltaz OR edgedir rot fb
186 */
187 static int
188 edarb_edgedir(void *data, int argc, const char *argv[])
189 {
190  struct ged *gedp = (struct ged *)data;
191  int type;
192  struct directory *dp;
193  struct rt_db_internal intern;
194  struct rt_arb_internal *arb;
195  int ret;
196  int i;
197  int edge;
198  vect_t slope;
199  fastf_t rot, fb_a;
200  static const char *usage = "arb edge [delta_x delta_y delta_z] | [rot fb]";
201 
202  /* must be wanting help */
203  if (argc == 2) {
204  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0], argv[1], usage);
205  return GED_HELP;
206  }
207 
208  if (argc < 6 || 7 < argc) {
209  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0], argv[1], usage);
210  return GED_ERROR;
211  }
212 
213  if (sscanf(argv[3], "%d", &edge) != 1) {
214  bu_vls_printf(gedp->ged_result_str, "bad edge - %s", argv[3]);
215  return GED_ERROR;
216  }
217  edge -= 1;
218 
219  GED_DB_LOOKUP(gedp, dp, (char *)argv[2], LOOKUP_QUIET, GED_ERROR);
220  GED_DB_GET_INTERNAL(gedp, &intern, dp, (matp_t)NULL, &rt_uniresource, GED_ERROR);
221 
222  if (intern.idb_type != ID_ARB8) {
223  bu_vls_printf(gedp->ged_result_str, "%s %s: solid type must be ARB\n", argv[0], argv[1]);
224  rt_db_free_internal(&intern);
225  return GED_ERROR;
226  }
227 
228  type = rt_arb_std_type(&intern, &gedp->ged_wdbp->wdb_tol);
229  arb = (struct rt_arb_internal *)intern.idb_ptr;
230  RT_ARB_CK_MAGIC(arb);
231 
232  /* set up slope -
233  * if 2 values input assume rot, fb used
234  * else assume delta_x, delta_y, delta_z
235  */
236  if (argc == 6) {
237  rot = atof(argv[1]) * DEG2RAD;
238  fb_a = atof(argv[2]) * DEG2RAD;
239  slope[0] = cos(fb_a) * cos(rot);
240  slope[1] = cos(fb_a) * sin(rot);
241  slope[2] = sin(fb_a);
242  } else {
243  for (i=0; i<3; i++) {
244  /* put edge slope in slope[] array */
245  slope[i] = atof(argv[i+4]);
246  }
247  }
248 
249  if (ZERO(MAGNITUDE(slope))) {
250  bu_vls_printf(gedp->ged_result_str, "%s %s: BAD slope\n", argv[0], argv[1]);
251  rt_db_free_internal(&intern);
252  return GED_ERROR;
253  }
254 
255  ret = editarb(gedp, arb, type, edge, slope, 1);
256  if (ret == GED_OK) {
257  GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
258  }
259 
260  rt_db_free_internal(&intern);
261 
262  return ret;
263 }
264 
265 
266 /* Permute command - permute the vertex labels of an ARB
267  * Format: permute tuple */
268 
269 /*
270  * Minimum and maximum tuple lengths
271  * ------------------------------------------------
272  * Solid # vertices needed # vertices
273  * type to disambiguate in THE face
274  * ------------------------------------------------
275  * ARB4 3 3
276  * ARB5 2 4
277  * ARB6 2 4
278  * ARB7 1 4
279  * ARB8 3 4
280  * ------------------------------------------------
281  */
282 static int
283 edarb_permute(void *data, int argc, const char *argv[])
284 {
285  struct ged *gedp = (struct ged *)data;
286  struct directory *dp;
287  struct rt_db_internal intern;
288  struct rt_arb_internal *arb;
289  static const char *usage = "arb tuple";
290 
291  /* must be wanting help */
292  if (argc == 2) {
293  bu_vls_printf(gedp->ged_result_str, "Usage: edarb %s %s %s", argv[0], argv[1], usage);
294  return GED_HELP;
295  }
296 
297  if (argc != 4) {
298  bu_vls_printf(gedp->ged_result_str, "Usage: edarb %s %s %s", argv[0], argv[1], usage);
299  return GED_ERROR;
300  }
301 
302  GED_DB_LOOKUP(gedp, dp, (char *)argv[2], LOOKUP_QUIET, GED_ERROR);
303  GED_DB_GET_INTERNAL(gedp, &intern, dp, (matp_t)NULL, &rt_uniresource, GED_ERROR);
304 
305  if (intern.idb_type != ID_ARB8) {
306  bu_vls_printf(gedp->ged_result_str, "%s %s: solid type must be ARB\n", argv[0], argv[1]);
307  rt_db_free_internal(&intern);
308  return GED_ERROR;
309  }
310 
311  arb = (struct rt_arb_internal *)intern.idb_ptr;
312  RT_ARB_CK_MAGIC(arb);
313 
314  if (arb_permute(arb, argv[3], &gedp->ged_wdbp->wdb_tol)) {
315  bu_vls_printf(gedp->ged_result_str, "Permute failed\n");
316  rt_db_free_internal(&intern);
317  return GED_ERROR;
318  }
319 
320  GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
321  rt_db_free_internal(&intern);
322 
323  return GED_OK;
324 }
325 
326 
327 int
328 ged_edarb(struct ged *gedp, int argc, const char *argv[])
329 {
330  int ret;
331  static struct bu_cmdtab arb_cmds[] = {
332  {"edgedir", edarb_edgedir},
333  {"extrude", edarb_extrude},
334  {"facedef", edarb_facedef},
335  {"mirface", edarb_mirface},
336  {"permute", edarb_permute},
337  {(const char *)NULL, BU_CMD_NULL}
338  };
339  static const char *usage = "edgedir|extrude|mirror|permute arb [args]";
340 
343  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
344 
345  /* initialize result */
346  bu_vls_trunc(gedp->ged_result_str, 0);
347 
348  /* must be wanting help */
349  if (argc == 1) {
350  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
351  return GED_HELP;
352  }
353 
354 
355  if (bu_cmd(arb_cmds, argc, argv, 1, gedp, &ret) == BRLCAD_OK)
356  return ret;
357 
358  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
359 
360  return GED_ERROR;
361 }
362 
363 
364 /*
365  * Local Variables:
366  * mode: C
367  * tab-width: 8
368  * indent-tabs-mode: t
369  * c-file-style: "stroustrup"
370  * End:
371  * ex: shiftwidth=4 tabstop=8
372  */
Definition: cmd.h:48
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_OK
Definition: ged.h:55
int rt_arb_calc_planes(struct bu_vls *error_msg_ret, struct rt_arb_internal *arb, int type, plane_t planes[6], const struct bn_tol *tol)
Definition: arb8.c:1871
int edarb_mirface(void *data, int argc, const char *argv[])
Definition: edarb.c:136
Definition: ged.h:338
struct db_i * dbip
Definition: raytrace.h:1266
#define ID_ARB8
Generalized ARB. V + 7 vectors.
Definition: raytrace.h:462
#define GED_DB_LOOKUP(_gedp, _dp, _name, _noisy, _flags)
Definition: ged.h:223
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
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
#define BU_CMD_NULL
Definition: cmd.h:37
#define GED_ERROR
Definition: ged.h:61
#define GED_DB_PUT_INTERNAL(_gedp, _dp, _intern, _resource, _flags)
Definition: ged.h:243
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
int edarb_facedef(void *data, int argc, const char *argv[])
Definition: facedef.c:173
COMPLEX data[64]
Definition: fftest.c:34
struct resource rt_uniresource
default. Defined in librt/globals.c
Definition: globals.c:41
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
int arb_extrude(struct rt_arb_internal *arb, int face, fastf_t dist, const struct bn_tol *tol, fastf_t peqn[7][4])
Definition: arb_edit.c:83
#define LOOKUP_QUIET
Definition: raytrace.h:893
#define BRLCAD_OK
Definition: defines.h:71
Editing operations for arb primitives.
#define GED_CHECK_DRAWABLE(_gedp, _flags)
Definition: ged.h:129
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
struct bu_vls * ged_result_str
Definition: ged.h:357
int arb_permute(struct rt_arb_internal *arb, const char *encoded_permutation, const struct bn_tol *tol)
Definition: arb_edit.c:242
#define ZERO(val)
Definition: units.c:38
void * idb_ptr
Definition: raytrace.h:195
struct bn_tol wdb_tol
Definition: raytrace.h:1269
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
#define GED_DB_GET_INTERNAL(_gedp, _intern, _dp, _mat, _resource, _flags)
Definition: ged.h:233
int rt_arb_std_type(const struct rt_db_internal *ip, const struct bn_tol *tol)
Definition: arb8.c:317
double dbi_local2base
local2mm
Definition: raytrace.h:807
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
int arb_mirror_face_axis(struct rt_arb_internal *arb, fastf_t peqn[7][4], const int face, const char *axis, const struct bn_tol *tol)
Definition: arb_edit.c:424
int ged_edarb(struct ged *gedp, int argc, const char *argv[])
Definition: edarb.c:328
Definition: vls.h:56
double fastf_t
Definition: defines.h:300
void rt_db_free_internal(struct rt_db_internal *ip)
Definition: dir.c:216
int arb_edit(struct rt_arb_internal *arb, fastf_t peqn[7][4], int edge, int newedge, vect_t pos_model, const struct bn_tol *tol)
Definition: arb_edit.c:568
int bu_cmd(const struct bu_cmdtab *cmds, int argc, const char *argv[], int cmd_index, void *data, int *result)