BRL-CAD
bev.c
Go to the documentation of this file.
1 /* B E V . 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/bev.c
21  *
22  * The bev command.
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <stdlib.h>
29 #include <ctype.h>
30 #include <string.h>
31 
32 #include "bu/parallel.h"
33 #include "bu/getopt.h"
34 #include "rtgeom.h"
35 
36 #include "./ged_private.h"
37 
38 
39 static union tree *bev_facetize_tree;
40 static struct model *bev_nmg_model;
41 
42 
43 static union tree *
44 bev_facetize_region_end(struct db_tree_state *UNUSED(tsp), const struct db_full_path *pathp, union tree *curtree, void *client_data)
45 {
46  struct bu_list vhead;
47  struct ged *gedp = (struct ged *)client_data;
48 
49  BU_LIST_INIT(&vhead);
50 
52  char *sofar = db_path_to_string(pathp);
53 
54  bu_vls_printf(gedp->ged_result_str, "bev_facetize_region_end() path='%s'\n", sofar);
55  bu_free((void *)sofar, "path string");
56  }
57 
58  if (curtree->tr_op == OP_NOP) return curtree;
59 
61  if (bev_facetize_tree) {
62  union tree *tr;
63  BU_ALLOC(tr, union tree);
64  RT_TREE_INIT(tr);
65  tr->tr_op = OP_UNION;
67  tr->tr_b.tb_left = bev_facetize_tree;
68  tr->tr_b.tb_right = curtree;
69  bev_facetize_tree = tr;
70  } else {
71  bev_facetize_tree = curtree;
72  }
74 
75  /* Tree has been saved, and will be freed later */
76  return TREE_NULL;
77 }
78 
79 
80 int
81 ged_bev(struct ged *gedp, int argc, const char *argv[])
82 {
83  static const char *usage = "[-t] new_obj obj1 op obj2 op obj3 ...";
84 
85  int i;
86  int c;
87  int ncpu;
88  const char *cmdname;
89  char *newname;
90  struct rt_db_internal intern;
91  struct directory *dp;
92  const char *opstr;
93  int failed;
94 
95  /* static due to longjmp */
96  static int triangulate = 0;
97  static union tree *tmp_tree = NULL;
98 
101  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
102 
103  /* initialize result */
104  bu_vls_trunc(gedp->ged_result_str, 0);
105 
106  /* must be wanting help */
107  if (argc == 1) {
108  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
109  return GED_HELP;
110  }
111 
112  if (argc < 3) {
113  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
114  return GED_ERROR;
115  }
116 
117  cmdname = argv[0];
118 
119  /* Establish tolerances */
122 
124 
125  /* Initial values for options, must be reset each time */
126  ncpu = 1;
127  triangulate = 0;
128 
129  /* Parse options. */
130  bu_optind = 1; /* re-init bu_getopt() */
131  while ((c=bu_getopt(argc, (char * const *)argv, "t")) != -1) {
132  switch (c) {
133  case 't':
134  triangulate = 1;
135  break;
136  default: {
137  bu_vls_printf(gedp->ged_result_str, "%s: option '%c' unknown\n", cmdname, c);
138  }
139 
140  break;
141  }
142  }
143  argc -= bu_optind;
144  argv += bu_optind;
145 
146  newname = (char *)argv[0];
147  argv++;
148  argc--;
149 
150  if (argc < 1) {
151  bu_vls_printf(gedp->ged_result_str, "%s: Nothing to evaluate!!!\n", cmdname);
152  return GED_ERROR;
153  }
154 
155  GED_CHECK_EXISTS(gedp, newname, LOOKUP_QUIET, GED_ERROR);
156 
158  "%s: tessellating primitives with tolerances a=%g, r=%g, n=%g\n",
159  argv[0],
160  gedp->ged_wdbp->wdb_ttol.abs,
161  gedp->ged_wdbp->wdb_ttol.rel,
162  gedp->ged_wdbp->wdb_ttol.norm);
163 
164  bev_facetize_tree = (union tree *)0;
165  bev_nmg_model = nmg_mm();
166  gedp->ged_wdbp->wdb_initial_tree_state.ts_m = &bev_nmg_model;
167 
168  opstr = NULL;
169  tmp_tree = (union tree *)NULL;
170 
171  while (argc) {
172  i = db_walk_tree(gedp->ged_wdbp->dbip, 1, (const char **)argv,
173  ncpu,
175  0, /* take all regions */
176  bev_facetize_region_end,
178  (void *)gedp);
179 
180  if (i < 0) {
181  bu_vls_printf(gedp->ged_result_str, "%s: error in db_walk_tree()\n", cmdname);
182  /* Destroy NMG */
183  nmg_km(bev_nmg_model);
184  return GED_ERROR;
185  }
186  argc--;
187  argv++;
188 
189  if (tmp_tree && opstr) {
190  union tree *new_tree;
191  db_op_t op = db_str2op(opstr);
192 
193  BU_ALLOC(new_tree, union tree);
194  RT_TREE_INIT(new_tree);
195 
196  new_tree->tr_b.tb_regionp = REGION_NULL;
197  new_tree->tr_b.tb_left = tmp_tree;
198  new_tree->tr_b.tb_right = bev_facetize_tree;
199 
200  switch (op) {
201  case DB_OP_UNION:
202  new_tree->tr_op = OP_UNION;
203  break;
204  case DB_OP_SUBTRACT:
205  new_tree->tr_op = OP_SUBTRACT;
206  break;
207  case DB_OP_INTERSECT:
208  new_tree->tr_op = OP_INTERSECT;
209  break;
210  default: {
211  bu_vls_printf(gedp->ged_result_str, "%s: Unrecognized operator: (%c)\nAborting\n",
212  argv[0], opstr[0]);
213  db_free_tree(bev_facetize_tree, &rt_uniresource);
214  nmg_km(bev_nmg_model);
215  return GED_ERROR;
216  }
217  }
218 
219  tmp_tree = new_tree;
220  bev_facetize_tree = (union tree *)NULL;
221  } else if (!tmp_tree && !opstr) {
222  /* just starting out */
223  tmp_tree = bev_facetize_tree;
224  bev_facetize_tree = (union tree *)NULL;
225  }
226 
227  if (argc) {
228  opstr = argv[0];
229  argc--;
230  argv++;
231  } else
232  opstr = NULL;
233 
234  }
235 
236  if (tmp_tree) {
237  /* Now, evaluate the boolean tree into ONE region */
238  bu_vls_printf(gedp->ged_result_str, "%s: evaluating boolean expressions\n", cmdname);
239 
240  if (BU_SETJUMP) {
241  BU_UNSETJUMP;
242 
243  bu_vls_printf(gedp->ged_result_str, "%s: WARNING: Boolean evaluation failed!!!\n", cmdname);
244  if (tmp_tree)
245  db_free_tree(tmp_tree, &rt_uniresource);
246  tmp_tree = (union tree *)NULL;
247  nmg_km(bev_nmg_model);
248  bev_nmg_model = (struct model *)NULL;
249  return GED_ERROR;
250  }
251 
252  failed = nmg_boolean(tmp_tree, bev_nmg_model, &gedp->ged_wdbp->wdb_tol, &rt_uniresource);
253  BU_UNSETJUMP;
254  } else
255  failed = 1;
256 
257  if (failed) {
258  bu_vls_printf(gedp->ged_result_str, "%s: no resulting region, aborting\n", cmdname);
259  if (tmp_tree)
260  db_free_tree(tmp_tree, &rt_uniresource);
261  tmp_tree = (union tree *)NULL;
262  nmg_km(bev_nmg_model);
263  bev_nmg_model = (struct model *)NULL;
264  return GED_ERROR;
265  }
266  /* New region remains part of this nmg "model" */
267  NMG_CK_REGION(tmp_tree->tr_d.td_r);
268  bu_vls_printf(gedp->ged_result_str, "%s: facetize %s\n", cmdname, tmp_tree->tr_d.td_name);
269 
270  nmg_vmodel(bev_nmg_model);
271 
272  /* Triangulate model, if requested */
273  if (triangulate) {
274  bu_vls_printf(gedp->ged_result_str, "%s: triangulating resulting object\n", cmdname);
275  if (BU_SETJUMP) {
276  BU_UNSETJUMP;
277  bu_vls_printf(gedp->ged_result_str, "%s: WARNING: Triangulation failed!!!\n", cmdname);
278  if (tmp_tree)
279  db_free_tree(tmp_tree, &rt_uniresource);
280  tmp_tree = (union tree *)NULL;
281  nmg_km(bev_nmg_model);
282  bev_nmg_model = (struct model *)NULL;
283  return GED_ERROR;
284  }
285  nmg_triangulate_model(bev_nmg_model, &gedp->ged_wdbp->wdb_tol);
286  BU_UNSETJUMP;
287  }
288 
289  bu_vls_printf(gedp->ged_result_str, "%s: converting NMG to database format\n", cmdname);
290 
291  /* Export NMG as a new solid */
292  RT_DB_INTERNAL_INIT(&intern);
293  intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
294  intern.idb_type = ID_NMG;
295  intern.idb_meth = &OBJ[ID_NMG];
296  intern.idb_ptr = (void *)bev_nmg_model;
297  bev_nmg_model = (struct model *)NULL;
298 
299  GED_DB_DIRADD(gedp, dp, newname, RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&intern.idb_type, GED_ERROR);
300  GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
301 
302  tmp_tree->tr_d.td_r = (struct nmgregion *)NULL;
303 
304  /* Free boolean tree, and the regions in it. */
305  db_free_tree(tmp_tree, &rt_uniresource);
306 
307  return GED_OK;
308 }
309 
310 
311 /*
312  * Local Variables:
313  * tab-width: 8
314  * mode: C
315  * indent-tabs-mode: t
316  * c-file-style: "stroustrup"
317  * End:
318  * ex: shiftwidth=4 tabstop=8
319  */
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_DB_DIRADD(_gedp, _dp, _name, _laddr, _len, _dirflags, _ptr, _flags)
Definition: ged.h:213
#define GED_OK
Definition: ged.h:55
struct model ** ts_m
ptr to ptr to NMG "model"
Definition: raytrace.h:1072
Definition: list.h:118
struct nmgregion * td_r
ptr to NMG region
Definition: raytrace.h:1168
int ged_bev(struct ged *gedp, int argc, const char *argv[])
Definition: bev.c:81
#define OP_NOP
Leaf with no effect.
Definition: raytrace.h:1132
Definition: ged.h:338
struct db_i * dbip
Definition: raytrace.h:1266
void bu_semaphore_acquire(unsigned int i)
Definition: semaphore.c:180
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 region * tb_regionp
ptr to containing region
Definition: raytrace.h:1148
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
int bu_optind
Definition: globals.c:89
db_op_t db_str2op(const char *str)
Definition: op.c:31
int bu_getopt(int nargc, char *const nargv[], const char *ostr)
Definition: getopt.c:43
struct rt_tess_tol wdb_ttol
Definition: raytrace.h:1268
#define GED_ERROR
Definition: ged.h:61
#define RT_TREE_INIT(_p)
Definition: raytrace.h:1189
union tree * tb_left
Definition: raytrace.h:1149
#define GED_DB_PUT_INTERNAL(_gedp, _dp, _intern, _resource, _flags)
Definition: ged.h:243
double rel
rel dist tol
Definition: raytrace.h:181
int idb_major_type
Definition: raytrace.h:192
#define OP_SUBTRACT
Binary: L subtract R.
Definition: raytrace.h:1129
struct resource rt_uniresource
default. Defined in librt/globals.c
Definition: globals.c:41
#define OP_INTERSECT
Binary: L intersect R.
Definition: raytrace.h:1128
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
#define RT_G_DEBUG
Definition: raytrace.h:1718
db_op_t
Definition: op.h:33
#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
const struct rt_functab * idb_meth
for ft_ifree(), etc.
Definition: raytrace.h:194
#define ID_NMG
n-Manifold Geometry solid
Definition: raytrace.h:469
#define TREE_NULL
Definition: raytrace.h:1181
void nmg_km(struct model *m)
Definition: nmg_mk.c:1634
void db_free_tree(union tree *tp, struct resource *resp)
Definition: db_tree.c:1296
union tree * nmg_booltree_leaf_tess(struct db_tree_state *tsp, const struct db_full_path *pathp, struct rt_db_internal *ip, void *client_data)
Definition: nmg_bool.c:1175
#define RT_DIR_PHONY_ADDR
Special marker for d_addr field.
Definition: raytrace.h:879
struct tree::tree_node tr_b
#define UNUSED(parameter)
Definition: common.h:239
void nmg_triangulate_model(struct model *m, const struct bn_tol *tol)
Definition: nmg_tri.c:3818
#define GED_CHECK_EXISTS(_gedp, _name, _noisy, _flags)
Definition: ged.h:171
char * db_path_to_string(const struct db_full_path *pp)
Definition: db_fullpath.c:191
struct tree::tree_nmgregion tr_d
struct bu_vls * ged_result_str
Definition: ged.h:357
void bu_semaphore_release(unsigned int i)
Definition: semaphore.c:218
void nmg_vmodel(const struct model *m)
Definition: nmg_ck.c:635
struct model * nmg_mm(void)
Definition: nmg_mk.c:235
uint32_t magic
Definition: raytrace.h:179
union tree * tb_right
Definition: raytrace.h:1150
#define BU_LIST_INIT(_hp)
Definition: list.h:148
void * idb_ptr
Definition: raytrace.h:195
struct bn_tol wdb_tol
Definition: raytrace.h:1269
const struct rt_functab OBJ[]
Definition: table.c:159
Definition: op.h:35
const struct rt_tess_tol * ts_ttol
Tessellation tolerance.
Definition: raytrace.h:1070
struct db_tree_state wdb_initial_tree_state
Definition: raytrace.h:1267
double abs
absolute dist tol
Definition: raytrace.h:180
#define BU_UNSETJUMP
Definition: parallel.h:193
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
#define REGION_NULL
Definition: raytrace.h:558
#define GED_HELP
Definition: ged.h:62
const char * td_name
If non-null, dynamic string describing heritage of this region.
Definition: raytrace.h:1167
double norm
normal tol
Definition: raytrace.h:182
#define RT_SEM_MODEL
Definition: raytrace.h:1733
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
#define RT_TESS_TOL_MAGIC
Definition: magic.h:170
#define BU_SETJUMP
Definition: parallel.h:192
int db_walk_tree(struct db_i *dbip, int argc, const char **argv, int ncpu, const struct db_tree_state *init_state, int(*reg_start_func)(struct db_tree_state *, const struct db_full_path *, const struct rt_comb_internal *, void *client_data), union tree *(*reg_end_func)(struct db_tree_state *, const struct db_full_path *, union tree *, void *client_data), union tree *(*leaf_func)(struct db_tree_state *, const struct db_full_path *, struct rt_db_internal *, void *client_data), void *client_data)
#define DEBUG_TREEWALK
22 Database tree traversal
Definition: raytrace.h:107
#define GED_CHECK_READ_ONLY(_gedp, _flags)
Definition: ged.h:181
int nmg_boolean(union tree *tp, struct model *m, const struct bn_tol *tol, struct resource *resp)
Definition: nmg_bool.c:1523
const struct bn_tol * ts_tol
Math tolerance.
Definition: raytrace.h:1071
#define OP_UNION
Binary: L union R.
Definition: raytrace.h:1127