BRL-CAD
obj_write.c
Go to the documentation of this file.
1 /* G - O B J . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1996-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  */
21 /** @file conv/g-obj.c
22  *
23  * Program to convert a BRL-CAD model (in a .g file) to a Wavefront
24  * '.obj' file by calling on the NMG booleans.
25  *
26  */
27 
28 #include "common.h"
29 
30 /* system headers */
31 #include <stdlib.h>
32 #include <math.h>
33 #include <string.h>
34 #include "bio.h"
35 
36 /* interface headers */
37 #include "bu/getopt.h"
38 #include "bu/parallel.h"
39 #include "vmath.h"
40 #include "nmg.h"
41 #include "rtgeom.h"
42 #include "raytrace.h"
43 #include "../../plugin.h"
44 
45 
46 #define V3ARGSIN(a) (a)[X]/25.4, (a)[Y]/25.4, (a)[Z]/25.4
47 
48 extern union tree *do_region_end(struct db_tree_state *tsp,
49  const struct db_full_path *pathp, union tree *curtree, void *client_data);
50 
51 static long vert_offset = 0;
52 static long norm_offset = 0;
53 static int do_normals = 0;
54 static int NMG_debug; /* saved arg of -X, for longjmp handling */
55 static int verbose = 0;
56 static int usemtl = 0; /* flag to include 'usemtl' statements with a
57  * code for GIFT materials:
58  *
59  * usemtl 0_100_32
60  * means aircode is 0
61  * los is 100
62  * GIFT material is 32
63  */
64 static const char *output_file = NULL; /* output filename */
65 static char *error_file = NULL; /* error filename */
66 static FILE *fp; /* Output file pointer */
67 static FILE *fpe; /* Error file pointer */
68 static struct db_i *dbip;
69 static struct rt_tess_tol ttol;
70 static struct bn_tol tol;
71 static struct model *the_model;
72 
73 static struct db_tree_state tree_state; /* includes tol & model */
74 
75 static int regions_tried = 0;
76 static int regions_converted = 0;
77 static int regions_written = 0;
78 static int inches = 0;
79 
80 static int
81 gcv_obj_write(const char *path, struct db_i *vdbip,
82  const struct gcv_opts *UNUSED(options))
83 {
84  double percent;
85  size_t num_objects = 0;
86  char **object_names = NULL;
87 
88  output_file = path;
89  dbip = vdbip;
90 
91  tree_state = rt_initial_tree_state; /* struct copy */
92  tree_state.ts_tol = &tol;
93  tree_state.ts_ttol = &ttol;
94  tree_state.ts_m = &the_model;
95 
96  ttol.magic = RT_TESS_TOL_MAGIC;
97  /* Defaults, updated by command line options. */
98  ttol.abs = 0.0;
99  ttol.rel = 0.01;
100  ttol.norm = 0.0;
101 
102  /* FIXME: These need to be improved */
103  tol.magic = BN_TOL_MAGIC;
104  tol.dist = BN_TOL_DIST;
105  tol.dist_sq = tol.dist * tol.dist;
106  tol.perp = 1e-6;
107  tol.para = 1 - tol.perp;
108 
109  the_model = nmg_mm();
110  BU_LIST_INIT(&RTG.rtg_vlfree); /* for vlist macros */
111 
112  if (!output_file)
113  fp = stdout;
114  else {
115  /* Open output file */
116  if ((fp = fopen(output_file, "wb+")) == NULL) {
117  perror("obj-g");
118  bu_log("Cannot open output file (%s) for writing\n", output_file);
119  return 0;
120  }
121  }
122 
123  /* Open g-obj error log file */
124  if (!error_file) {
125  fpe = stderr;
126  setmode(fileno(fpe), O_BINARY);
127  } else if ((fpe = fopen(error_file, "wb")) == NULL) {
128  perror("g-obj");
129  bu_log("Cannot open output file (%s) for writing\n", error_file);
130  return 0;
131  }
132 
133  BN_CK_TOL(tree_state.ts_tol);
134  RT_CK_TESS_TOL(tree_state.ts_ttol);
135 
136  /* Write out header */
137  if (inches)
138  fprintf(fp, "# BRL-CAD generated Wavefront OBJ file (Units in)\n");
139  else
140  fprintf(fp, "# BRL-CAD generated Wavefront OBJ file (Units mm)\n");
141 
142  fprintf(fp, "# BRL-CAD model: %s\n# BRL_CAD objects:", "obj-g");
143  fprintf(fp, "\n");
144 
145  /* get toplevel objects */
146  {
147  struct directory **results;
149  num_objects = db_ls(dbip, DB_LS_TOPS, NULL, &results);
150  object_names = db_dpv_to_argv(results);
151  bu_free(results, "tops");
152  }
153 
154  /* Walk indicated tree(s). Each region will be output separately */
155  (void) db_walk_tree(dbip, num_objects, (const char **)object_names,
156  1, /* ncpu */
157  &tree_state,
158  0, /* take all regions */
161  (void *)NULL); /* in librt/nmg_bool.c */
162 
163  bu_free(object_names, "object_names");
164 
165  if (regions_tried > 0) {
166  percent = ((double)regions_converted * 100.0) / regions_tried;
167  printf("Tried %d regions, %d converted to NMG's successfully. %g%%\n",
168  regions_tried, regions_converted, percent);
169  percent = ((double)regions_written * 100.0) / regions_tried;
170  printf(" %d triangulated successfully. %g%%\n",
171  regions_written, percent);
172  }
173 
174  fclose(fp);
175 
176  /* Release dynamic storage */
177  nmg_km(the_model);
179 
180  return 1;
181 }
182 
183 
184 static const struct gcv_converter converters[] = {
185  {"obj", NULL, gcv_obj_write},
186  {NULL, NULL, NULL}
187 };
188 
189 const struct gcv_plugin_info gcv_plugin_conv_obj_write = {converters};
190 
191 
192 static void
193 nmg_to_obj(struct nmgregion *r, const struct db_full_path *pathp,
194  int UNUSED(region_id), int aircode, int los, int material_id)
195 {
196  struct model *m;
197  struct shell *s;
198  struct vertex *v;
199  struct bu_ptbl verts;
200  struct bu_ptbl norms;
201  char *region_name;
202  size_t numverts = 0; /* Number of vertices to output */
203  size_t numtri = 0; /* Number of triangles to output */
204  size_t i;
205 
206  NMG_CK_REGION(r);
207  RT_CK_FULL_PATH(pathp);
208 
209  region_name = db_path_to_string(pathp);
210 
211  m = r->m_p;
212  NMG_CK_MODEL(m);
213 
214  /* triangulate model */
215  nmg_triangulate_model(m, &tol);
216 
217  /* list all vertices in result */
218  nmg_vertex_tabulate(&verts, &r->l.magic);
219 
220  /* Get number of vertices */
221  numverts = BU_PTBL_END(&verts);
222 
223  /* get list of vertexuse normals */
224  if (do_normals)
225  nmg_vertexuse_normal_tabulate(&norms, &r->l.magic);
226 
227  /* BEGIN CHECK SECTION */
228  /* Check vertices */
229 
230  for (i = 0; i < numverts; i++) {
231  v = (struct vertex *)BU_PTBL_GET(&verts, i);
232  NMG_CK_VERTEX(v);
233  }
234 
235  /* Check triangles */
236  for (BU_LIST_FOR(s, shell, &r->s_hd)) {
237  struct faceuse *fu;
238 
239  NMG_CK_SHELL(s);
240 
241  for (BU_LIST_FOR(fu, faceuse, &s->fu_hd)) {
242  struct loopuse *lu;
243 
244  NMG_CK_FACEUSE(fu);
245 
246  if (fu->orientation != OT_SAME)
247  continue;
248 
249  for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
250  struct edgeuse *eu;
251  int vert_count = 0;
252 
253  NMG_CK_LOOPUSE(lu);
254 
255  if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
256  continue;
257 
258  /* check vertex numbers for each triangle */
259  for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
260  int loc;
261  NMG_CK_EDGEUSE(eu);
262 
263  v = eu->vu_p->v_p;
264  NMG_CK_VERTEX(v);
265 
266  vert_count++;
267  loc = bu_ptbl_locate(&verts, (long *)v);
268 
269  if (loc < 0) {
270  bu_ptbl_free(&verts);
271  bu_free(region_name, "region name");
272  bu_log("Vertex from eu %p is not in nmgregion %p\n", (void *)eu, (void *)r);
273  bu_exit(1, "ERROR: Can't find vertex in list!");
274  }
275  }
276 
277  if (vert_count > 3) {
278  bu_ptbl_free(&verts);
279  bu_free(region_name, "region name");
280  bu_log("lu %p has %d vertices!\n", (void *)lu, vert_count);
281  bu_exit(1, "ERROR: LU is not a triangle\n");
282  } else if (vert_count < 3)
283  continue;
284 
285  numtri++;
286  }
287  }
288  }
289 
290  /* END CHECK SECTION */
291  /* Write pertinent info for this region */
292 
293  if (usemtl)
294  fprintf(fp, "usemtl %d_%d_%d\n", aircode, los, material_id);
295 
296  fprintf(fp, "g %s", pathp->fp_names[0]->d_namep);
297 
298  for (i = 1; i < pathp->fp_len; i++)
299  fprintf(fp, "/%s", pathp->fp_names[i]->d_namep);
300 
301  fprintf(fp, "\n");
302 
303  /* Write vertices */
304  for (i = 0; i < numverts; i++) {
305  v = (struct vertex *)BU_PTBL_GET(&verts, i);
306  NMG_CK_VERTEX(v);
307 
308  if (inches)
309  fprintf(fp, "v %f %f %f\n", V3ARGSIN(v->vg_p->coord));
310  else
311  fprintf(fp, "v %f %f %f\n", V3ARGS(v->vg_p->coord));
312  }
313 
314  /* Write vertexuse normals */
315  if (do_normals) {
316  for (i = 0; i < BU_PTBL_LEN(&norms); i++) {
317  struct vertexuse_a_plane *va;
318 
319  va = (struct vertexuse_a_plane *)BU_PTBL_GET(&norms, i);
320  NMG_CK_VERTEXUSE_A_PLANE(va);
321 
322  if (inches)
323  fprintf(fp, "vn %f %f %f\n", V3ARGSIN(va->N));
324  else
325  fprintf(fp, "vn %f %f %f\n", V3ARGS(va->N));
326  }
327  }
328 
329  /* output triangles */
330  for (BU_LIST_FOR(s, shell, &r->s_hd)) {
331  struct faceuse *fu;
332 
333  NMG_CK_SHELL(s);
334 
335  for (BU_LIST_FOR(fu, faceuse, &s->fu_hd)) {
336  struct loopuse *lu;
337 
338  NMG_CK_FACEUSE(fu);
339 
340  if (fu->orientation != OT_SAME)
341  continue;
342 
343  for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
344  struct edgeuse *eu;
345  int vert_count = 0;
346  int use_normals = 1;
347 
348  NMG_CK_LOOPUSE(lu);
349 
350  if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
351  continue;
352 
353  /* Each vertexuse of the face must have a normal in order
354  * to use the normals in Wavefront
355  */
356  if (do_normals) {
357  for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
358  NMG_CK_EDGEUSE(eu);
359 
360  if (!eu->vu_p->a.magic_p) {
361  use_normals = 0;
362  break;
363  }
364 
365  if (*eu->vu_p->a.magic_p != NMG_VERTEXUSE_A_PLANE_MAGIC) {
366  use_normals = 0;
367  break;
368  }
369  }
370  } else
371  use_normals = 0;
372 
373  fprintf(fp, "f");
374 
375  /* list vertex numbers for each triangle */
376  for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
377  int loc;
378  NMG_CK_EDGEUSE(eu);
379 
380  v = eu->vu_p->v_p;
381  NMG_CK_VERTEX(v);
382 
383  vert_count++;
384  loc = bu_ptbl_locate(&verts, (long *)v);
385 
386  if (loc < 0) {
387  bu_ptbl_free(&verts);
388  bu_log("Vertex from eu %p is not in nmgregion %p\n", (void *)eu, (void *)r);
389  bu_free(region_name, "region name");
390  bu_exit(1, "Can't find vertex in list!\n");
391  }
392 
393  if (use_normals) {
394  int j;
395 
396  j = bu_ptbl_locate(&norms, (long *)eu->vu_p->a.magic_p);
397  fprintf(fp, " %ld//%ld", loc + 1 + vert_offset, j + 1 + norm_offset);
398  } else
399  fprintf(fp, " %ld", loc + 1 + vert_offset);
400  }
401 
402  fprintf(fp, "\n");
403 
404  if (vert_count > 3) {
405  bu_ptbl_free(&verts);
406  bu_free(region_name, "region name");
407  bu_log("lu %p has %d vertices!\n", (void *)lu, vert_count);
408  bu_exit(1, "ERROR: LU is not a triangle\n");
409  }
410  }
411  }
412  }
413 
414  /* regions_converted++;
415  printf("Processed region %s\n", region_name);
416  printf("Regions attempted = %d Regions done = %d\n", regions_tried, regions_converted);
417  fflush(stdout);
418  */
419  vert_offset += numverts;
420  bu_ptbl_free(&verts);
421 
422  if (do_normals) {
423  norm_offset += BU_PTBL_END(&norms);
424  bu_ptbl_free(&norms);
425  }
426 
427  bu_free(region_name, "region name");
428 }
429 
430 
431 static void
432 process_triangulation(struct nmgregion *r, const struct db_full_path *pathp,
433  struct db_tree_state *tsp)
434 {
435  if (!BU_SETJUMP) {
436  /* try */
437 
438  /* Write the region to the TANKILL file */
439  nmg_to_obj(r, pathp, tsp->ts_regionid, tsp->ts_aircode, tsp->ts_los,
440  tsp->ts_gmater);
441 
442  } else {
443  /* catch */
444 
445  char *sofar;
446 
447  sofar = db_path_to_string(pathp);
448  bu_log("FAILED in triangulator: %s\n", sofar);
449  bu_free((char *)sofar, "sofar");
450 
451  /* Sometimes the NMG library adds debugging bits when
452  * it detects an internal error, before bombing out.
453  */
454  RTG.NMG_debug = NMG_debug; /* restore mode */
455 
456  /* Release any intersector 2d tables */
458 
459  /* Get rid of (m)any other intermediate structures */
460  if ((*tsp->ts_m)->magic == NMG_MODEL_MAGIC) {
461  nmg_km(*tsp->ts_m);
462  } else {
463  bu_log("WARNING: tsp->ts_m pointer corrupted, ignoring it.\n");
464  }
465 
466  /* Now, make a new, clean model structure for next pass. */
467  *tsp->ts_m = nmg_mm();
468  }
469 
470  BU_UNSETJUMP;
471 }
472 
473 
474 static union tree *
475  process_boolean(union tree *curtree, struct db_tree_state *tsp,
476  const struct db_full_path *pathp)
477 {
478  union tree *ret_tree = TREE_NULL;
479 
480  /* Begin bomb protection */
481  if (!BU_SETJUMP) {
482  /* try */
483 
484  (void)nmg_model_fuse(*tsp->ts_m, tsp->ts_tol);
485  ret_tree = nmg_booltree_evaluate(curtree, tsp->ts_tol, &rt_uniresource);
486 
487  } else {
488  /* catch */
489  char *name = db_path_to_string(pathp);
490 
491  /* Error, bail out */
492  bu_log("conversion of %s FAILED!\n", name);
493 
494  /* Sometimes the NMG library adds debugging bits when
495  * it detects an internal error, before before bombing out.
496  */
497  RTG.NMG_debug = NMG_debug;/* restore mode */
498 
499  /* Release any intersector 2d tables */
501 
502  /* Release the tree memory & input regions */
503  db_free_tree(curtree, &rt_uniresource);/* Does an nmg_kr() */
504 
505  /* Get rid of (m)any other intermediate structures */
506  if ((*tsp->ts_m)->magic == NMG_MODEL_MAGIC) {
507  nmg_km(*tsp->ts_m);
508  } else {
509  bu_log("WARNING: tsp->ts_m pointer corrupted, ignoring it.\n");
510  }
511 
512  bu_free(name, "db_path_to_string");
513  /* Now, make a new, clean model structure for next pass. */
514  *tsp->ts_m = nmg_mm();
515  }
516 
517  BU_UNSETJUMP;/* Relinquish the protection */
518 
519  return ret_tree;
520 }
521 
522 
523 /*
524  * Called from db_walk_tree().
525  *
526  * This routine must be prepared to run in parallel.
527  */
528 union tree *
529  do_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp,
530  union tree *curtree, void *UNUSED(client_data))
531 {
532  union tree *ret_tree;
533  struct bu_list vhead;
534  struct nmgregion *r;
535 
536  RT_CK_FULL_PATH(pathp);
537  RT_CK_TREE(curtree);
538  RT_CK_TESS_TOL(tsp->ts_ttol);
539  BN_CK_TOL(tsp->ts_tol);
540  NMG_CK_MODEL(*tsp->ts_m);
541 
542  BU_LIST_INIT(&vhead);
543 
544  if (RT_G_DEBUG & DEBUG_TREEWALK || verbose) {
545  char *sofar = db_path_to_string(pathp);
546  bu_log("\ndo_region_end(%d %d%%) %s\n",
547  regions_tried,
548  regions_tried > 0 ? (regions_converted * 100) / regions_tried : 0,
549  sofar);
550  bu_free(sofar, "path string");
551  }
552 
553  if (curtree->tr_op == OP_NOP)
554  return curtree;
555 
556  regions_tried++;
557 
558  ret_tree = process_boolean(curtree, tsp, pathp);
559 
560  if (ret_tree)
561  r = ret_tree->tr_d.td_r;
562  else
563  r = (struct nmgregion *)NULL;
564 
565  regions_converted++;
566 
567  if (r != 0) {
568  struct shell *s;
569  int empty_region = 0;
570  int empty_model = 0;
571 
572  /* Kill cracks */
573  s = BU_LIST_FIRST(shell, &r->s_hd);
574 
575  while (BU_LIST_NOT_HEAD(&s->l, &r->s_hd)) {
576  struct shell *next_s;
577 
578  next_s = BU_LIST_PNEXT(shell, &s->l);
579 
580  if (nmg_kill_cracks(s)) {
581  if (nmg_ks(s)) {
582  empty_region = 1;
583  break;
584  }
585  }
586 
587  s = next_s;
588  }
589 
590  /* kill zero length edgeuses */
591  if (!empty_region) {
592  empty_model = nmg_kill_zero_length_edgeuses(*tsp->ts_m);
593  }
594 
595  if (!empty_region && !empty_model) {
596  process_triangulation(r, pathp, tsp);
597 
598  regions_written++;
599 
600  BU_UNSETJUMP;
601  }
602 
603  if (!empty_model)
604  nmg_kr(r);
605  }
606 
607  /* Dispose of original tree, so that all associated dynamic memory
608  * is released now, not at the end of all regions. A return of
609  * TREE_NULL from this routine signals an error, and there is no
610  * point to adding _another_ message to our output, so we need to
611  * cons up an OP_NOP node to return.
612  */
613 
614 
615  db_free_tree(curtree, &rt_uniresource); /* Does an nmg_kr() */
616 
617  if (regions_tried > 0) {
618  float npercent;
619  float tpercent;
620 
621  npercent = (float)(regions_converted * 100) / regions_tried;
622  tpercent = (float)(regions_written * 100) / regions_tried;
623  printf("Tried %d regions; %d conv. to NMG's, %d conv. to tri.; nmgper = %.2f%%, triper = %.2f%%\n",
624  regions_tried, regions_converted, regions_written, npercent, tpercent);
625  }
626 
627  BU_ALLOC(curtree, union tree);
628  RT_TREE_INIT(curtree);
629  curtree->tr_op = OP_NOP;
630  return curtree;
631 }
632 
633 
634 /*
635  * Local Variables:
636  * mode: C
637  * tab-width: 8
638  * indent-tabs-mode: t
639  * c-file-style: "stroustrup"
640  * End:
641  * ex: shiftwidth=4 tabstop=8
642  */
#define NMG_MODEL_MAGIC
Definition: magic.h:133
char * d_namep
pointer to name string
Definition: raytrace.h:859
const struct gcv_plugin_info gcv_plugin_conv_obj_write
Definition: obj_write.c:189
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
Definition: raytrace.h:800
struct model ** ts_m
ptr to ptr to NMG "model"
Definition: raytrace.h:1072
#define NMG_EDGEUSE_MAGIC
Definition: magic.h:120
int nmg_model_fuse(struct model *m, const struct bn_tol *tol)
Definition: nmg_fuse.c:1919
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
const struct db_tree_state rt_initial_tree_state
Definition: globals.c:90
Definition: list.h:118
struct nmgregion * td_r
ptr to NMG region
Definition: raytrace.h:1168
size_t fp_len
Definition: db_fullpath.h:44
int ts_gmater
GIFT compat material code.
Definition: raytrace.h:1045
#define OP_NOP
Leaf with no effect.
Definition: raytrace.h:1132
double dist
>= 0
Definition: tol.h:73
if lu s
Definition: nmg_mod.c:3860
Definition: clone.c:90
struct bu_list rtg_vlfree
head of bn_vlist freelist
Definition: raytrace.h:1698
lu
Definition: nmg_mod.c:3855
int nmg_kr(struct nmgregion *r)
Definition: nmg_mk.c:1595
double dist_sq
dist * dist
Definition: tol.h:74
#define BN_TOL_MAGIC
Definition: magic.h:74
void rt_vlist_cleanup(void)
Definition: vlist.c:272
Header file for the BRL-CAD common definitions.
int ts_los
equivalent LOS estimate
Definition: raytrace.h:1046
Definition: gcv.c:8
int ts_aircode
GIFT compat air code.
Definition: raytrace.h:1044
#define RT_TREE_INIT(_p)
Definition: raytrace.h:1189
NMG_CK_LOOPUSE(lu)
Definition: ptbl.h:62
double rel
rel dist tol
Definition: raytrace.h:181
int nmg_ks(struct shell *s)
Definition: nmg_mk.c:1546
#define V3ARGSIN(a)
Definition: obj_write.c:46
struct resource rt_uniresource
default. Defined in librt/globals.c
Definition: globals.c:41
#define RT_G_DEBUG
Definition: raytrace.h:1718
void bu_exit(int status, const char *fmt,...) _BU_ATTR_NORETURN _BU_ATTR_PRINTF23
Definition: bomb.c:195
uint32_t NMG_debug
debug bits for NMG's see nmg.h
Definition: raytrace.h:1699
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
#define BU_PTBL_GET(ptbl, i)
Definition: ptbl.h:108
#define DB_LS_TOPS
Definition: raytrace.h:4657
#define TREE_NULL
Definition: raytrace.h:1181
#define V3ARGS(a)
Definition: color.c:56
#define RT_CK_TESS_TOL(_p)
Definition: raytrace.h:184
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
char * options
Definition: gqa.c:56
union tree * do_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, union tree *curtree, void *client_data)
Definition: obj_write.c:529
#define BN_TOL_DIST
Definition: tol.h:109
#define BU_LIST_PNEXT(structure, p)
Definition: list.h:422
#define UNUSED(parameter)
Definition: common.h:239
int nmg_kill_zero_length_edgeuses(struct model *m)
Definition: nmg_misc.c:8351
void nmg_triangulate_model(struct model *m, const struct bn_tol *tol)
Definition: nmg_tri.c:3818
Support for uniform tolerances.
Definition: tol.h:71
#define BN_CK_TOL(_p)
Definition: tol.h:82
#define BU_LIST_FIRST_MAGIC(hp)
Definition: list.h:416
struct directory ** fp_names
array of dir pointers
Definition: db_fullpath.h:46
char * db_path_to_string(const struct db_full_path *pp)
Definition: db_fullpath.c:191
struct tree::tree_nmgregion tr_d
size_t db_ls(const struct db_i *dbip, int flags, const char *pattern, struct directory ***dpv)
Definition: ls.c:58
int bu_ptbl_locate(const struct bu_ptbl *b, const long *p)
#define BU_PTBL_LEN(ptbl)
Definition: ptbl.h:107
void bu_ptbl_free(struct bu_ptbl *b)
Definition: ptbl.c:226
#define RT_CK_FULL_PATH(_p)
Definition: db_fullpath.h:59
struct model * nmg_mm(void)
Definition: nmg_mk.c:235
char ** db_dpv_to_argv(struct directory **dpv)
Definition: ls.c:123
double perp
nearly 0
Definition: tol.h:75
uint32_t magic
Definition: raytrace.h:179
#define BU_LIST_INIT(_hp)
Definition: list.h:148
void nmg_isect2d_final_cleanup(void)
Definition: nmg_inter.c:647
int nmg_kill_cracks(struct shell *s)
Definition: nmg_misc.c:8187
uint32_t magic
Definition: tol.h:72
#define BU_PTBL_END(ptbl)
Definition: ptbl.h:106
const struct rt_tess_tol * ts_ttol
Tessellation tolerance.
Definition: raytrace.h:1070
double abs
absolute dist tol
Definition: raytrace.h:180
#define BU_UNSETJUMP
Definition: parallel.h:193
#define NMG_VERTEXUSE_A_PLANE_MAGIC
Definition: magic.h:144
double norm
normal tol
Definition: raytrace.h:182
union tree * nmg_booltree_evaluate(register union tree *tp, const struct bn_tol *tol, struct resource *resp)
Definition: nmg_bool.c:1307
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
#define RT_CK_TREE(_p)
Definition: raytrace.h:1182
#define RT_TESS_TOL_MAGIC
Definition: magic.h:170
int ts_regionid
GIFT compat region ID code.
Definition: raytrace.h:1043
#define BU_SETJUMP
Definition: parallel.h:192
NMG_CK_SHELL(s)
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
HIDDEN void verbose(struct human_data_t *dude)
Definition: human.c:2008
void db_update_nref(struct db_i *dbip, struct resource *resp)
Definition: db_match.c:75
const struct bn_tol * ts_tol
Math tolerance.
Definition: raytrace.h:1071
#define BU_LIST_NOT_HEAD(p, hp)
Definition: list.h:324
double para
nearly 1
Definition: tol.h:76
#define BU_LIST_FIRST(structure, hp)
Definition: list.h:312
void nmg_vertex_tabulate(struct bu_ptbl *tab, const uint32_t *magic_p)
Definition: nmg_info.c:1985
void nmg_vertexuse_normal_tabulate(struct bu_ptbl *tab, const uint32_t *magic_p)
Definition: nmg_info.c:2038
struct rt_g RTG
Definition: globals.c:39