BRL-CAD
facedef.c
Go to the documentation of this file.
1 /* F A C E D E F . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1986-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/facedef.c
21  *
22  */
23 
24 #include "common.h"
25 
26 #include <stdlib.h>
27 #include <math.h>
28 #include <signal.h>
29 
30 
31 #include "vmath.h"
32 #include "rtgeom.h"
33 #include "raytrace.h"
34 #include "ged_private.h"
35 
36 
37 char *p_rotfb[] = {
38  "Enter rot, fb angles: ",
39  "Enter fb angle: ",
40  "Enter fixed vertex(v#) or point(X Y Z): ",
41  "Enter Y, Z of point: ",
42  "Enter Z of point: "
43 };
44 
45 
46 char *p_3pts[] = {
47  "Enter X, Y, Z of point",
48  "Enter Y, Z of point",
49  "Enter Z of point"
50 };
51 
52 
53 char *p_pleqn[] = {
54  "Enter A, B, C, D of plane equation: ",
55  "Enter B, C, D of plane equation: ",
56  "Enter C, D of plane equation: ",
57  "Enter D of plane equation: "
58 };
59 
60 
61 char *p_nupnt[] = {
62  "Enter X, Y, Z of fixed point: ",
63  "Enter Y, Z of fixed point: ",
64  "Enter Z of fixed point: "
65 };
66 
67 
68 /*
69  * Gets the planar equation from the array argv[] and puts the result
70  * into 'plane'.
71  */
72 static void
73 get_pleqn(struct ged *gedp, fastf_t *plane, const char *argv[])
74 {
75  int i;
76 
77  for (i=0; i<4; i++)
78  plane[i]= atof(argv[i]);
79  VUNITIZE(&plane[0]);
80  plane[W] *= gedp->ged_wdbp->dbip->dbi_local2base;
81  return;
82 }
83 
84 
85 /*
86  * Gets three definite points from the array argv[] and finds the
87  * planar equation from these points. The resulting plane equation is
88  * stored in 'plane'.
89  *
90  * Returns -
91  * 0 success
92  * -1 failure
93  */
94 static int
95 get_3pts(struct ged *gedp, fastf_t *plane, const char *argv[], const struct bn_tol *tol)
96 {
97  int i;
98  point_t a, b, c;
99 
100  for (i=0; i<3; i++)
101  a[i] = atof(argv[0+i]) * gedp->ged_wdbp->dbip->dbi_local2base;
102  for (i=0; i<3; i++)
103  b[i] = atof(argv[3+i]) * gedp->ged_wdbp->dbip->dbi_local2base;
104  for (i=0; i<3; i++)
105  c[i] = atof(argv[6+i]) * gedp->ged_wdbp->dbip->dbi_local2base;
106 
107  if (bn_mk_plane_3pts(plane, a, b, c, tol) < 0) {
108  bu_vls_printf(gedp->ged_result_str, "facedef: not a plane\n");
109  return -1; /* failure */
110  }
111  return 0; /* success */
112 }
113 
114 
115 /*
116  * Gets information from the array argv[]. Finds the planar equation
117  * given rotation and fallback angles, plus a fixed point. Result is
118  * stored in 'plane'. The vertices pointed to by 's_recp' are used if
119  * a vertex is chosen as fixed point.
120  */
121 static void
122 get_rotfb(struct ged *gedp, fastf_t *plane, const char *argv[], const struct rt_arb_internal *arb)
123 {
124  fastf_t rota, fb_a;
125  short int i, temp;
126  point_t pt;
127 
128  rota= atof(argv[0]) * DEG2RAD;
129  fb_a = atof(argv[1]) * DEG2RAD;
130 
131  /* calculate normal vector (length=1) from rot, fb */
132  plane[0] = cos(fb_a) * cos(rota);
133  plane[1] = cos(fb_a) * sin(rota);
134  plane[2] = sin(fb_a);
135 
136  if (argv[2][0] == 'v') {
137  /* vertex given */
138  /* strip off 'v', subtract 1 */
139  temp = atoi(argv[2]+1) - 1;
140  plane[W]= VDOT(&plane[0], arb->pt[temp]);
141  } else {
142  /* definite point given */
143  for (i=0; i<3; i++)
144  pt[i]=atof(argv[2+i]) * gedp->ged_wdbp->dbip->dbi_local2base;
145  plane[W]=VDOT(&plane[0], pt);
146  }
147 }
148 
149 
150 /*
151  * Gets a point from the three strings in the 'argv' array. The value
152  * of D of 'plane' is changed such that the plane passes through the
153  * input point.
154  */
155 static void
156 get_nupnt(struct ged *gedp, fastf_t *plane, const char *argv[])
157 {
158  int i;
159  point_t pt;
160 
161  for (i=0; i<3; i++)
162  pt[i] = atof(argv[i]) * gedp->ged_wdbp->dbip->dbi_local2base;
163  plane[W] = VDOT(&plane[0], pt);
164 }
165 
166 /*
167 
168  * Redefines one of the defining planes for a GENARB8. Finds which
169  * plane to redefine and gets input, then shuttles the process over to
170  * one of four functions before calculating new vertices.
171  */
172 int
173 edarb_facedef(void *data, int argc, const char *argv[])
174 {
175  struct ged *gedp = (struct ged *)data;
176  int type;
177  struct directory *dp;
178  struct rt_db_internal intern;
179  struct rt_arb_internal *arb;
180  short int i;
181  int face, prod, plane;
182  plane_t planes[6];
183  struct bu_vls error_msg = BU_VLS_INIT_ZERO;
184  static const char *usage = "arb face [a|b|c|d parameters]";
185 
186  /* must be wanting help */
187  if (argc == 2) {
188  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0], argv[1], usage);
189  return GED_HELP;
190  }
191 
192  GED_DB_LOOKUP(gedp, dp, (char *)argv[2], LOOKUP_QUIET, GED_ERROR);
193  GED_DB_GET_INTERNAL(gedp, &intern, dp, (matp_t)NULL, &rt_uniresource, GED_ERROR);
194 
195  if (intern.idb_type != ID_ARB8) {
196  bu_vls_printf(gedp->ged_result_str, "%s %s: solid type must be ARB\n", argv[0], argv[1]);
197  rt_db_free_internal(&intern);
198  return GED_ERROR;
199  }
200 
201  type = rt_arb_std_type(&intern, &gedp->ged_wdbp->wdb_tol);
202  if (type != 8 && type != 6 && type != 4) {
203  bu_vls_printf(gedp->ged_result_str, "ARB%d: extrusion of faces not allowed\n", type);
204  rt_db_free_internal(&intern);
205  return GED_ERROR;
206  }
207 
208  arb = (struct rt_arb_internal *)intern.idb_ptr;
209  RT_ARB_CK_MAGIC(arb);
210 
211  /* find new planes to account for any editing */
212  if (rt_arb_calc_planes(&error_msg, arb, type, planes, &gedp->ged_wdbp->wdb_tol)) {
213  bu_vls_printf(gedp->ged_result_str, "%s", bu_vls_addr(&error_msg));
214  bu_vls_free(&error_msg);
215  rt_db_free_internal(&intern);
216  return GED_ERROR;
217  }
218  bu_vls_free(&error_msg);
219 
220  /* get face, initialize args and argcnt */
221  face = atoi(argv[3]);
222 
223  /* use product of vertices to distinguish faces */
224  for (i=0, prod=1;i<4;i++) {
225  if (face > 0) {
226  prod *= face%10;
227  face /= 10;
228  }
229  }
230 
231  switch (prod) {
232  case 6: /* face 123 of arb4 */
233  case 24:plane=0; /* face 1234 of arb8 */
234  /* face 1234 of arb7 */
235  /* face 1234 of arb6 */
236  /* face 1234 of arb5 */
237  if (type==4 && prod==24)
238  plane=2; /* face 234 of arb4 */
239  break;
240  case 8: /* face 124 of arb4 */
241  case 180: /* face 2365 of arb6 */
242  case 210: /* face 567 of arb7 */
243  case 1680:plane=1; /* face 5678 of arb8 */
244  break;
245  case 30: /* face 235 of arb5 */
246  case 120: /* face 1564 of arb6 */
247  case 20: /* face 145 of arb7 */
248  case 160:plane=2; /* face 1584 of arb8 */
249  if (type==5)
250  plane=4; /* face 145 of arb5 */
251  break;
252  case 12: /* face 134 of arb4 */
253  case 10: /* face 125 of arb6 */
254  case 252:plane=3; /* face 2376 of arb8 */
255  /* face 2376 of arb7 */
256  if (type==5)
257  plane=1; /* face 125 of arb5 */
258  break;
259  case 72: /* face 346 of arb6 */
260  case 60:plane=4; /* face 1265 of arb8 */
261  /* face 1265 of arb7 */
262  if (type==5)
263  plane=3; /* face 345 of arb5 */
264  break;
265  case 420: /* face 4375 of arb7 */
266  case 672:plane=5; /* face 4378 of arb8 */
267  break;
268  default:
269  {
270  bu_vls_printf(gedp->ged_result_str, "bad face (product=%d)\n", prod);
271  rt_db_free_internal(&intern);
272  return GED_ERROR;
273  }
274  }
275 
276  if (argc < 5) {
277  /* menu of choices for plane equation definition */
278  bu_vls_printf(gedp->ged_result_str, "\ta planar equation\n\
279 \tb 3 points\n\
280 \tc rot, fb angles + fixed pt\n\
281 \td same plane thru fixed pt\n\
282 \tq quit\n\
283 Enter form of new face definition: ");
284  rt_db_free_internal(&intern);
285  return GED_MORE;
286  }
287 
288  switch (argv[4][0]) {
289  case 'a':
290  /* special case for arb7, because of 2 4-pt planes meeting */
291  if (type == 7)
292  if (plane!=0 && plane!=3) {
293  bu_vls_printf(gedp->ged_result_str, "facedef: can't redefine that arb7 plane\n");
294  rt_db_free_internal(&intern);
295  return GED_ERROR;
296  }
297  if (argc < 9) {
298  /* total # of args under this option */
299  bu_vls_printf(gedp->ged_result_str, "%s", p_pleqn[argc-5]);
300  rt_db_free_internal(&intern);
301  return GED_MORE;
302  }
303  get_pleqn(gedp, planes[plane], &argv[5]);
304  break;
305  case 'b':
306  /* special case for arb7, because of 2 4-pt planes meeting */
307  if (type == 7)
308  if (plane!=0 && plane!=3) {
309  bu_vls_printf(gedp->ged_result_str, "facedef: can't redefine that arb7 plane\n");
310  rt_db_free_internal(&intern);
311  return GED_ERROR;
312  }
313  if (argc < 14) {
314  /* total # of args under this option */
315  bu_vls_printf(gedp->ged_result_str, "%s %d: ", p_3pts[(argc-5)%3], (argc-2)/3);
316  rt_db_free_internal(&intern);
317  return GED_MORE;
318  }
319  if (get_3pts(gedp, planes[plane], &argv[5], &gedp->ged_wdbp->wdb_tol)) {
320  return GED_ERROR;
321  }
322  break;
323  case 'c':
324  /* special case for arb7, because of 2 4-pt planes meeting */
325  if (type == 7 && (plane != 0 && plane != 3)) {
326  if (argc < 7) {
327  bu_vls_printf(gedp->ged_result_str, "%s", p_rotfb[argc-5]);
328  rt_db_free_internal(&intern);
329  return GED_MORE;
330  }
331 
332  argv[7] = "Release 6";
333  bu_vls_printf(gedp->ged_result_str, "Fixed point is vertex five.\n");
334  }
335  /* total # of as under this option */
336  else if (argc < 10 && (argc > 7 ? argv[7][0] != 'R' : 1)) {
337  bu_vls_printf(gedp->ged_result_str, "%s", p_rotfb[argc-5]);
338  rt_db_free_internal(&intern);
339  return GED_MORE;
340  }
341  get_rotfb(gedp, planes[plane], &argv[5], arb);
342  break;
343  case 'd':
344  /* special case for arb7, because of 2 4-pt planes meeting */
345  if (type == 7)
346  if (plane!=0 && plane!=3) {
347  bu_vls_printf(gedp->ged_result_str, "facedef: can't redefine that arb7 plane\n");
348  rt_db_free_internal(&intern);
349  return GED_ERROR;
350  }
351  if (argc < 8) {
352  bu_vls_printf(gedp->ged_result_str, "%s", p_nupnt[argc-5]);
353  rt_db_free_internal(&intern);
354  return GED_MORE;
355  }
356  get_nupnt(gedp, planes[plane], &argv[5]);
357  break;
358  case 'q':
359  return GED_OK;
360  default:
361  bu_vls_printf(gedp->ged_result_str, "facedef: %s is not an option\n", argv[2]);
362  rt_db_free_internal(&intern);
363  return GED_ERROR;
364  }
365 
366  /* find all vertices from the plane equations */
367  if (rt_arb_calc_points(arb, type, (const plane_t *)planes, &gedp->ged_wdbp->wdb_tol) < 0) {
368  bu_vls_printf(gedp->ged_result_str, "facedef: unable to find points\n");
369  rt_db_free_internal(&intern);
370  return GED_ERROR;
371  }
372 
373  GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
374  rt_db_free_internal(&intern);
375 
376  return GED_OK;
377 }
378 
379 
380 /*
381  * Local Variables:
382  * mode: C
383  * tab-width: 8
384  * indent-tabs-mode: t
385  * c-file-style: "stroustrup"
386  * End:
387  * ex: shiftwidth=4 tabstop=8
388  */
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
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
char * p_pleqn[]
Definition: facedef.c:53
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
#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 LOOKUP_QUIET
Definition: raytrace.h:893
char * p_nupnt[]
Definition: facedef.c:61
Support for uniform tolerances.
Definition: tol.h:71
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
struct bu_vls * ged_result_str
Definition: ged.h:357
char * p_3pts[]
Definition: facedef.c:46
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
char * p_rotfb[]
Definition: facedef.c:37
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
Definition: vls.h:56
double fastf_t
Definition: defines.h:300
int bn_mk_plane_3pts(plane_t plane, const point_t a, const point_t b, const point_t c, const struct bn_tol *tol)
int rt_arb_calc_points(struct rt_arb_internal *arb, int cgtype, const plane_t planes[6], const struct bn_tol *tol)
Definition: arb8.c:1740
void rt_db_free_internal(struct rt_db_internal *ip)
Definition: dir.c:216
#define GED_MORE
Definition: ged.h:63