BRL-CAD
rfarb.c
Go to the documentation of this file.
1 /* R F A R B . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2008-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library 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 library 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/rfarb.c
21  *
22  * The rfarb command.
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <stdlib.h>
29 #include <ctype.h>
30 #include <string.h>
31 
32 #include "rtgeom.h"
33 #include "./ged_private.h"
34 
35 
36 int
37 ged_rfarb(struct ged *gedp, int argc, const char *argv[])
38 {
39  struct directory *dp;
40  struct rt_db_internal internal;
41  struct rt_arb_internal *aip;
42 
43  int i;
44  int solve[3];
45  vect_t norm;
46  fastf_t ndotv;
47 
48  /* intentionally double for scan */
49  double known_pt[3];
50  double pt[3][2];
51  double thick;
52  double rota;
53  double fba;
54 
55  static const char *usage = "name pX pY pZ rA fbA c X Y c X Y c X Y th";
56 
59  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
60 
61  /* initialize result */
62  bu_vls_trunc(gedp->ged_result_str, 0);
63 
64  /* must be wanting help */
65  if (argc == 1) {
66  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
67  return GED_HELP;
68  }
69 
70  if (argc != 16) {
71  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
72  return GED_ERROR;
73  }
74 
75  if (db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_QUIET) != RT_DIR_NULL) {
76  bu_vls_printf(gedp->ged_result_str, "%s: %s already exists\n", argv[0], argv[1]);
77  return GED_ERROR;
78  }
79 
80  if (sscanf(argv[2], "%lf", &known_pt[X]) != 1 ||
81  sscanf(argv[3], "%lf", &known_pt[Y]) != 1 ||
82  sscanf(argv[4], "%lf", &known_pt[Z]) != 1) {
83  bu_vls_printf(gedp->ged_result_str, "%s: bad value - %s %s %s",
84  argv[0], argv[2], argv[3], argv[4]);
85  return GED_ERROR;
86  }
87 
88  if (sscanf(argv[5], "%lf", &rota) != 1) {
89  bu_vls_printf(gedp->ged_result_str, "%s: bad rotation angle - %s", argv[0], argv[5]);
90  return GED_ERROR;
91  }
92 
93  if (sscanf(argv[6], "%lf", &fba) != 1) {
94  bu_vls_printf(gedp->ged_result_str, "%s: bad fallback angle - %s", argv[0], argv[6]);
95  return GED_ERROR;
96  }
97 
98  rota *= DEG2RAD;
99  fba *= DEG2RAD;
100 
101  /* calculate plane defined by these angles */
102  norm[0] = cos(fba) * cos(rota);
103  norm[1] = cos(fba) * sin(rota);
104  norm[2] = sin(fba);
105 
106  for (i = 0; i < 3; i++) {
107  switch (argv[7+3*i][0]) {
108  case 'x':
109  if (ZERO(norm[0])) {
110  bu_vls_printf(gedp->ged_result_str, "X not unique in this face\n");
111  return GED_ERROR;
112  }
113  solve[i] = X;
114 
115  if (sscanf(argv[7+3*i+1], "%lf", &pt[i][X]) != 1 ||
116  sscanf(argv[7+3*i+2], "%lf", &pt[i][Y]) != 1) {
117  bu_vls_printf(gedp->ged_result_str, "%s: at least one bad value - %s %s",
118  argv[0], argv[7+3*i+1], argv[7+3*i+2]);
119  }
120 
121  pt[i][X] *= gedp->ged_wdbp->dbip->dbi_local2base;
122  pt[i][Y] *= gedp->ged_wdbp->dbip->dbi_local2base;
123  break;
124 
125  case 'y':
126  if (ZERO(norm[1])) {
127  bu_vls_printf(gedp->ged_result_str, "Y not unique in this face\n");
128  return GED_ERROR;
129  }
130  solve[i] = Y;
131 
132  if (sscanf(argv[7+3*i+1], "%lf", &pt[i][X]) != 1 ||
133  sscanf(argv[7+3*i+2], "%lf", &pt[i][Y]) != 1) {
134  bu_vls_printf(gedp->ged_result_str, "%s: at least one bad value - %s %s",
135  argv[0], argv[7+3*i+1], argv[7+3*i+2]);
136  }
137 
138  pt[i][X] *= gedp->ged_wdbp->dbip->dbi_local2base;
139  pt[i][Y] *= gedp->ged_wdbp->dbip->dbi_local2base;
140  break;
141 
142  case 'z':
143  if (ZERO(norm[2])) {
144  bu_vls_printf(gedp->ged_result_str, "Z not unique in this face\n");
145  return GED_ERROR;
146  }
147  solve[i] = Z;
148 
149  if (sscanf(argv[7+3*i+1], "%lf", &pt[i][X]) != 1 ||
150  sscanf(argv[7+3*i+2], "%lf", &pt[i][Y]) != 1) {
151  bu_vls_printf(gedp->ged_result_str, "%s: at least one bad value - %s %s",
152  argv[0], argv[7+3*i+1], argv[7+3*i+2]);
153  }
154 
155  pt[i][X] *= gedp->ged_wdbp->dbip->dbi_local2base;
156  pt[i][Y] *= gedp->ged_wdbp->dbip->dbi_local2base;
157  break;
158 
159  default:
160  bu_vls_printf(gedp->ged_result_str, "coordinate must be x, y, or z\n");
161  return GED_ERROR;
162  }
163  }
164 
165  if (sscanf(argv[7+3*3], "%lf", &thick) != 1 || ZERO(thick)) {
166  bu_vls_printf(gedp->ged_result_str, "%s: bad thickness - %s", argv[0], argv[7+3*3]);
167  return GED_ERROR;
168  }
169  thick *= gedp->ged_wdbp->dbip->dbi_local2base;
170 
171  RT_DB_INTERNAL_INIT(&internal);
172  internal.idb_major_type = DB5_MAJORTYPE_BRLCAD;
173  internal.idb_type = ID_ARB8;
174  internal.idb_meth = &OBJ[ID_ARB8];
175  BU_ALLOC(internal.idb_ptr, struct rt_arb_internal);
176  aip = (struct rt_arb_internal *)internal.idb_ptr;
177  aip->magic = RT_ARB_INTERNAL_MAGIC;
178 
179  for (i = 0; i < 8; i++) {
180  VSET(aip->pt[i], 0.0, 0.0, 0.0);
181  }
182 
183  VSCALE(aip->pt[0], known_pt, gedp->ged_wdbp->dbip->dbi_local2base);
184 
185  ndotv = VDOT(aip->pt[0], norm);
186 
187  /* calculate the unknown coordinate for points 2, 3, 4 */
188  for (i = 0; i < 3; i++) {
189  int j;
190  j = i+1;
191 
192  switch (solve[i]) {
193  case X:
194  aip->pt[j][Y] = pt[i][0];
195  aip->pt[j][Z] = pt[i][1];
196  aip->pt[j][X] = (ndotv
197  - norm[1] * aip->pt[j][Y]
198  - norm[2] * aip->pt[j][Z])
199  / norm[0];
200  break;
201  case Y:
202  aip->pt[j][X] = pt[i][0];
203  aip->pt[j][Z] = pt[i][1];
204  aip->pt[j][Y] = (ndotv
205  - norm[0] * aip->pt[j][X]
206  - norm[2] * aip->pt[j][Z])
207  / norm[1];
208  break;
209  case Z:
210  aip->pt[j][X] = pt[i][0];
211  aip->pt[j][Y] = pt[i][1];
212  aip->pt[j][Z] = (ndotv
213  - norm[0] * aip->pt[j][X]
214  - norm[1] * aip->pt[j][Y])
215  / norm[2];
216  break;
217 
218  default:
219  return GED_ERROR;
220  }
221  }
222 
223  /* calculate the remaining 4 vertices */
224  for (i = 0; i < 4; i++) {
225  VJOIN1(aip->pt[i+4], aip->pt[i], thick, norm);
226  }
227 
228  dp = db_diradd(gedp->ged_wdbp->dbip, argv[1], RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&internal.idb_type);
229  if (dp == RT_DIR_NULL) {
230  bu_vls_printf(gedp->ged_result_str, "%s: Cannot add %s to the directory\n", argv[0], argv[1]);
231  return GED_ERROR;
232  }
233 
234  if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &internal, &rt_uniresource) < 0) {
235  rt_db_free_internal(&internal);
236  bu_vls_printf(gedp->ged_result_str, "%s: Database write error, aborting.\n", argv[0]);
237  }
238 
239  return GED_OK;
240 }
241 
242 
243 /*
244  * Local Variables:
245  * tab-width: 8
246  * mode: C
247  * indent-tabs-mode: t
248  * c-file-style: "stroustrup"
249  * End:
250  * ex: shiftwidth=4 tabstop=8
251  */
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_OK
Definition: ged.h:55
int rt_db_put_internal(struct directory *dp, struct db_i *dbip, struct rt_db_internal *ip, struct resource *resp)
Definition: dir.c:136
Definition: ged.h:338
int ged_rfarb(struct ged *gedp, int argc, const char *argv[])
Definition: rfarb.c:37
struct db_i * dbip
Definition: raytrace.h:1266
#define ID_ARB8
Generalized ARB. V + 7 vectors.
Definition: raytrace.h:462
#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
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
#define GED_ERROR
Definition: ged.h:61
Definition: color.c:49
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
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
#define RT_DIR_SOLID
this name is a solid
Definition: raytrace.h:883
#define RT_DB_INTERNAL_INIT(_p)
Definition: raytrace.h:199
#define LOOKUP_QUIET
Definition: raytrace.h:893
#define RT_DIR_PHONY_ADDR
Special marker for d_addr field.
Definition: raytrace.h:879
struct bu_vls * ged_result_str
Definition: ged.h:357
struct directory * db_diradd(struct db_i *, const char *name, off_t laddr, size_t len, int flags, void *ptr)
Definition: db_lookup.c:190
#define ZERO(val)
Definition: units.c:38
const struct rt_functab OBJ[]
Definition: table.c:159
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
#define RT_DIR_NULL
Definition: raytrace.h:875
#define GED_HELP
Definition: ged.h:62
Definition: color.c:51
double dbi_local2base
local2mm
Definition: raytrace.h:807
#define GED_CHECK_READ_ONLY(_gedp, _flags)
Definition: ged.h:181
double fastf_t
Definition: defines.h:300
#define RT_ARB_INTERNAL_MAGIC
Definition: magic.h:82
void rt_db_free_internal(struct rt_db_internal *ip)
Definition: dir.c:216
Definition: color.c:50