BRL-CAD
bottess.c
Go to the documentation of this file.
1 /* B O T T E S S . 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 
21 /** @file libgcv/region_end.c
22  *
23  * Generate a tree of resolved BoT's, one per region. Roughly based
24  * on UnBBoolean's j3dbool (and associated papers).
25  *
26  */
27 
28 #include "common.h"
29 
30 #include <math.h> /* ceil */
31 #include <string.h> /* memcpy */
32 
33 #include "bn.h"
34 #include "raytrace.h"
35 #include "nmg.h"
36 #include "gcv.h"
37 
38 #include "./soup.h"
39 #include "./tri_intersect.h"
40 
41 
42 /* assume 4096, seems common enough. a portable way to get to PAGE_SIZE might be
43  * better. */
44 const int faces_per_page = 4096 / sizeof(struct face_s);
45 
46 
47 int
48 soup_rm_face(struct soup_s *s, unsigned long int i)
49 {
50  if (i>=s->nfaces) {
51  bu_log("trying to remove a nonexistent face? %lu/%lu\n", i, s->nfaces);
52  bu_bomb("Asploding\n");
53  }
54  memcpy(&s->faces[i], &s->faces[s->nfaces-1], sizeof(struct face_s));
55  return s->nfaces--;
56 }
57 
58 
59 int
60 soup_add_face_precomputed(struct soup_s *s, point_t a, point_t b , point_t c, plane_t d, uint32_t foo)
61 {
62  struct face_s *f;
63  vect_t e1, e2, x;
64 
65  VSUB2(e1, b, a);
66  VSUB2(e2, c, a);
67  VCROSS(x, e1, e2);
68 
69  /* grow face array if needed */
70  if (s->nfaces >= s->maxfaces)
71  s->faces = (struct face_s *)bu_realloc(s->faces, (s->maxfaces += faces_per_page) * sizeof(struct face_s), "bot soup faces");
72  f = s->faces + s->nfaces;
73 
74  VMOVE(f->vert[0], a);
75  if (VDOT(x, d) <= 0) {
76  VMOVE(f->vert[1], b);
77  VMOVE(f->vert[2], c);
78  } else {
79  VMOVE(f->vert[1], c);
80  VMOVE(f->vert[2], b);
81  }
82 
83  HMOVE(f->plane, d);
84 
85  /* solve the bounding box (should this be VMINMAX?) */
86  VMOVE(f->min, f->vert[0]); VMOVE(f->max, f->vert[0]);
87  VMIN(f->min, f->vert[1]); VMAX(f->max, f->vert[1]);
88  VMIN(f->min, f->vert[2]); VMAX(f->max, f->vert[2]);
89  /* fluff the bounding box for fp fuzz */
90  f->min[X]-=.1; f->min[Y]-=.1; f->min[Z]-=.1;
91  f->max[X]+=.1; f->max[Y]+=.1; f->max[Z]+=.1;
92 
93  f->foo = foo;
94 
95  s->nfaces++;
96  return 0;
97 }
98 
99 
100 int
101 soup_add_face(struct soup_s *s, point_t a, point_t b, point_t c, const struct bn_tol *tol) {
102  plane_t p;
103 
104  /* solve the plane */
105  bn_mk_plane_3pts(p, a, b, c, tol);
106 
107  return soup_add_face_precomputed(s, a, b, c, p, OUTSIDE);
108 }
109 
110 
111 long int splitz = 0;
112 long int splitty = 0;
113 
114 int
115 split_face_single(struct soup_s *s, unsigned long int fid, point_t isectpt[2], struct face_s *opp_face, const struct bn_tol *tol)
116 {
117  struct face_s *f = s->faces+fid;
118  int a, i, j, isv[2] = {0, 0};
119 
120 #define VERT_INT 0x10
121 #define LINE_INT 0x20
122 #define FACE_INT 0x40
123 #define ALL_INT (VERT_INT|LINE_INT|FACE_INT)
124 
125  /****** START hoistable ******/
126  for (i=0;i<2;i++) for (j=0;j<3;j++) {
127  if (isv[i] == 0) {
128  fastf_t dist;
129 
130  switch ( bn_isect_pt_lseg( &dist, (fastf_t *)&f->vert[j], (fastf_t *)&f->vert[j==2?0:j+1], (fastf_t *)&isectpt[i], tol) ) {
131  case -2: case -1: continue;
132  case 1: isv[i] = VERT_INT|j; break;
133  case 2: isv[i] = VERT_INT|(j==2?0:j+1); break;
134  case 3: isv[i] = LINE_INT|j; break;
135  default: bu_log("Whu?\n"); break;
136  }
137  }
138  }
139 
140  /*** test if intersect is middle of face ***/
141  for (i=0;i<2;i++)
142  /* test for face in plane */
143  if (isv[i] == 0) /* assume that the isectpt is necessarily on the vert, line or
144  face... if it's not seen on the vert or line, it must be face.
145  This should probably be a real check. */
146  isv[i] = FACE_INT;
147 
148  if (isv[0] == 0 || isv[1] == 0) {
149  bu_log("Something real bad %x %x\n", isv[0], isv[1]);
150  return -1;
151  }
152 
153  if ((isv[0]&ALL_INT) > (isv[1]&ALL_INT)) {
154  int tmpi;
155  point_t tmpp;
156  VMOVE(tmpp, isectpt[0]);
157  VMOVE(isectpt[0], isectpt[1]);
158  VMOVE(isectpt[1], tmpp);
159  tmpi = isv[0];
160  isv[0]=isv[1];
161  isv[1]=tmpi;
162  }
163 
164  /****** END hoistable ******/
165 
166  /* test if both ends of the intersect line are on vertices */
167  /* if VERT+VERT, abort */
168  if ((isv[0]&VERT_INT) && (isv[1]&VERT_INT)) {
169  return 1;
170  }
171 
172  a = isv[0]&~ALL_INT;
173  if ( a != 0 && a != 1 && a != 2) {
174  bu_log("Bad a value: %d\n", a);
175  bu_bomb("Exploding\n");
176  }
177  /* if VERT+LINE, break into 2 */
178  if (isv[0]&VERT_INT && isv[1]&LINE_INT) {
179  vect_t muh;
180  int meh;
181 
182  VSUB2(muh, isectpt[1], f->vert[a==2?0:a+1]);
183  meh = VDOT(opp_face->plane, muh) > 0;
184  soup_add_face_precomputed(s, f->vert[a], isectpt[1], f->vert[a==2?0:a+1], f->plane, meh == 1 ? OUTSIDE : INSIDE);
185  soup_add_face_precomputed(s, f->vert[a], f->vert[a==0?2:a-1], isectpt[1], f->plane, meh == 1 ? INSIDE : OUTSIDE);
186 
187  soup_rm_face(s, fid);
188  return 2;
189  }
190 
191  /* if LINE+LINE, break into 3, figure out which side has two verts and cut * that */
192  if (isv[0]&LINE_INT && isv[1]&LINE_INT) {
193  return 1;
194  }
195 
196  /* if VERT+FACE, break into 3, intersect is one line, other two to the * opposing verts */
197  if (isv[0]&VERT_INT ) {
198  soup_add_face_precomputed(s, f->vert[0], f->vert[1], isectpt[1], f->plane, 0);
199  soup_add_face_precomputed(s, f->vert[1], f->vert[2], isectpt[1], f->plane, 0);
200  soup_add_face_precomputed(s, f->vert[2], f->vert[0], isectpt[1], f->plane, 0);
201  soup_rm_face(s, fid);
202  return 3;
203  }
204 
205  /* if LINE+FACE, break into 4 */
206  if (isv[0]&LINE_INT ) {
207  soup_add_face_precomputed(s, f->vert[a], isectpt[0], isectpt[1], f->plane, 0);
208  soup_add_face_precomputed(s, f->vert[a==2?0:a+1], isectpt[1], isectpt[0], f->plane, 0);
209  soup_add_face_precomputed(s, f->vert[a==2?0:a+1], f->vert[a==0?2:a-1], isectpt[1], f->plane, 0);
210  soup_add_face_precomputed(s, f->vert[a], isectpt[1], f->vert[a==0?2:a-1], f->plane, 0);
211  soup_rm_face(s, fid);
212  return 4;
213  }
214 
215  /* if FACE+FACE, break into 3 */
216  if (isv[0]&FACE_INT ) {
217  /* extend intersect line to triangle edges, could be 2 or 3? */
218 
219  /* make sure isectpt[0] is closest to vert[0] */
220  if (DIST_PT_PT_SQ(f->vert[0], isectpt[0]) > DIST_PT_PT_SQ(f->vert[0], isectpt[1])) {
221  point_t tmp;
222  VMOVE(tmp, isectpt[1]);
223  VMOVE(isectpt[1], isectpt[0]);
224  VMOVE(isectpt[0], tmp);
225  }
226 
227  soup_add_face_precomputed(s, f->vert[0], isectpt[0], f->vert[2], f->plane, 0);
228  soup_add_face_precomputed(s, f->vert[0], f->vert[1], isectpt[0], f->plane, 0);
229  soup_add_face_precomputed(s, f->vert[1], isectpt[1], isectpt[0], f->plane, 0);
230  soup_add_face_precomputed(s, f->vert[2], isectpt[0], isectpt[1], f->plane, 0);
231  soup_add_face_precomputed(s, f->vert[1], f->vert[2], isectpt[1], f->plane, 0);
232  return 5;
233  }
234 #undef VERT_INT
235 #undef LINE_INT
236 #undef ALL_INT
237 #undef FACE_INT
238  /* this should never be reached */
239  bu_log("derp?\n");
240 
241  return 0;
242 }
243 
244 
245 /* returns 0 to continue, 1 if the left face was split, 2 if the right face was
246  * split */
247 int
248 split_face(struct soup_s *left, unsigned long int left_face, struct soup_s *right, unsigned long int right_face, const struct bn_tol *tol) {
249  struct face_s *lf, *rf;
250  vect_t isectpt[2] = {{0, 0, 0}, {0, 0, 0}};
251  int coplanar, r = 0;
252 
253  lf = left->faces+left_face;
254  rf = right->faces+right_face;
255 
256  splitz++;
257  if (gcv_tri_tri_intersect_with_isectline(left, right, lf, rf, &coplanar, (point_t *)isectpt, tol) != 0 && !VNEAR_EQUAL(isectpt[0], isectpt[1], tol->dist)) {
258  splitty++;
259 
260  if (split_face_single(left, left_face, isectpt, &right->faces[right_face], tol) > 1) r|=0x1;
261  if (split_face_single(right, right_face, isectpt, &left->faces[left_face], tol) > 1) r|=0x2;
262  }
263 
264  return r;
265 }
266 
267 
268 struct soup_s *
269 bot2soup(struct rt_bot_internal *bot, const struct bn_tol *tol)
270 {
271  struct soup_s *s;
272  unsigned long int i;
273 
274  RT_BOT_CK_MAGIC(bot);
275 
276  if (bot->orientation != RT_BOT_CCW)
277  bu_bomb("Bad orientation out of nmg_bot\n");
278 
279  BU_ALLOC(s, struct soup_s);
280  s->magic = SOUP_MAGIC;
281  s->nfaces = 0;
282  s->maxfaces = ceil(bot->num_faces / (double)faces_per_page) * faces_per_page;
283  s->faces = (struct face_s *)bu_malloc(sizeof(struct face_s) * s->maxfaces, "bot soup faces");
284 
285  for (i=0;i<bot->num_faces;i++)
286  soup_add_face(s, bot->vertices+3*bot->faces[i*3+0], bot->vertices+3*bot->faces[i*3+1], bot->vertices+3*bot->faces[i*3+2], tol);
287 
288  return s;
289 }
290 
291 
292 void
293 free_soup(struct soup_s *s) {
294  if (s == NULL)
295  bu_bomb("null soup");
296  if (s->faces)
297  bu_free(s->faces, "bot soup faces");
298  bu_free(s, "bot soup");
299  return;
300 }
301 
302 
303 union tree *
304 invert(union tree *tree)
305 {
306  struct soup_s *s;
307  unsigned long int i;
308 
309  RT_CK_TREE(tree);
310  if (tree->tr_op != OP_NMG_TESS) {
311  bu_log("Erm, this isn't an nmg tess\n");
312  return tree;
313  }
314  s = (struct soup_s *)tree->tr_d.td_r->m_p;
315  SOUP_CKMAG(s);
316 
317  for (i=0;i<s->nfaces;i++) {
318  struct face_s *f = s->faces+i;
319  point_t t;
320  VMOVE(t, f->vert[0]);
321  VMOVE(f->vert[0], f->vert[1]);
322  VMOVE(f->vert[0], t);
323  /* flip the inverted bit. */
324  f->foo^=INVERTED;
325  }
326 
327  return tree;
328 }
329 
330 
331 void
332 split_faces(union tree *left_tree, union tree *right_tree, const struct bn_tol *tol)
333 {
334  struct soup_s *l, *r;
335  unsigned long int i, j;
336 
337  RT_CK_TREE(left_tree);
338  RT_CK_TREE(right_tree);
339  l = (struct soup_s *)left_tree->tr_d.td_r->m_p;
340  r = (struct soup_s *)right_tree->tr_d.td_r->m_p;
341  SOUP_CKMAG(l);
342  SOUP_CKMAG(r);
343 
344  /* this is going to be big and hairy. Has to walk both meshes finding
345  * all intersections and split intersecting faces so there are edges at
346  * the intersections. Initially going to be O(n^2), then change to use
347  * space partitioning (binning? octree? kd?). */
348  for (i=0;i<l->nfaces;i++) {
349  struct face_s *lf = l->faces+i, *rf = NULL;
350  int ret;
351 
352  for (j=0;j<r->nfaces;j++) {
353  rf = r->faces+j;
354  /* quick bounding box test */
355  if (lf->min[X]>rf->max[X] || lf->max[X]>lf->max[X] ||
356  lf->min[Y]>rf->max[Y] || lf->max[Y]>lf->max[Y] ||
357  lf->min[Z]>rf->max[Z] || lf->max[Z]>lf->max[Z])
358  continue;
359  /* two possibly overlapping faces found */
360  ret = split_face(l, i, r, j, tol);
361  if (ret&0x1) i--;
362  if (ret&0x2) j--;
363  }
364  }
365 }
366 
367 
368 union tree *
369 compose(union tree *left_tree, union tree *right_tree, unsigned long int UNUSED(face_status1), unsigned long int UNUSED(face_status2), unsigned long int UNUSED(face_status3))
370 {
371  struct soup_s *l, *r;
372  int i;
373 
374  RT_CK_TREE(left_tree);
375  RT_CK_TREE(right_tree);
376  l = (struct soup_s *)left_tree->tr_d.td_r->m_p;
377  r = (struct soup_s *)right_tree->tr_d.td_r->m_p;
378  printf("Composing! %lu %lu\n", l->nfaces, r->nfaces);
379 
380  bu_log("solid /left\n");
381  for (i=0; i < (int)l->nfaces; i++) {
382  bu_log(" facet normal %f %f %f\n", V3ARGS(l->faces[i].plane));
383  bu_log(" outer loop\n");
384  bu_log(" vertex %f %f %f\n", V3ARGS(l->faces[i].vert[0]));
385  bu_log(" vertex %f %f %f\n", V3ARGS(l->faces[i].vert[1]));
386  bu_log(" vertex %f %f %f\n", V3ARGS(l->faces[i].vert[2]));
387  bu_log(" endloop\n");
388  bu_log(" endfacet\n");
389  }
390  bu_log("endsolid /left\n");
391 
392  bu_log("solid /right\n");
393  for (i=0; i < (int)r->nfaces; i++) {
394  bu_log(" facet normal %f %f %f\n", V3ARGS(r->faces[i].plane));
395  bu_log(" outer loop\n");
396  bu_log(" vertex %f %f %f\n", V3ARGS(r->faces[i].vert[0]));
397  bu_log(" vertex %f %f %f\n", V3ARGS(r->faces[i].vert[1]));
398  bu_log(" vertex %f %f %f\n", V3ARGS(r->faces[i].vert[2]));
399  bu_log(" endloop\n");
400  bu_log(" endfacet\n");
401  }
402  bu_log("endsolid /right\n");
403  return left_tree;
404 
405 }
406 
407 
408 union tree *
409 evaluate(union tree *tr, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
410 {
411  RT_CK_TREE(tr);
412 
413  switch (tr->tr_op) {
414  case OP_NOP:
415  return tr;
416  case OP_NMG_TESS:
417  /* ugh, keep it as nmg_tess and just shove the rt_bot_internal ptr
418  * in as nmgregion. :/ Also, only doing the first shell of the first
419  * model. Primitives should only provide a single shell, right? */
420  {
421  struct rt_db_internal ip;
422  struct nmgregion *nmgr = BU_LIST_FIRST(nmgregion, &tr->tr_d.td_r->m_p->r_hd);
423  /* the bot temporary format may be unnecessary if we can walk
424  * the nmg shells and generate soup from them directly. */
425  struct rt_bot_internal *bot = nmg_bot(BU_LIST_FIRST(shell, &nmgr->s_hd), tol);
426 
427  /* causes a crash.
428  nmg_kr(nmgr);
429  free(nmgr);
430  */
431 
432  tr->tr_d.td_r->m_p = (struct model *)bot2soup(bot, tol);
433  SOUP_CKMAG((struct soup_s *)tr->tr_d.td_r->m_p);
434 
435  /* fill in a db_internal with our new bot so we can free it */
436  RT_DB_INTERNAL_INIT(&ip);
437  ip.idb_major_type = DB5_MAJORTYPE_BRLCAD;
438  ip.idb_minor_type = ID_BOT;
439  ip.idb_meth = &OBJ[ID_BOT];
440  ip.idb_ptr = bot;
441  ip.idb_meth->ft_ifree(&ip);
442  }
443  return tr;
444  case OP_UNION:
445  case OP_INTERSECT:
446  case OP_SUBTRACT:
447  RT_CK_TREE(tr->tr_b.tb_left);
448  RT_CK_TREE(tr->tr_b.tb_right);
449  tr->tr_b.tb_left = evaluate(tr->tr_b.tb_left, ttol, tol);
450  tr->tr_b.tb_right = evaluate(tr->tr_b.tb_right, ttol, tol);
451  RT_CK_TREE(tr->tr_b.tb_left);
452  RT_CK_TREE(tr->tr_b.tb_right);
453  SOUP_CKMAG(tr->tr_b.tb_left->tr_d.td_r->m_p);
454  SOUP_CKMAG(tr->tr_b.tb_right->tr_d.td_r->m_p);
455  split_faces(tr->tr_b.tb_left, tr->tr_b.tb_right, tol);
456  RT_CK_TREE(tr->tr_b.tb_left);
457  RT_CK_TREE(tr->tr_b.tb_right);
458  SOUP_CKMAG(tr->tr_b.tb_left->tr_d.td_r->m_p);
459  SOUP_CKMAG(tr->tr_b.tb_right->tr_d.td_r->m_p);
460  break;
461  default:
462  bu_bomb("bottess evaluate(): bad op (first pass)\n");
463  }
464 
465  switch (tr->tr_op) {
466  case OP_UNION:
467  return compose(tr->tr_b.tb_left, tr->tr_b.tb_right, OUTSIDE, SAME, OUTSIDE);
468  case OP_INTERSECT:
469  return compose(tr->tr_b.tb_left, tr->tr_b.tb_right, INSIDE, SAME, INSIDE);
470  case OP_SUBTRACT:
472  default:
473  bu_bomb("bottess evaluate(): bad op (second pass, CSG)\n");
474  }
475  bu_bomb("Got somewhere I shouldn't have\n");
476  return NULL;
477 }
478 
479 
480 long int lsplitz=0;
481 long int lsplitty=0;
482 
483 union tree *
484 gcv_bottess_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, union tree *curtree, void *UNUSED(client_data))
485 {
486  union tree *ret_tree = TREE_NULL;
487 
488  if (!tsp || !curtree || !pathp) {
489  bu_log("INTERNAL ERROR: gcv_region_end missing parameters\n");
490  return TREE_NULL;
491  }
492 
493  RT_CK_FULL_PATH(pathp);
494  RT_CK_TREE(curtree);
495  RT_CK_TESS_TOL(tsp->ts_ttol);
496  BN_CK_TOL(tsp->ts_tol);
497  NMG_CK_MODEL(*tsp->ts_m);
498 
499  splitz=0;
500  splitty=0;
501 
502  RT_CK_FULL_PATH(pathp);
503  RT_CK_TREE(curtree);
504  RT_CK_TESS_TOL(tsp->ts_ttol);
505  BN_CK_TOL(tsp->ts_tol);
506  NMG_CK_MODEL(*tsp->ts_m);
507 
508  if (curtree->tr_op == OP_NOP)
509  return curtree;
510 
511  ret_tree = evaluate(curtree, tsp->ts_ttol, tsp->ts_tol);
512 
513  lsplitz+=splitz;
514  lsplitz+=splitz;
515  lsplitty+=splitty;
516  splitz=0;
517  splitty=0;
518 
519  return ret_tree;
520 }
521 
522 
523 union tree *
524 gcv_bottess(int argc, const char **argv, struct db_i *dbip, struct rt_tess_tol *ttol)
525 {
526  struct db_tree_state tree_state = rt_initial_tree_state;
527  tree_state.ts_ttol = ttol;
528 
529  if (db_walk_tree(dbip, argc, argv, 1, &tree_state, NULL, gcv_bottess_region_end, nmg_booltree_leaf_tess, NULL) < 0)
530  bu_log("gcv_bottess: db_walk_tree failure\n");
531 
532  return NULL;
533 }
534 
535 
536 /*
537  * Local Variables:
538  * tab-width: 8
539  * mode: C
540  * indent-tabs-mode: t
541  * c-file-style: "stroustrup"
542  * End:
543  * ex: shiftwidth=4 tabstop=8
544  */
Definition: raytrace.h:800
struct model ** ts_m
ptr to ptr to NMG "model"
Definition: raytrace.h:1072
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
#define FACE_INT
const struct db_tree_state rt_initial_tree_state
Definition: globals.c:90
struct rt_bot_internal * nmg_bot(struct shell *s, const struct bn_tol *tol)
Definition: nmg_misc.c:10826
struct soup_s * bot2soup(struct rt_bot_internal *bot, const struct bn_tol *tol)
Definition: bottess.c:269
#define INVERTED
Definition: soup.h:38
struct nmgregion * td_r
ptr to NMG region
Definition: raytrace.h:1168
int bn_isect_pt_lseg(fastf_t *dist, const point_t a, const point_t b, const point_t p, const struct bn_tol *tol)
Intersect a point P with the line segment defined by two distinct points A and B. ...
#define OUTSIDE
Definition: nmg_class.c:59
void free_soup(struct soup_s *s)
Definition: bottess.c:293
#define OP_NOP
Leaf with no effect.
Definition: raytrace.h:1132
double dist
>= 0
Definition: tol.h:73
void(* ft_ifree)(struct rt_db_internal *)
Definition: raytrace.h:2159
union tree * evaluate(union tree *tr, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
Definition: bottess.c:409
if lu s
Definition: nmg_mod.c:3860
#define OP_NMG_TESS
Leaf: tr_stp -> nmgregion.
Definition: raytrace.h:1137
point_t vert[3]
Definition: soup.h:44
#define ID_BOT
Bag o' triangles.
Definition: raytrace.h:488
#define VERT_INT
#define SAME
Definition: soup.h:36
union tree * invert(union tree *tree)
Definition: bottess.c:304
point_t min
Definition: soup.h:44
Header file for the BRL-CAD common definitions.
union tree * gcv_bottess_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, union tree *curtree, void *client_data)
Definition: bottess.c:484
int soup_rm_face(struct soup_s *s, unsigned long int i)
Definition: bottess.c:48
Definition: soup.h:43
#define SOUP_MAGIC
Definition: soup.h:40
union tree * compose(union tree *left_tree, union tree *right_tree, unsigned long int face_status1, unsigned long int face_status2, unsigned long int face_status3)
Definition: bottess.c:369
long int splitz
Definition: bottess.c:111
union tree * tb_left
Definition: raytrace.h:1149
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
#define OPPOSITE
Definition: soup.h:37
uint32_t magic
Definition: soup.h:50
int idb_major_type
Definition: raytrace.h:192
#define OP_SUBTRACT
Binary: L subtract R.
Definition: raytrace.h:1129
Definition: color.c:49
#define OP_INTERSECT
Binary: L intersect R.
Definition: raytrace.h:1128
int split_face(struct soup_s *left, unsigned long int left_face, struct soup_s *right, unsigned long int right_face, const struct bn_tol *tol)
Definition: bottess.c:248
#define ALL_INT
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
long int splitty
Definition: bottess.c:112
#define RT_DB_INTERNAL_INIT(_p)
Definition: raytrace.h:199
plane_t plane
Definition: soup.h:45
const struct rt_functab * idb_meth
for ft_ifree(), etc.
Definition: raytrace.h:194
#define TREE_NULL
Definition: raytrace.h:1181
#define V3ARGS(a)
Definition: color.c:56
#define RT_CK_TESS_TOL(_p)
Definition: raytrace.h:184
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
const int faces_per_page
Definition: bottess.c:44
struct tree::tree_node tr_b
void * bu_realloc(void *ptr, size_t siz, const char *str)
long int lsplitty
Definition: bottess.c:481
#define UNUSED(parameter)
Definition: common.h:239
Support for uniform tolerances.
Definition: tol.h:71
#define BN_CK_TOL(_p)
Definition: tol.h:82
int soup_add_face_precomputed(struct soup_s *s, point_t a, point_t b, point_t c, plane_t d, uint32_t foo)
Definition: bottess.c:60
struct tree::tree_nmgregion tr_d
#define RT_CK_FULL_PATH(_p)
Definition: db_fullpath.h:59
union tree * tb_right
Definition: raytrace.h:1150
void * idb_ptr
Definition: raytrace.h:195
#define INSIDE
Definition: nmg_class.c:57
const struct rt_functab OBJ[]
Definition: table.c:159
const struct rt_tess_tol * ts_ttol
Tessellation tolerance.
Definition: raytrace.h:1070
point_t max
Definition: soup.h:44
union tree * gcv_bottess(int argc, const char **argv, struct db_i *dbip, struct rt_tess_tol *ttol)
Definition: bottess.c:524
int idb_minor_type
ID_xxx.
Definition: raytrace.h:193
uint32_t foo
Definition: soup.h:46
Definition: color.c:51
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
#define RT_CK_TREE(_p)
Definition: raytrace.h:1182
int split_face_single(struct soup_s *s, unsigned long int fid, point_t isectpt[2], struct face_s *opp_face, const struct bn_tol *tol)
Definition: bottess.c:115
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 SOUP_CKMAG(_ptr)
Definition: soup.h:41
int gcv_tri_tri_intersect_with_isectline(struct soup_s *left, struct soup_s *right, struct face_s *lf, struct face_s *rf, int *coplanar, point_t *isectpt, const struct bn_tol *tol)
struct face_s * faces
Definition: soup.h:51
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
const struct bn_tol * ts_tol
Math tolerance.
Definition: raytrace.h:1071
#define LINE_INT
double fastf_t
Definition: defines.h:300
#define OP_UNION
Binary: L union R.
Definition: raytrace.h:1127
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)
void split_faces(union tree *left_tree, union tree *right_tree, const struct bn_tol *tol)
Definition: bottess.c:332
long int lsplitz
Definition: bottess.c:480
unsigned long int maxfaces
Definition: soup.h:52
Definition: soup.h:49
unsigned long int nfaces
Definition: soup.h:52
Definition: color.c:50
#define BU_LIST_FIRST(structure, hp)
Definition: list.h:312
int soup_add_face(struct soup_s *s, point_t a, point_t b, point_t c, const struct bn_tol *tol)
Definition: bottess.c:101