BRL-CAD
nmg_ck.c
Go to the documentation of this file.
1 /* N M G _ C K . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1993-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 /** @addtogroup nmg */
21 /** @{ */
22 /** @file primitives/nmg/nmg_ck.c
23  *
24  * Validators and consistency checkers for NMG data structures.
25  *
26  */
27 /** @} */
28 
29 #include "common.h"
30 
31 #include <stddef.h>
32 #include <string.h>
33 #include "bio.h"
34 
35 #include "vmath.h"
36 #include "nmg.h"
37 #include "raytrace.h"
38 
39 
40 /************************************************************************
41  * *
42  * Validator Routines *
43  * *
44  ************************************************************************/
45 
46 /**
47  * Verify vertex geometry
48  */
49 void
50 nmg_vvg(const struct vertex_g *vg)
51 {
52  NMG_CK_VERTEX_G(vg);
53 }
54 
55 
56 /**
57  * Verify a vertex
58  */
59 void
60 nmg_vvertex(const struct vertex *v, const struct vertexuse *vup)
61 {
62  struct vertexuse *vu;
63  int vup_is_in_list = 0;
64 
65  NMG_CK_VERTEX(v);
66 
67  for (BU_LIST_FOR(vu, vertexuse, &v->vu_hd)) {
68  NMG_CK_VERTEXUSE(vu);
69  if (vu->v_p != v)
70  bu_bomb("nmg_vvertex() a vertexuse in my list doesn't share my vertex\n");
71  if (vu == vup)
72  vup_is_in_list = 1;
73  }
74  if (v->vg_p) nmg_vvg(v->vg_p);
75  if (! vup_is_in_list)
76  bu_bomb("nmg_vvertex() vup not found in list of vertexuses\n");
77 }
78 
79 
80 /* Verify vertex attributes */
81 void
82 nmg_vvua(const uint32_t *vua)
83 {
84  NMG_CK_VERTEXUSE_A_EITHER(vua);
85 }
86 
87 
88 /**
89  * Verify vertexuse
90  */
91 void
92 nmg_vvu(const struct vertexuse *vu, const uint32_t *up_magic_p)
93 {
94  uint32_t magic;
95 
96  NMG_CK_VERTEXUSE(vu);
97  if (vu->up.magic_p != up_magic_p) {
98  bu_log("nmg_vvu() up is %s, s/b %s\n",
99  bu_identify_magic(*vu->up.magic_p),
100  bu_identify_magic(*up_magic_p));
101  bu_bomb("nmg_vvu() vertexuse denies parent\n");
102  }
103 
104  if (!vu->l.forw)
105  bu_bomb("nmg_vvu() vertexuse has null forw pointer\n");
106 
107  magic = BU_LIST_FIRST_MAGIC(&vu->l);
108  if (magic != NMG_VERTEXUSE_MAGIC && magic != BU_LIST_HEAD_MAGIC)
109  bu_bomb("nmg_vvu() vertexuse forw is bad vertexuse\n");
110 
111  if (BU_LIST_PNEXT_PLAST(vertexuse, vu) != vu)
112  bu_bomb("nmg_vvu() vertexuse not back of next vertexuse\n");
113 
114  nmg_vvertex(vu->v_p, vu);
115 
116  if (vu->a.magic_p) nmg_vvua(vu->a.magic_p);
117 }
118 
119 
120 /* Verify edge geometry */
121 void
122 nmg_veg(const uint32_t *eg)
123 {
124  struct bu_list *eu2;
125 
126  NMG_CK_EDGE_G_EITHER(eg);
127  switch (*eg) {
129  bu_ck_list_magic(&((struct edge_g_lseg *)eg)->eu_hd2,
130  "nmg_veg() edge_g_lseg eu_hd2 list",
132  break;
134  bu_ck_list_magic(&((struct edge_g_cnurb *)eg)->eu_hd2,
135  "nmg_veg() edge_g_cnurb eu_hd2 list",
137  break;
138  }
139 
140  /* Ensure that all edgeuses on the edge_g_* list point to me */
141  for (BU_LIST_FOR(eu2, bu_list, &((struct edge_g_lseg *)eg)->eu_hd2)) {
142  struct edgeuse *eu;
143 
144  eu = BU_LIST_MAIN_PTR(edgeuse, eu2, l2);
145  NMG_CK_EDGEUSE(eu);
146  if (eu->g.magic_p == eg) continue;
147  bu_log("eg=%p, eu=%p, eu->g=%p\n", (void *)eg, (void *)eu, (void *)eu->g.magic_p);
148  bu_log("nmg_veg() edgeuse is on wrong eu_hd2 list for eu->g\n");
149  }
150 }
151 
152 
153 /**
154  * Verify edge
155  */
156 void
157 nmg_vedge(const struct edge *e, const struct edgeuse *eup)
158 {
159  const struct edgeuse *eu;
160  int is_use = 0; /* flag: eup is in edge's use list */
161 
162  NMG_CK_EDGE(e);
163  NMG_CK_EDGEUSE(eup);
164  NMG_CK_VERTEXUSE(eup->vu_p);
165  NMG_CK_VERTEX(eup->vu_p->v_p);
166  NMG_CK_EDGEUSE(eup->eumate_p);
167  NMG_CK_VERTEXUSE(eup->eumate_p->vu_p);
168  NMG_CK_VERTEX(eup->eumate_p->vu_p->v_p);
169 
170  if (!e->eu_p) bu_bomb("nmg_vedge() edge has null edgeuse pointer\n");
171 
172  NMG_CK_EDGEUSE(e->eu_p);
173 
174  eu = eup;
175  do {
176  NMG_CK_EDGEUSE(eu);
177  NMG_CK_EDGEUSE(eu->eumate_p);
178  if (eu == eup || eu->eumate_p == eup)
179  is_use = 1;
180 
181  NMG_CK_VERTEXUSE(eu->vu_p);
182  NMG_CK_VERTEX(eu->vu_p->v_p);
183  if (eu->vu_p->v_p == eup->vu_p->v_p) {
184  if (eu->eumate_p->vu_p->v_p != eup->eumate_p->vu_p->v_p) {
185  bu_log("nmg_vedge() edgeuse mate does not have correct vertex\n");
186  bu_log("(eu=%p, eu->vu_p->v_p=%p, eu->eumate_p->vu_p->v_p=%p)\n",
187  (void *)eu, (void *)eu->vu_p->v_p, (void *)eu->eumate_p->vu_p->v_p);
188  bu_log("(eup=%p, eup->vu_p->v_p=%p, eup->eumate_p->vu_p->v_p=%p)\n",
189  (void *)eup, (void *)eup->vu_p->v_p, (void *)eup->eumate_p->vu_p->v_p);
190  bu_bomb("nmg_vedge() edgeuse mate does not have correct vertex\n");
191  }
192  } else if (eu->vu_p->v_p == eup->eumate_p->vu_p->v_p) {
193  if (eu->eumate_p->vu_p->v_p != eup->vu_p->v_p) {
194  bu_log("nmg_vedge() edgeuse does not have correct vertex\n");
195  bu_log("(eu=%p, eu->vu_p->v_p=%p, eu->eumate_p->vu_p->v_p=%p)\n",
196  (void *)eu, (void *)eu->vu_p->v_p, (void *)eu->eumate_p->vu_p->v_p);
197  bu_log("(eup=%p, eup->vu_p->v_p=%p, eup->eumate_p->vu_p->v_p=%p)\n",
198  (void *)eup, (void *)eup->vu_p->v_p, (void *)eup->eumate_p->vu_p->v_p);
199  bu_bomb("nmg_vedge() edgeuse does not have correct vertex\n");
200  }
201  } else {
202  bu_log("nmg_vedge() edgeuse does not share vertex endpoint\n");
203  bu_log("(eu=%p, eu->vu_p->v_p=%p, eu->eumate_p->vu_p->v_p=%p)\n",
204  (void *)eu, (void *)eu->vu_p->v_p, (void *)eu->eumate_p->vu_p->v_p);
205  bu_log("(eup=%p, eup->vu_p->v_p=%p, eup->eumate_p->vu_p->v_p=%p)\n",
206  (void *)eup, (void *)eup->vu_p->v_p, (void *)eup->eumate_p->vu_p->v_p);
207  bu_bomb("nmg_vedge() edgeuse does not share vertex endpoint\n");
208  }
209 
210  eu = eu->eumate_p->radial_p;
211  } while (eu != eup);
212 
213  if (!is_use)
214  bu_bomb("nmg_vedge() Cannot get from edge to parent edgeuse\n");
215 }
216 
217 
218 /**
219  * Verify edgeuse list.
220  */
221 void
222 nmg_veu(const struct bu_list *hp, const uint32_t *up_magic_p)
223 {
224  struct edgeuse *eu;
225  struct edgeuse *eunext;
226  struct edgeuse *eulast;
227  uint32_t up_magic;
228 
229  bu_ck_list_magic(hp, "nmg_veu() edegeuse list head", NMG_EDGEUSE_MAGIC);
230 
231  up_magic = *up_magic_p;
232  switch (up_magic) {
233  case NMG_SHELL_MAGIC:
234  case NMG_LOOPUSE_MAGIC:
235  break;
236  default:
237  bu_bomb("nmg_veu() bad up_magic_p\n");
238  }
239  for (BU_LIST_FOR(eu, edgeuse, hp)) {
240  NMG_CK_EDGEUSE(eu);
241 
242  if (eu->up.magic_p != up_magic_p)
243  bu_bomb("nmg_veu() edgeuse denies parentage\n");
244 
245  if (!eu->l.forw)
246  bu_bomb("nmg_veu() edgeuse has Null \"forw\" pointer\n");
247  eunext = BU_LIST_PNEXT_CIRC(edgeuse, eu);
248  eulast = BU_LIST_PPREV_CIRC(edgeuse, &eu->l);
249  if (eunext->l.magic != NMG_EDGEUSE_MAGIC)
250  bu_bomb("nmg_veu() edgeuse forw is bad edgeuse\n");
251  if (eulast->l.magic != NMG_EDGEUSE_MAGIC)
252  bu_bomb("nmg_veu() edgeuse back is bad edgeuse\n");
253  NMG_CK_EDGEUSE(eunext);
254  NMG_CK_EDGEUSE(eulast);
255 
256  /* Check that forw->back is us */
257  if (BU_LIST_PPREV_CIRC(edgeuse, eunext) != eu) {
258  if (eunext->l.back)
259  bu_bomb("nmg_veu() next edgeuse has back that points elsewhere\n");
260  bu_bomb("nmg_veu() next edgeuse has NULL back\n");
261  }
262 
263  /*
264  * For edgeuses in loops, ensure that vertices are shared.
265  * This does not apply to wire edgeuses in the shell.
266  */
267  if (up_magic == NMG_LOOPUSE_MAGIC &&
268  eu->vu_p->v_p != eulast->eumate_p->vu_p->v_p) {
269  bu_log("eu=%p, e=%p\n", (void *)eu, (void *)eu->e_p);
270  bu_log("eulast=%p, e=%p\n", (void *)eulast, (void *)eulast->e_p);
271  bu_log(" eu: (%g, %g, %g) <--> (%g, %g, %g)\n",
272  V3ARGS(eu->vu_p->v_p->vg_p->coord),
273  V3ARGS(eu->eumate_p->vu_p->v_p->vg_p->coord));
274  bu_log(" eulast: (%g, %g, %g) <--> (%g, %g, %g)\n",
275  V3ARGS(eulast->vu_p->v_p->vg_p->coord),
276  V3ARGS(eulast->eumate_p->vu_p->v_p->vg_p->coord));
277  bu_log("unshared vertex (mine) v=%p: (%g, %g, %g)\n",
278  (void *)eu->vu_p->v_p,
279  V3ARGS(eu->vu_p->v_p->vg_p->coord));
280  bu_log("\t\t (last->eumate_p) v=%p: (%g, %g, %g)\n",
281  (void *)eulast->eumate_p->vu_p->v_p,
282  V3ARGS(eulast->eumate_p->vu_p->v_p->vg_p->coord));
283  nmg_pr_lu_briefly(eu->up.lu_p, (char *)NULL);
284  nmg_pr_lu_briefly(eu->up.lu_p->lumate_p, (char *)NULL);
285  bu_bomb("nmg_veu() discontinuous edgeloop mine/last\n");
286  }
287  if (up_magic == NMG_LOOPUSE_MAGIC &&
288  eunext->vu_p->v_p != eu->eumate_p->vu_p->v_p) {
289  bu_log("eu=%p, e=%p\n", (void *)eu, (void *)eu->e_p);
290  bu_log("eunext=%p, e=%p\n", (void *)eunext, (void *)eunext->e_p);
291  bu_log(" eu: (%g, %g, %g) <--> (%g, %g, %g)\n",
292  V3ARGS(eu->vu_p->v_p->vg_p->coord),
293  V3ARGS(eu->eumate_p->vu_p->v_p->vg_p->coord));
294  bu_log(" eunext: (%g, %g, %g) <--> (%g, %g, %g)\n",
295  V3ARGS(eunext->vu_p->v_p->vg_p->coord),
296  V3ARGS(eunext->eumate_p->vu_p->v_p->vg_p->coord));
297  bu_log("unshared vertex (mate) v=%p: (%g, %g, %g)\n",
298  (void *)eu->eumate_p->vu_p->v_p,
299  V3ARGS(eu->eumate_p->vu_p->v_p->vg_p->coord));
300  bu_log("\t\t (next) v=%p: (%g, %g, %g)\n",
301  (void *)eunext->vu_p->v_p,
302  V3ARGS(eunext->vu_p->v_p->vg_p->coord));
303  nmg_pr_lu_briefly(eu->up.lu_p, (char *)NULL);
304  nmg_pr_lu_briefly(eu->up.lu_p->lumate_p, (char *)NULL);
305  bu_bomb("nmg_veu() discontinuous edgeloop next/mate\n");
306  }
307 
308  /* Check mate and radial */
309  if (eu->eumate_p->l.magic != NMG_EDGEUSE_MAGIC)
310  bu_bomb("nmg_veu() edgeuse mate is bad edgeuse\n");
311  if (eu->eumate_p->eumate_p != eu)
312  bu_bomb("nmg_veu() edgeuse mate spurns edgeuse\n");
313 
314  if (eu->radial_p->l.magic != NMG_EDGEUSE_MAGIC)
315  bu_bomb("nmg_veu() edgeuse radial is bad edgeuse\n");
316  if (eu->radial_p->radial_p != eu)
317  bu_bomb("nmg_veu() edgeuse radial denies knowing edgeuse\n");
318 
319  nmg_vedge(eu->e_p, eu);
320 
321  if (eu->vu_p->v_p != eu->eumate_p->vu_p->v_p) {
322  if (!eu->l2.forw)
323  bu_bomb("nmg_veu() l2.forw is NULL\n");
324  if (!eu->l2.back)
325  bu_bomb("nmg_veu() l2.back is NULL\n");
326 
327  if (eu->g.magic_p != eu->eumate_p->g.magic_p)
328  bu_bomb("nmg_veu() edgeuse and mate don't share geometry\n");
329  if (eu->g.magic_p) nmg_veg(eu->g.magic_p);
330  }
331 
332  switch (eu->orientation) {
333  case OT_NONE : break;
334  case OT_SAME : break;
335  case OT_OPPOSITE: break;
336  case OT_UNSPEC : break;
337  default : bu_bomb("nmg_veu() unknown loopuse orientation\n");
338  break;
339  }
340 
341  nmg_vvu(eu->vu_p, &eu->l.magic);
342  }
343 }
344 
345 
346 /**
347  * Verify loop geometry
348  */
349 void
350 nmg_vlg(const struct loop_g *lg)
351 {
352  int i;
353 
354  NMG_CK_LOOP_G(lg);
355 
356  for (i=0; i < ELEMENTS_PER_POINT; ++i)
357  if (lg->min_pt[i] > lg->max_pt[i])
358  bu_bomb("nmg_vlg() loop geom min_pt greater than max_pt\n");
359 }
360 
361 
362 /**
363  * Verify loop
364  */
365 void
366 nmg_vloop(const struct loop *l, const struct loopuse *lup)
367 {
368 
369  NMG_CK_LOOP(l);
370  NMG_CK_LOOPUSE(lup);
371 
372  if (!l->lu_p) bu_bomb("nmg_vloop() null loopuse pointer\n");
373 
374  if (l->lg_p) nmg_vlg(l->lg_p);
375 }
376 
377 
378 /**
379  * Verify loopuse
380  */
381 void
382 nmg_vlu(const struct bu_list *hp, const uint32_t *up)
383 {
384  struct loopuse *lu;
385 
386  for (BU_LIST_FOR(lu, loopuse, hp)) {
387  NMG_CK_LOOPUSE(lu);
388 
389  if (lu->up.magic_p != up) {
390  bu_log("nmg_vlu() up is %p, s/b %p\n",
391  (void *)lu->up.magic_p, (void *)up);
392  bu_bomb("nmg_vlu() loopuse denies parentage\n");
393  }
394 
395  if (!lu->l.forw)
396  bu_bomb("nmg_vlu() loopuse has null forw pointer\n");
397  if (BU_LIST_PNEXT_PLAST(loopuse, lu) != lu)
398  bu_bomb("nmg_vlu() forw loopuse has back pointing somewhere else\n");
399 
400  if (!lu->lumate_p)
401  bu_bomb("nmg_vlu() loopuse has null mate pointer\n");
402 
403  if (lu->lumate_p->l.magic != NMG_LOOPUSE_MAGIC)
404  bu_bomb("nmg_vlu() loopuse mate is bad loopuse\n");
405 
406  if (lu->lumate_p->lumate_p != lu)
407  bu_bomb("nmg_vlu() lumate spurns loopuse\n");
408 
409  switch (lu->orientation) {
410  case OT_NONE : break;
411  case OT_SAME : break;
412  case OT_OPPOSITE : break;
413  case OT_UNSPEC : break;
414  case OT_BOOLPLACE: break;
415  default:
416  bu_log("lu=%p, orientation=%d\n", (void *)lu, lu->orientation);
417  bu_bomb("nmg_vlu() unknown loopuse orientation\n");
418  break;
419  }
420  if (lu->lumate_p->orientation != lu->orientation)
421  bu_bomb("nmg_vlu() loopuse and mate have different orientation\n");
422 
423  if (!lu->l_p)
424  bu_bomb("nmg_vlu() loopuse has Null loop pointer\n");
425  nmg_vloop(lu->l_p, lu);
426 
427  if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC)
428  nmg_veu(&lu->down_hd, &lu->l.magic);
429  else if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_VERTEXUSE_MAGIC)
430  nmg_vvu(BU_LIST_FIRST(vertexuse, &lu->down_hd), &lu->l.magic);
431  else
432  bu_bomb("nmg_vlu() bad down_hd magic\n");
433  }
434 }
435 
436 
437 /**
438  * Verify face geometry
439  */
440 void
441 nmg_vfg(const struct face_g_plane *fg)
442 {
443  NMG_CK_FACE_G_EITHER(fg);
444 
445  if (fg->magic == NMG_FACE_G_PLANE_MAGIC) {
446  if (VNEAR_ZERO(fg->N, SMALL_FASTF) && !ZERO(fg->N[H])) {
447  bu_log("bad NMG plane equation %fX + %fY + %fZ = %f\n",
448  fg->N[X], fg->N[Y], fg->N[Z], fg->N[H]);
449  bu_bomb("nmg_vfg() Bad NMG geometry\n");
450  }
451  }
452  if (fg->magic == NMG_FACE_G_SNURB_MAGIC) {
453  /* XXX Should the face's NURB be checked somehow?? */
454  }
455 }
456 
457 
458 /**
459  * Verify face
460  */
461 void
462 nmg_vface(const struct face *f, const struct faceuse *fup)
463 {
464  int i;
465 
466  NMG_CK_FACE(f);
467  NMG_CK_FACEUSE(fup);
468 
469  /* make sure we can get back to the parent faceuse from the face */
470  if (!f->fu_p) bu_bomb("nmg_vface() null faceuse pointer\n");
471 
472  for (i=0; i < ELEMENTS_PER_POINT; ++i)
473  if (f->min_pt[i] > f->max_pt[i]) {
474  bu_log("nmg_vface() face min_pt[%d]:%g greater than max_pt[%d]:%g\n",
475  i, f->min_pt[i], i, f->max_pt[i]);
476  bu_log("min_pt(%g %g %g) ", V3ARGS(f->min_pt));
477  bu_log("max_pt(%g %g %g)\n", V3ARGS(f->max_pt));
478  bu_bomb("Invalid NMG\n");
479  }
480  if (f->g.plane_p) nmg_vfg(f->g.plane_p);
481 }
482 
483 
484 /**
485  * Validate a list of faceuses
486  */
487 void
488 nmg_vfu(const struct bu_list *hp, const struct shell *s)
489 {
490  struct faceuse *fu;
491 
492  NMG_CK_SHELL(s);
493 
494  for (BU_LIST_FOR(fu, faceuse, hp)) {
495  NMG_CK_FACEUSE(fu);
496  if (fu->s_p != s) {
497  bu_log("faceuse claims shell parent (%8p) instead of (%8p)\n",
498  (void *)fu->s_p, (void *)s);
499  bu_bomb("nmg_vfu()\n");
500  }
501 
502  if (!fu->l.forw) {
503  bu_bomb("nmg_vfu() faceuse forw is NULL\n");
504  } else if (fu->l.forw->back != (struct bu_list *)fu) {
505  bu_bomb("nmg_vfu() faceuse->forw->back != faceuse\n");
506  }
507 
508  if (!fu->fumate_p)
509  bu_bomb("nmg_vfu() null faceuse fumate_p pointer\n");
510 
511  if (fu->fumate_p->l.magic != NMG_FACEUSE_MAGIC)
512  bu_bomb("nmg_vfu() faceuse mate is bad faceuse ptr\n");
513 
514  if (fu->fumate_p->fumate_p != fu)
515  bu_bomb("nmg_vfu() faceuse mate spurns faceuse!\n");
516 
517  switch (fu->orientation) {
518  case OT_NONE : break;
519  case OT_SAME : if (fu->fumate_p->orientation != OT_OPPOSITE)
520  bu_bomb("nmg_vfu() faceuse of \"SAME\" orientation has mate that is not \"OPPOSITE\" orientation\n");
521  break;
522  case OT_OPPOSITE: if (fu->fumate_p->orientation != OT_SAME)
523  bu_bomb("nmg_vfu() faceuse of \"OPPOSITE\" orientation has mate that is not \"SAME\" orientation\n");
524  break;
525  case OT_UNSPEC : break;
526  default : bu_bomb("nmg_vfu() unknown faceuse orientation\n"); break;
527  }
528 
529  NMG_CK_FACE(fu->f_p);
530  nmg_vface(fu->f_p, fu);
531 
532  nmg_vlu(&fu->lu_hd, &fu->l.magic);
533  }
534 }
535 
536 
537 /**
538  * validate a single shell and all elements under it
539  */
540 void
541 nmg_vsshell(const struct shell *s, const struct nmgregion *r)
542 {
543  pointp_t lpt, hpt;
544 
545  NMG_CK_SHELL(s);
546  if (s->r_p != r) {
547  bu_log("shell's r_p (%8p) doesn't point to parent (%8p)\n", (void *)s->r_p, (void *)r);
548  bu_bomb("nmg_vsshell()\n");
549  }
550 
551  if (!s->l.forw) {
552  bu_bomb("nmg_vshell(): Shell's forw ptr is null\n");
553  } else if (s->l.forw->back != (struct bu_list *)s) {
554  bu_log("forw shell's back(%8p) is not me (%8p)\n", (void *)s->l.forw->back, (void *)s);
555  bu_bomb("nmg_vsshell()\n");
556  }
557 
558  if (s->sa_p) {
559  NMG_CK_SHELL_A(s->sa_p);
560  /* we make sure that all values of min_pt are less than or
561  * equal to the values of max_pt
562  */
563  lpt = s->sa_p->min_pt;
564  hpt = s->sa_p->max_pt;
565  if (lpt[0] > hpt[0] || lpt[1] > hpt[1] || lpt[2] > hpt[2]) {
566  bu_log("nmg_vsshell(): ad min_pt/max_pt for shell(%8p)'s extent\n", (void *)s);
567  bu_log("Min_pt %g %g %g\n", lpt[0], lpt[1], lpt[2]);
568  bu_log("Max_pt %g %g %g\n", hpt[0], hpt[1], hpt[2]);
569  }
570  }
571 
572  /* now we check out the "children" */
573  if (s->vu_p) {
574  if (BU_LIST_NON_EMPTY(&s->fu_hd) || BU_LIST_NON_EMPTY(&s->lu_hd) ||
575  BU_LIST_NON_EMPTY(&s->eu_hd)) {
576  bu_log("shell (%8p) with vertexuse (%8p) has other children\n", (void *)s, (void *)s->vu_p);
577  bu_bomb("nmg_vsshell()\n");
578  }
579  }
580 
581  nmg_vfu(&s->fu_hd, s);
582  nmg_vlu(&s->lu_hd, &s->l.magic);
583  nmg_veu(&s->eu_hd, &s->l.magic);
584 }
585 
586 
587 /**
588  * Validate a list of shells and all elements under them.
589  */
590 void
591 nmg_vshell(const struct bu_list *hp, const struct nmgregion *r)
592 {
593  struct shell *s;
594 
595  NMG_CK_REGION(r);
596 
597  for (BU_LIST_FOR(s, shell, hp)) {
598  nmg_vsshell(s, r);
599  }
600 }
601 
602 
603 /**
604  * validate a list of nmgregions and all elements under them
605  */
606 void
607 nmg_vregion(const struct bu_list *hp, const struct model *m)
608 {
609  struct nmgregion *r;
610 
611  for (BU_LIST_FOR(r, nmgregion, hp)) {
612  NMG_CK_REGION(r);
613  if (r->m_p != m) {
614  bu_log("nmgregion pointer m_p %8p should be %8p\n",
615  (void *)r->m_p, (void *)m);
616  bu_bomb("nmg_vregion()\n");
617  }
618  if (r->ra_p) {
619  NMG_CK_REGION_A(r->ra_p);
620  }
621 
622  nmg_vshell(&r->s_hd, r);
623 
624  if (BU_LIST_PNEXT_PLAST(nmgregion, r) != r) {
625  bu_bomb("nmg_vregion() forw nmgregion's back is not me\n");
626  }
627  }
628 }
629 
630 
631 /**
632  * validate an NMG model and all elements in it.
633  */
634 void
635 nmg_vmodel(const struct model *m)
636 {
637  NMG_CK_MODEL(m);
638  nmg_vregion(&m->r_hd, m);
639 }
640 
641 
642 /************************************************************************
643  * *
644  * Checking Routines *
645  * *
646  ************************************************************************/
647 
648 void
649 nmg_ck_e(const struct edgeuse *eu, const struct edge *e, const char *str)
650 {
651  char *errstr;
652  struct edgeuse *eparent;
653  int len = (int)strlen(str)+128;
654 
655  errstr = (char *)bu_calloc(len, sizeof(char), "nmg_ck_e error str");
656  snprintf(errstr, len, "%sedge %p\n", str, (void *)e);
657 
658  NMG_CK_EDGE(e);
659  NMG_CK_EDGEUSE(eu);
660 
661  eparent = e->eu_p;
662 
663  NMG_CK_EDGEUSE(eparent);
664  NMG_CK_EDGEUSE(eparent->eumate_p);
665  do {
666  if (eparent == eu || eparent->eumate_p == eu) break;
667 
668  eparent = eparent->radial_p->eumate_p;
669  } while (eparent != e->eu_p);
670 
671  if (eparent != eu && eparent->eumate_p != eu) {
672  bu_strlcat(errstr, "nmg_ck_e() Edge denies edgeuse parentage\n", len);
673  bu_bomb(errstr);
674  }
675 
676  bu_free(errstr, "nmg_ck_e error str");
677 }
678 
679 
680 void
681 nmg_ck_vu(const uint32_t *parent, const struct vertexuse *vu, const char *str)
682 {
683  char *errstr;
684  int len = (int)strlen(str)+128;
685 
686  errstr = (char *)bu_calloc(len, sizeof(char), "nmg_ck_vu error str");
687  snprintf(errstr, len, "%svertexuse %p\n", str, (void *)vu);
688 
689  if (vu->up.magic_p != parent) {
690  bu_strlcat(errstr, "nmg_ck_vu() Vertexuse denies parentage\n", len);
691  bu_bomb(errstr);
692  }
693 
694  bu_free(errstr, "nmg_ck_vu error str");
695 }
696 
697 
698 void
699 nmg_ck_eu(const uint32_t *parent, const struct edgeuse *eu, const char *str)
700 {
701  char *errstr;
702  struct edgeuse *eur, *eu_next, *eu_last;
703  int len = (int)strlen(str)+128;
704 
705  errstr = (char *)bu_calloc(len, sizeof(char), "nmg_ck_eu error str");
706  snprintf(errstr, len, "%sedgeuse %p\n", str, (void *)eu);
707 
708  NMG_CK_EDGEUSE(eu);
709 
710  if (eu->up.magic_p != parent) {
711  bu_strlcat(errstr, "nmg_ck_eu() Edgeuse child denies parentage\n", len);
712  bu_bomb(errstr);
713  }
714 
715  if (*eu->eumate_p->up.magic_p != *eu->up.magic_p) {
716  bu_strlcat(errstr, "nmg_ck_eu() eumate has different kind of parent\n", len);
717  bu_bomb(errstr);
718  }
719  if (*eu->up.magic_p == NMG_SHELL_MAGIC) {
720  if (eu->eumate_p->up.s_p != eu->up.s_p) {
721  bu_strlcat(errstr, "nmg_ck_eu() eumate in different shell\n", len);
722  bu_bomb(errstr);
723  }
724 
725  eur = eu->radial_p;
726  while (eur && eur != eu && eur != eu->eumate_p)
727  eur = eur->eumate_p->radial_p;
728 
729  if (!eur) {
730  bu_strlcat(errstr, "nmg_ck_eu() Radial trip from eu ended in null pointer\n", len);
731  bu_bomb(errstr);
732  }
733 
734  } else if (*eu->up.magic_p == NMG_LOOPUSE_MAGIC) {
735  if (eu->eumate_p->up.lu_p != eu->up.lu_p->lumate_p) {
736  bu_strlcat(errstr, "nmg_ck_eu() eumate not in same loop\n", len);
737  bu_bomb(errstr);
738  }
739 
740  eur = eu->radial_p;
741  while (eur && eur != eu->eumate_p && eur != eu)
742  eur = eur->eumate_p->radial_p;
743 
744  if (!eur) {
745  bu_strlcat(errstr, "nmg_ck_eu() radial path leads to null ptr\n", len);
746  bu_bomb(errstr);
747  }
748  if (eur == eu) {
749  bu_strlcat(errstr, "nmg_ck_eu() Never saw eumate\n", len);
750  bu_bomb(errstr);
751  }
752 
753  eu_next = BU_LIST_PNEXT_CIRC(edgeuse, eu);
754  if (eu_next->vu_p->v_p != eu->eumate_p->vu_p->v_p)
755  bu_bomb("nmg_ck_eu: next and mate don't share vertex\n");
756 
757  eu_last = BU_LIST_PPREV_CIRC(edgeuse, eu);
758  if (eu_last->eumate_p->vu_p->v_p != eu->vu_p->v_p)
759  bu_bomb("nmg_ck_eu: edge and last-mate don't share vertex\n");
760 
761  } else {
762  bu_strlcat(errstr, "nmg_ck_eu() Bad edgeuse parent\n", len);
763  bu_bomb(errstr);
764  }
765 
766  NMG_CK_EDGE(eu->e_p);
767  nmg_ck_e(eu, eu->e_p, errstr);
768 
769  NMG_CK_VERTEXUSE(eu->vu_p);
770  nmg_ck_vu(&eu->l.magic, eu->vu_p, errstr);
771 
772  bu_free(errstr, "nmg_ck_eu error str");
773 }
774 
775 
776 void
777 nmg_ck_lg(const struct loop *l, const struct loop_g *lg, const char *str)
778 {
779  char *errstr;
780  int len = (int)strlen(str)+128;
781 
782  errstr = (char *)bu_calloc(len, sizeof(char), "nmg_ck_lg error str");
783  snprintf(errstr, len, "%sloop_g %p\n", str, (void *)lg);
784 
785  NMG_CK_LOOP_G(lg);
786  NMG_CK_LOOP(l);
787 
788  bu_free(errstr, "nmg_ck_lg error str");
789 }
790 
791 
792 void
793 nmg_ck_l(const struct loopuse *lu, const struct loop *l, const char *str)
794 {
795  char *errstr;
796  int len = (int)strlen(str)+128;
797 
798  errstr = (char *)bu_calloc(len, sizeof(char), "nmg_ck_l error str");
799  snprintf(errstr, len, "%sloop %p\n", str, (void *)l);
800 
801  NMG_CK_LOOP(l);
802  NMG_CK_LOOPUSE(lu);
803 
804  if (l->lu_p != lu && l->lu_p->lumate_p != lu) {
805  bu_strlcat(errstr, "nmg_ck_l() Cannot get from loop to loopuse\n", len);
806  bu_bomb(errstr);
807  }
808 
809  if (l->lg_p) nmg_ck_lg(l, l->lg_p, errstr);
810 
811  bu_free(errstr, "");
812 }
813 
814 
815 void
816 nmg_ck_lu(const uint32_t *parent, const struct loopuse *lu, const char *str)
817 {
818  struct edgeuse *eu;
819  struct vertexuse *vu;
820  char *errstr;
821  int l;
822  int edgeuse_num=0;
823  uint32_t magic1;
824  int len = (int)strlen(str)+128;
825 
826  errstr = (char *)bu_calloc(len, sizeof(char), "nmg_ck_lu error str");
827  snprintf(errstr, len, "%sloopuse %p\n", str, (void *)lu);
828 
829  NMG_CK_LOOPUSE(lu);
830 
831  if (lu->up.magic_p != parent) {
832  bu_strlcat(errstr, "nmg_ck_lu() loopuse child denies parentage\n", len);
833  bu_bomb(errstr);
834  }
835 
836  /* check the parent of lu and lumate WRT each other */
837  NMG_CK_LOOPUSE(lu->lumate_p);
838  if (*lu->lumate_p->up.magic_p != *lu->up.magic_p) {
839  bu_strlcat(errstr, "nmg_ck_lu() loopuse mate has different kind of parent\n", len);
840  bu_bomb(errstr);
841  }
842 
843  if (*lu->up.magic_p == NMG_SHELL_MAGIC) {
844  if (lu->lumate_p->up.s_p != lu->up.s_p) {
845  bu_strlcat(errstr, "nmg_ck_lu() Lumate not in same shell\n", len);
846  bu_bomb(errstr);
847  }
848  } else if (*lu->up.magic_p == NMG_FACEUSE_MAGIC) {
849  if (lu->lumate_p->up.fu_p != lu->up.fu_p->fumate_p) {
850  bu_strlcat(errstr, "nmg_ck_lu() lumate part of different face\n", len);
851  bu_bomb(errstr);
852  }
853  } else {
854  bu_strlcat(errstr, "nmg_ck_lu() Bad loopuse parent type\n", len);
855  bu_bomb(errstr);
856  }
857 
858  NMG_CK_LOOP(lu->l_p);
859  nmg_ck_l(lu, lu->l_p, errstr);
860 
861  /* check the children of the loopuse */
862  magic1 = BU_LIST_FIRST_MAGIC(&lu->down_hd);
863  if (magic1 == NMG_VERTEXUSE_MAGIC) {
864  vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
865  NMG_CK_VERTEXUSE(vu);
866  nmg_ck_vu(&lu->l.magic, vu, errstr);
867  } else if (magic1 == NMG_EDGEUSE_MAGIC) {
868  l = (int)strlen(errstr);
869  for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
870  NMG_CK_EDGEUSE(eu);
871  snprintf(&errstr[l], len-l, "%sedgeuse #%d (%p)\n",
872  errstr, edgeuse_num++, (void *)eu);
873  nmg_ck_eu(&lu->l.magic, eu, errstr);
874  }
875  } else {
876  bu_strlcat(errstr, "nmg_ck_lu() Bad loopuse down pointer\n", len);
877  bu_bomb(errstr);
878  }
879  bu_free(errstr, "nmg_ck_lu error str");
880 }
881 
882 
883 void
884 nmg_ck_fg(const struct face *f, const struct face_g_plane *fg, const char *str)
885 {
886  char *errstr;
887  int len = (int)strlen(str)+128;
888 
889  errstr = (char *)bu_calloc(len, sizeof(char), "nmg_ck_fg error str");
890  snprintf(errstr, len, "%sFace_g %p\n", str, (void *)f);
891 
892  NMG_CK_FACE_G_PLANE(fg);
893  if (VNEAR_ZERO(fg->N, SMALL_FASTF) && !ZERO(fg->N[H])) {
894  snprintf(&errstr[strlen(errstr)], len-strlen(errstr),
895  "nmg_ck_fg() bad NMG plane equation %fX + %fY + %fZ = %f\n",
896  fg->N[X], fg->N[Y], fg->N[Z], fg->N[H]);
897  bu_bomb(errstr);
898  }
899 
900  bu_free(errstr, "nmg_ck_fg error str");
901 }
902 
903 
904 void
905 nmg_ck_f(const struct faceuse *fu, const struct face *f, const char *str)
906 {
907  char *errstr;
908  int len = (int)strlen(str)+128;
909 
910  errstr = (char *)bu_calloc(len, sizeof(char), "nmg_ck_f error str");
911  snprintf(errstr, len, "%sFace %p\n", str, (void *)f);
912 
913  NMG_CK_FACE(f);
914  NMG_CK_FACEUSE(fu);
915  NMG_CK_FACE_G_PLANE(f->g.plane_p);
916  if (f->fu_p != fu && f->fu_p->fumate_p != fu) {
917  bu_strlcat(errstr, "nmg_ck_f() Cannot get from face to \"parent faceuse\"\n", len);
918  bu_bomb(errstr);
919  }
920 
921  if (f->g.plane_p) nmg_ck_fg(f, f->g.plane_p, errstr);
922 
923  bu_free(errstr, "nmg_ck_f error str");
924 }
925 
926 
927 void
928 nmg_ck_fu(const struct shell *s, const struct faceuse *fu, const char *str)
929 {
930  char *errstr;
931  int l;
932  int loop_number = 0;
933  struct loopuse *lu;
934  int len = (int)strlen(str)+128;
935 
936  NMG_CK_FACEUSE(fu);
937  NMG_CK_SHELL(s);
938 
939  errstr = (char *)bu_calloc(len, sizeof(char), "nmg_ck_fu error str");
940  snprintf(errstr, len, "%sFaceuse %p\n", str, (void *)fu);
941 
942  if (fu->s_p != s) {
943  bu_strlcat(errstr, "nmg_ck_fu() faceuse child denies shell parentage\n", len);
944  bu_bomb(errstr);
945  }
946 
947  if (BU_LIST_PNEXT_PLAST(faceuse, fu)) {
948  bu_strlcat(errstr, "nmg_ck_fu() Faceuse not lastward of next faceuse\n", len);
949  bu_bomb(errstr);
950  }
951 
952  if (BU_LIST_PLAST_PNEXT(faceuse, fu)) {
953  bu_strlcat(errstr, "nmg_ck_fu() Faceuse not nextward from last faceuse\n", len);
954  bu_bomb(errstr);
955  }
956 
957  NMG_CK_FACEUSE(fu->fumate_p);
958  if (fu->fumate_p->fumate_p != fu) {
959  bu_strlcat(errstr, "nmg_ck_fu() Faceuse not fumate of fumate\n", len);
960  bu_bomb(errstr);
961  }
962 
963  if (fu->fumate_p->s_p != s) {
964  bu_strlcat(errstr, "nmg_ck_fu() faceuse mates not in same shell\n", len);
965  bu_bomb(errstr);
966  }
967 
968  nmg_ck_f(fu, fu->f_p, errstr);
969 
970  l = (int)strlen(errstr);
971  for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
972  NMG_CK_LOOPUSE(lu);
973  snprintf(&errstr[l], len-l, "%sloopuse #%d (%p)\n",
974  errstr, loop_number++, (void *)lu);
975  nmg_ck_lu(&fu->l.magic, lu, errstr);
976  }
977  bu_free(errstr, "nmg_ck_fu error str");
978 }
979 
980 
981 /**
982  * Check if vertices from edgeuses using this edge geometry
983  * actually lie on the edge geometry.
984  *
985  * "eg" must be LSEG
986  * returns number of vertices not on edge line
987  */
988 
989 int
990 nmg_ck_eg_verts(const struct edge_g_lseg *eg, const struct bn_tol *tol)
991 {
992  struct bu_list *eu2;
993  vect_t e_dir;
994  int count=0;
995 
996  NMG_CK_EDGE_G_LSEG(eg);
997  BN_CK_TOL(tol);
998 
999  VMOVE(e_dir, eg->e_dir);
1000  VUNITIZE(e_dir);
1001 
1002  for (BU_LIST_FOR(eu2, bu_list, &eg->eu_hd2)) {
1003  struct edgeuse *eu;
1004  struct vertex *v1, *v2;
1005  struct vertex_g *vg1, *vg2;
1006  vect_t pt_to_vert;
1007  vect_t eg_to_vert;
1008 
1009  eu = BU_LIST_MAIN_PTR(edgeuse, eu2, l2);
1010 
1011  NMG_CK_EDGEUSE(eu);
1012 
1013  v1 = eu->vu_p->v_p;
1014  NMG_CK_VERTEX(v1);
1015  vg1 = v1->vg_p;
1016  NMG_CK_VERTEX_G(vg1);
1017 
1018  v2 = eu->eumate_p->vu_p->v_p;
1019  NMG_CK_VERTEX(v2);
1020  vg2 = v2->vg_p;
1021  NMG_CK_VERTEX_G(vg2);
1022 
1023  VSUB2(pt_to_vert, vg1->coord, eg->e_pt);
1024  VJOIN1(eg_to_vert, pt_to_vert, -VDOT(e_dir, pt_to_vert), e_dir);
1025  if (MAGSQ(eg_to_vert) > tol->dist_sq) {
1026  count++;
1027  bu_log("vertex (%g %g %g) on eu to (%g %g %g)\n", V3ARGS(vg1->coord),
1028  V3ARGS(vg2->coord));
1029  bu_log("\tnot on edge geometry: pt=(%g %g %g), dir=(%g %g %g)\n",
1030  V3ARGS(eg->e_pt), V3ARGS(eg->e_dir));
1031  }
1032  }
1033 
1034  return count;
1035 }
1036 
1037 
1038 /**
1039  * Check that vertices actually lie on geometry for
1040  * faces and edges
1041  *
1042  * returns number of vertices that do not lie on geometry
1043  */
1044 int
1045 nmg_ck_geometry(const struct model *m, const struct bn_tol *tol)
1046 {
1047  struct bu_ptbl g_tbl;
1048  int i;
1049  int count=0;
1050 
1051  NMG_CK_MODEL(m);
1052  BN_CK_TOL(tol);
1053 
1054  bu_ptbl_init(&g_tbl, 64, " &g_tbl ");
1055 
1056  nmg_edge_g_tabulate(&g_tbl, &m->magic);
1057 
1058  for (i=0; i<BU_PTBL_END(&g_tbl); i++) {
1059  uint32_t *ep;
1060  struct edge_g_lseg *eg;
1061 
1062  ep = (uint32_t *)BU_PTBL_GET(&g_tbl, i);
1063  switch (*ep) {
1064  case NMG_EDGE_G_LSEG_MAGIC:
1065  eg = (struct edge_g_lseg *)ep;
1066  NMG_CK_EDGE_G_LSEG(eg);
1067  count += nmg_ck_eg_verts(eg, tol);
1068  break;
1070  /* XXX any checking for vertices on CNURB geometry?? */
1071  break;
1072  }
1073  }
1074 
1075  bu_ptbl_reset(&g_tbl);
1076 
1077  nmg_face_tabulate(&g_tbl, &m->magic);
1078 
1079  for (i=0; i<BU_PTBL_END(&g_tbl); i++) {
1080  struct face *f;
1081 
1082  f = (struct face *)BU_PTBL_GET(&g_tbl, i);
1083  NMG_CK_FACE(f);
1084 
1085  count += nmg_ck_fg_verts(f->fu_p, f, tol);
1086  }
1087 
1088  bu_ptbl_free(&g_tbl);
1089 
1090  return count;
1091 }
1092 
1093 
1094 /**
1095  * Search for null ("worthless") edges in a face.
1096  * Such edges are legitimate to have, but can be troublesome
1097  * for the boolean routines.
1098  *
1099  * Often used to see if breaking an edge at a given
1100  * vertex results in a null edge being created.
1101  */
1102 int
1103 nmg_ck_face_worthless_edges(const struct faceuse *fu)
1104 {
1105  const struct loopuse *lu;
1106 
1107  for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
1108  struct edgeuse *eu;
1109 
1110  NMG_CK_LOOPUSE(lu);
1111  if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_VERTEXUSE_MAGIC)
1112  continue;
1113  for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
1114  struct edgeuse *neu;
1115  neu = BU_LIST_PNEXT_CIRC(edgeuse, eu);
1116  if (eu == neu)
1117  bu_bomb("nmg_ck_face_worthless_edges() lu has only one edge?\n");
1118  if (eu->vu_p == neu->vu_p)
1119  bu_bomb("nmg_ck_face_worthless_edges() edge runs between two copies of vu??\n");
1120  if (eu->vu_p->v_p == neu->vu_p->v_p) {
1121  bu_log("eu=%p, neu=%p, v=%p\n", (void *)eu, (void *)neu, (void *)eu->vu_p->v_p);
1122  bu_log("eu=%p, neu=%p, v=%p\n", (void *)eu->eumate_p, (void *)neu->eumate_p, (void *)eu->eumate_p->vu_p->v_p);
1123  bu_bomb("nmg_ck_face_worthless_edges() edge runs from&to same vertex\n");
1124  return 1;
1125  }
1126  }
1127  }
1128  return 0;
1129 
1130 }
1131 
1132 
1133 /**
1134  * check all the edgeuses of a loopuse to make sure these children
1135  * know who their parent really is.
1136  */
1137 void
1138 nmg_ck_lueu(const struct loopuse *cklu, const char *s)
1139 {
1140  struct edgeuse *eu;
1141 
1142  if (BU_LIST_FIRST_MAGIC(&cklu->down_hd) == NMG_VERTEXUSE_MAGIC)
1143  bu_bomb("NMG nmg_ck_lueu. I got a vertex loop!\n");
1144 
1145  eu = BU_LIST_FIRST(edgeuse, &cklu->down_hd);
1146  if (eu->l.back != &cklu->down_hd) {
1147  bu_bomb("nmg_ck_lueu first element in list doesn't point back to head\n");
1148  }
1149 
1150  for (BU_LIST_FOR(eu, edgeuse, &cklu->down_hd)) {
1151  NMG_CK_EDGEUSE(eu);
1152  if (eu->up.lu_p != cklu) {
1153  bu_log("nmg_cl_lueu() edgeuse of %s (going next) has lost proper parent\n", s);
1154  bu_bomb("nmg_ck_lueu\n");
1155  }
1156  if ((struct edgeuse *)eu->l.forw->back != eu) {
1157  bu_log("nmg_cl_lueu() %s next edge (%8p) doesn't point back to me (%8p)!\n",
1158  s, (void *)eu->l.forw, (void *)eu);
1159  nmg_pr_lu(cklu, NULL);
1160  }
1161  if ((struct edgeuse *)eu->l.back->forw != eu) {
1162  bu_log("nmg_cl_lueu() %s last edge (%p) doesn't point forward to me (%p)!\n",
1163  s, (void *)eu->l.forw, (void *)eu);
1164  nmg_pr_lu(cklu, NULL);
1165  }
1166  }
1167 
1168  cklu = cklu->lumate_p;
1169 
1170  eu = BU_LIST_FIRST(edgeuse, &cklu->down_hd);
1171  if (eu->l.back != &cklu->down_hd) {
1172  bu_bomb("nmg_ck_lueu first element in lumate list doesn't point back to head\n");
1173  }
1174 
1175  for (BU_LIST_FOR(eu, edgeuse, &cklu->down_hd)) {
1176  NMG_CK_EDGEUSE(eu);
1177  if (eu->up.lu_p != cklu) {
1178  bu_log("nmg_cl_lueu() edgeuse of %s (lumate going next) has lost proper parent\n", s);
1179  bu_bomb("nmg_ck_lueu\n");
1180  }
1181  if ((struct edgeuse *)eu->l.forw->back != eu) {
1182  bu_log("nmg_cl_lueu() %s next edge (%8p) doesn't point back to me (%8p)!\n",
1183  s, (void *)eu->l.forw, (void *)eu);
1184  nmg_pr_lu(cklu, NULL);
1185  }
1186  if ((struct edgeuse *)eu->l.back->forw != eu) {
1187  bu_log("nmg_cl_lueu() %s (lumate) back edge (%8p) doesn't point forward to me (%8p)!\n",
1188  s, (void *)eu->l.forw, (void *)eu);
1189  nmg_pr_lu(cklu, NULL);
1190  }
1191  }
1192 }
1193 
1194 
1195 /**
1196  * check to see if all radial uses of an edge (within a shell) are
1197  * properly oriented with respect to each other.
1198  * NOTE that ONLY edgeuses belonging to the shell of eu are checked.
1199  *
1200  * Can't check faceuse orientation parity for
1201  * things from more than one shell; parity is conserved
1202  * only within faces from a single shell.
1203  *
1204  * Return
1205  * 0 OK
1206  * 1 bad edgeuse mate
1207  * 2 unclosed space
1208  */
1209 int
1210 nmg_check_radial(const struct edgeuse *eu, const struct bn_tol *tol)
1211 {
1212  const struct shell *s;
1213 
1214  NMG_CK_EDGEUSE(eu);
1215  BN_CK_TOL(tol);
1216  s = nmg_find_s_of_eu(eu);
1217  NMG_CK_SHELL(s);
1218 
1219  /*
1220  * XXX Added code to skip dangling faces (needs to be checked a little more) - JRA
1221  *
1222  * XXX I think that if dangling faces are to be processed
1223  * correctly, XXX the caller should pass in a table of dangling
1224  * faces. -Mike
1225  */
1226 #ifndef NEW_DANGLING_FACE_CHECKING_METHOD
1227  return 0;
1228 #else
1229  if (RTG.NMG_debug & DEBUG_BASIC) {
1230  bu_log("nmg_check_radial(eu=x%x, tol)\n", eu);
1231  }
1232 
1233  eu_orig = eu;
1234  eu1 = eu;
1235 
1236  /* If this eu is a wire, advance to first non-wire. */
1237  while ((fu = nmg_find_fu_of_eu(eu)) == (struct faceuse *)NULL ||
1238  nmg_find_s_of_eu((struct edgeuse *)eu) != s
1239  ) {
1240  eu = eu->radial_p->eumate_p;
1241  if (eu == eu1) return 0; /* wires all around */
1242  }
1243 
1244  curr_orient = fu->orientation;
1245  eur = eu->radial_p;
1246  eurstart = eur;
1247  eu1 = eu; /* virtual radial to eur */
1248 
1249  NMG_CK_EDGEUSE(eur);
1250  do {
1251  /*
1252  * Search until another edgeuse in this shell is found.
1253  * Continue search if it is a wire edge.
1254  */
1255  while (nmg_find_s_of_eu((struct edgeuse *)eur) != s
1256  || (fu = nmg_find_fu_of_eu(eur)) == (struct faceuse *)NULL) {
1257  /* Advance to next eur */
1258  NMG_CK_EDGEUSE(eur->eumate_p);
1259  if (eur->eumate_p->eumate_p != eur) {
1260  bu_bomb("nmg_check_radial: bad edgeuse mate\n");
1261  }
1262  eur = eur->eumate_p->radial_p;
1263  NMG_CK_EDGEUSE(eur);
1264  if (eur == eurstart) return 0;
1265  }
1266 
1267  /* if that radial edgeuse doesn't have the
1268  * correct orientation, print & bomb
1269  * If radial (eur) is my (virtual, this-shell) mate (eu1),
1270  * then it's OK, a mis-match is to be expected.
1271  */
1272  NMG_CK_LOOPUSE(eur->up.lu_p);
1273  fu = eur->up.lu_p->up.fu_p;
1274  NMG_CK_FACEUSE(fu);
1275  if (fu->orientation != curr_orient &&
1276  eur != eu1->eumate_p) {
1277  char file[128];
1278  char buf[128];
1279  static int num=0;
1280 
1281  p = eu1->vu_p->v_p->vg_p->coord;
1282  q = eu1->eumate_p->vu_p->v_p->vg_p->coord;
1283  bu_log("nmg_check_radial(): Radial orientation problem\n edge: %g %g %g -> %g %g %g\n",
1284  p[0], p[1], p[2], q[0], q[1], q[2]);
1285  bu_log(" eu_orig=%8x, eur=%8x, s=x%x, eurstart=x%x, curr_orient=%s\n",
1286  eu_orig, eur, s, eurstart,
1287  nmg_orientation(curr_orient));
1288 
1289  /* Plot the edge in yellow, & the loops */
1290  RTG.NMG_debug |= DEBUG_PLOTEM;
1291  nmg_face_lu_plot(eu1->up.lu_p, eu1->vu_p,
1292  eu1->eumate_p->vu_p);
1293  nmg_face_lu_plot(eur->up.lu_p, eur->vu_p,
1294  eur->eumate_p->vu_p);
1295 
1296  snprintf(buf, 128, "%g %g %g -> %g %g %g\n",
1297  p[0], p[1], p[2], q[0], q[1], q[2]);
1298 
1299  snprintf(file, 128, "radial%d.g", num++);
1301  nmg_find_model(&(fu->l.magic)), buf);
1302 
1303  nmg_pr_fu_around_eu(eu_orig, tol);
1304 
1305  bu_log("nmg_check_radial: unclosed space\n");
1306  return 2;
1307  }
1308 
1309  eu1 = eur->eumate_p;
1310  NMG_CK_LOOPUSE(eu1->up.lu_p);
1311  NMG_CK_FACEUSE(eu1->up.lu_p->up.fu_p);
1312  curr_orient = eu1->up.lu_p->up.fu_p->orientation;
1313  eur = eu1->radial_p;
1314  } while (eur != eurstart);
1315  return 0;
1316 #endif
1317 }
1318 
1319 
1320 /**
1321  * Given an edgeuse, check that the proper orientation "parity" of
1322  * same/opposite/opposite/same is preserved, for all non-wire edgeuses
1323  * within shell s1.
1324  * If s2 is non-null, then ensure that the parity of all edgeuses in
1325  * BOTH s1 and s2 are correct, and mutually compatible.
1326  *
1327  * This routine does not care if a face is "dangling" or not.
1328  *
1329  * If the edgeuse specified is a wire edgeuse, skip forward to a non-wire.
1330  *
1331  * Returns -
1332  * 0 OK
1333  * !0 Bad orientation parity.
1334  */
1335 int
1336 nmg_eu_2s_orient_bad(const struct edgeuse *eu, const struct shell *s1, const struct shell *s2, const struct bn_tol *tol)
1337 {
1338  char curr_orient;
1339  const struct edgeuse *eu_orig;
1340  const struct edgeuse *eur;
1341  const struct edgeuse *eu1;
1342  const struct edgeuse *eurstart;
1343  const struct faceuse *fu;
1344  const struct shell *s;
1345  int ret = 0;
1346 
1347  NMG_CK_EDGEUSE(eu);
1348  NMG_CK_SHELL(s1);
1349  if (s2) NMG_CK_SHELL(s2); /* s2 may be NULL */
1350  BN_CK_TOL(tol);
1351 
1352  eu_orig = eu; /* for printing */
1353  eu1 = eu; /* remember, for loop termination */
1354 
1355  /*
1356  * If this eu is not in s1, or it is a wire,
1357  * advance to first non-wire.
1358  */
1359  for (;;) {
1360  fu = nmg_find_fu_of_eu(eu);
1361  if (!fu) goto next_a; /* it's a wire */
1362  s = fu->s_p;
1363  NMG_CK_SHELL(s);
1364  if (s != s1) goto next_a;
1365  break;
1366  next_a:
1367  eu = eu->radial_p->eumate_p;
1368  if (eu == eu1) goto out; /* wires all around */
1369  }
1370 
1371  curr_orient = fu->orientation;
1372  eur = eu->radial_p;
1373  eurstart = eur;
1374  eu1 = eu; /* virtual radial to eur */
1375 
1376  NMG_CK_EDGEUSE(eur);
1377  do {
1378  /*
1379  * Search until another edgeuse in shell s1 or s2 is found.
1380  * Continue search if it is a wire edge or dangling face.
1381  */
1382  for (;;) {
1383  fu = nmg_find_fu_of_eu(eur);
1384  if (!fu) goto next_eu; /* it's a wire */
1385  NMG_CK_FACEUSE(fu);
1386  s = fu->s_p;
1387  NMG_CK_SHELL(s);
1388  if (s != s1) {
1389  if (!s2) goto next_eu;
1390  if (s != s2) goto next_eu;
1391  }
1392  break;
1393  next_eu:
1394  /* Advance to next eur */
1395  NMG_CK_EDGEUSE(eur->eumate_p);
1396  if (eur->eumate_p->eumate_p != eur)
1397  bu_bomb("nmg_eu_2s_orient_bad: bad edgeuse mate\n");
1398 
1399  eur = eur->eumate_p->radial_p;
1400  NMG_CK_EDGEUSE(eur);
1401  if (eur == eurstart) goto out;
1402  }
1403 
1404  /*
1405  * eur is mate's radial of last eu.
1406  * If the orientation does not match, this is an error.
1407  * If radial (eur) is my (virtual, this-shell) mate (eu1),
1408  * then it's OK, a mis-match is to be expected when there
1409  * is only one edgeuse&mate from this shell on this edge.
1410  */
1411  if (fu->orientation != curr_orient &&
1412  eur != eu1->eumate_p) {
1413  nmg_pr_fu_around_eu(eu_orig, tol);
1414  bu_log("nmg_eu_2s_orient_bad(eu=%p, s1=%p, s2=%p) bad radial parity eu1=%p, eur=%p, eurstart=%p\n",
1415  (void *)eu_orig, (void *)s1, (void *)s2, (void *)eu1, (void *)eur, (void *)eurstart);
1416  ret = 1;
1417  goto out;
1418  }
1419 
1420  /* If eu belongs to a face, eumate had better, also! */
1421  eu1 = eur->eumate_p;
1422  NMG_CK_LOOPUSE(eu1->up.lu_p);
1423  fu = eu1->up.lu_p->up.fu_p;
1424  NMG_CK_FACEUSE(fu);
1425  curr_orient = fu->orientation;
1426  eur = eu1->radial_p;
1427  } while (eur != eurstart);
1428  /* All is well, the whole way 'round */
1429 out:
1430  if (RTG.NMG_debug & DEBUG_BASIC) {
1431  bu_log("nmg_eu_2s_orient_bad(eu=%p, s1=%p, s2=%p) ret=%d\n",
1432  (void *)eu_orig, (void *)s1, (void *)s2, ret);
1433  }
1434  return ret;
1435 }
1436 
1437 
1438 /**
1439  * Verify that shell is closed.
1440  * Do this by verifying that it is not possible to get from outside
1441  * to inside the solid by crossing any face edge.
1442  *
1443  * Returns -
1444  * 0 OK
1445  * !0 Problem.
1446  */
1447 int
1448 nmg_ck_closed_surf(const struct shell *s, const struct bn_tol *tol)
1449 {
1450  struct faceuse *fu;
1451  struct loopuse *lu;
1452  struct edgeuse *eu;
1453  int status = 0;
1454  uint32_t magic1;
1455 
1456  NMG_CK_SHELL(s);
1457  BN_CK_TOL(tol);
1458  for (BU_LIST_FOR(fu, faceuse, &s->fu_hd)) {
1459  NMG_CK_FACEUSE(fu);
1460  for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
1461  NMG_CK_LOOPUSE(lu);
1462  magic1 = BU_LIST_FIRST_MAGIC(&lu->down_hd);
1463  if (magic1 == NMG_EDGEUSE_MAGIC) {
1464  /* Check status on all the edgeuses before quitting */
1465  for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
1466  if (nmg_check_radial(eu, tol))
1467  status = 1;
1468  }
1469  if (status) {
1470  bu_log("nmg_ck_closed_surf(%p), problem with loopuse %p\n", (void *)s, (void *)lu);
1471  return 1;
1472  }
1473  } else if (magic1 == NMG_VERTEXUSE_MAGIC) {
1474  register struct vertexuse *vu;
1475  vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
1476  NMG_CK_VERTEXUSE(vu);
1477  NMG_CK_VERTEX(vu->v_p);
1478  }
1479  }
1480  }
1481  return 0;
1482 }
1483 
1484 
1485 /**
1486  * Check all the shells in a region for being closed.
1487  *
1488  * Returns -
1489  * 0 OK
1490  * !0 status code from nmg_check_radial()
1491  */
1492 int
1493 nmg_ck_closed_region(const struct nmgregion *r, const struct bn_tol *tol)
1494 {
1495  const struct shell *s;
1496  int ret;
1497 
1498  NMG_CK_REGION(r);
1499  BN_CK_TOL(tol);
1500  for (BU_LIST_FOR(s, shell, &r->s_hd)) {
1501  ret = nmg_ck_closed_surf(s, tol);
1502  if (ret != 0) return ret;
1503  }
1504  return 0;
1505 }
1506 
1507 
1508 /**
1509  * accepts a vertex pointer, two faceuses, and a tolerance.
1510  * Checks if the vertex is in both faceuses (topologically
1511  * and geometrically within tolerance of plane).
1512  *
1513  * Calls bu_bomb if vertex is not in the faceuses topology or
1514  * out of tolerance of either face.
1515  *
1516  */
1517 
1518 void
1519 nmg_ck_v_in_2fus(const struct vertex *vp, const struct faceuse *fu1, const struct faceuse *fu2, const struct bn_tol *tol)
1520 {
1521  struct bu_vls str = BU_VLS_INIT_ZERO;
1522  struct faceuse *fu;
1523  struct vertexuse *vu;
1524  fastf_t dist1, dist2;
1525  int found1=0, found2=0;
1526  plane_t n1, n2;
1527 
1528  NMG_CK_VERTEX(vp);
1529  NMG_CK_FACEUSE(fu1);
1530  NMG_CK_FACEUSE(fu2);
1531  BN_CK_TOL(tol);
1532 
1533  /* topology check */
1534  for (BU_LIST_FOR(vu, vertexuse, &vp->vu_hd)) {
1535  fu = nmg_find_fu_of_vu(vu);
1536  if (fu == fu1)
1537  found1 = 1;
1538  if (fu == fu2)
1539  found2 = 1;
1540  if (found1 && found2)
1541  break;
1542  }
1543 
1544  if (!found1 || !found2) {
1545  bu_vls_printf(&str, "nmg_ck_v_in_2fus: vertex %p not used in", (void *)vp);
1546  if (!found1)
1547  bu_vls_printf(&str, " faceuse %p", (void *)fu1);
1548  if (!found2)
1549  bu_vls_printf(&str, " faceuse %p", (void *)fu2);
1550  bu_bomb(bu_vls_addr(&str));
1551  }
1552 
1553  /* geometry check */
1554  NMG_GET_FU_PLANE(n1, fu1);
1555  NMG_GET_FU_PLANE(n2, fu2);
1556  dist1 = DIST_PT_PLANE(vp->vg_p->coord, n1);
1557  dist2 = DIST_PT_PLANE(vp->vg_p->coord, n2);
1558 
1559  if (!NEAR_ZERO(dist1, tol->dist) || !NEAR_ZERO(dist2, tol->dist)) {
1560  bu_vls_printf(&str, "nmg_ck_v_in_2fus: vertex %p (%g %g %g) not in plane of" ,
1561  (void *)vp, V3ARGS(vp->vg_p->coord));
1562  if (!NEAR_ZERO(dist1, tol->dist))
1563  bu_vls_printf(&str, " faceuse %p (off by %g)", (void *)fu1, dist1);
1564  if (!NEAR_ZERO(dist2, tol->dist))
1565  bu_vls_printf(&str, " faceuse %p (off by %g)", (void *)fu2, dist2);
1566  bu_bomb(bu_vls_addr(&str));
1567  }
1568 
1569 }
1570 /**
1571  * Visits every vertex in the region and checks if the
1572  * vertex coordinates are within tolerance of every face
1573  * it is supposed to be in (according to the topology).
1574  *
1575  */
1576 
1577 struct v_ck_state {
1578  char *visited;
1579  struct bu_ptbl *tabl;
1580  struct bn_tol *tol;
1581 };
1582 
1583 
1584 HIDDEN void
1585 nmg_ck_v_in_fus(uint32_t *vp, void *state, int UNUSED(unused))
1586 {
1587  register struct v_ck_state *sp = (struct v_ck_state *)state;
1588  register struct vertex *v = (struct vertex *)vp;
1589 
1590  NMG_CK_VERTEX(v);
1591  /* If this vertex has been processed before, do nothing more */
1592  if (NMG_INDEX_FIRST_TIME(sp->visited, v)) {
1593  struct vertexuse *vu;
1594  struct faceuse *fu;
1595 
1596  for (BU_LIST_FOR(vu, vertexuse, &v->vu_hd)) {
1597  fastf_t dist;
1598 
1599  fu = nmg_find_fu_of_vu(vu);
1600  if (fu) {
1601  plane_t n;
1602 
1603  NMG_CK_FACEUSE(fu);
1604  if (fu->orientation != OT_SAME)
1605  continue;
1606  if (!fu->f_p->g.magic_p)
1607  bu_log("ERROR - nmg_ck_vs_in_region: fu (%p) has no geometry\n", (void *)fu);
1608  else if (*fu->f_p->g.magic_p == NMG_FACE_G_PLANE_MAGIC) {
1609  NMG_GET_FU_PLANE(n, fu);
1610  dist = DIST_PT_PLANE(v->vg_p->coord, n);
1611  if (!NEAR_ZERO(dist, sp->tol->dist)) {
1612  bu_log("ERROR - nmg_ck_vs_in_region: vertex %p (%g %g %g) is %g from faceuse %p\n" ,
1613  (void *)v, V3ARGS(v->vg_p->coord), dist, (void *)fu);
1614  }
1615  }
1616  /* else if (*fu->f_p->g.magic_p == NMG_FACE_G_SNURB_MAGIC) XXXX */
1617  }
1618  }
1619  }
1620 }
1621 
1622 
1623 void
1624 nmg_ck_vs_in_region(const struct nmgregion *r, const struct bn_tol *tol)
1625 {
1626  struct model *m;
1627  struct v_ck_state st;
1628  struct bu_ptbl tab;
1629  static const struct nmg_visit_handlers handlers = {NULL, NULL, NULL, NULL, NULL,
1630  NULL, NULL, NULL, NULL, NULL,
1631  NULL, NULL, NULL, NULL, NULL,
1632  NULL, NULL, NULL, NULL, NULL,
1633  NULL, NULL, NULL, nmg_ck_v_in_fus, NULL};
1634  /* handlers.vis_vertex = nmg_ck_v_in_fus; */
1635 
1636  NMG_CK_REGION(r);
1637  BN_CK_TOL(tol);
1638  m = r->m_p;
1639  NMG_CK_MODEL(m);
1640 
1641  st.visited = (char *)bu_calloc(m->maxindex+1, sizeof(char), "visited[]");
1642  st.tabl = &tab;
1643  st.tol = (struct bn_tol *)tol;
1644 
1645  (void)bu_ptbl_init(&tab, 64, " &tab");
1646 
1647  nmg_visit(&r->l.magic, &handlers, (void *)&st);
1648 
1649  bu_ptbl_free(&tab);
1650 
1651  bu_free((char *)st.visited, "visited[]");
1652 }
1653 
1654 
1655 /*
1656  * Local Variables:
1657  * mode: C
1658  * tab-width: 8
1659  * indent-tabs-mode: t
1660  * c-file-style: "stroustrup"
1661  * End:
1662  * ex: shiftwidth=4 tabstop=8
1663  */
void nmg_vvu(const struct vertexuse *vu, const uint32_t *up_magic_p)
Definition: nmg_ck.c:92
void nmg_ck_eu(const uint32_t *parent, const struct edgeuse *eu, const char *str)
Definition: nmg_ck.c:699
int nmg_ck_face_worthless_edges(const struct faceuse *fu)
Definition: nmg_ck.c:1103
int nmg_ck_closed_surf(const struct shell *s, const struct bn_tol *tol)
Definition: nmg_ck.c:1448
#define BU_LIST_PNEXT_CIRC(structure, p)
Definition: list.h:442
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
#define NMG_EDGEUSE_MAGIC
Definition: magic.h:120
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
struct faceuse * nmg_find_fu_of_eu(const struct edgeuse *eu)
Definition: nmg_info.c:270
void nmg_ck_lg(const struct loop *l, const struct loop_g *lg, const char *str)
Definition: nmg_ck.c:777
void nmg_stash_model_to_file(const char *filename, const struct model *m, const char *title)
Definition: nmg_misc.c:4500
Definition: list.h:118
void nmg_vloop(const struct loop *l, const struct loopuse *lup)
Definition: nmg_ck.c:366
int nmg_ck_geometry(const struct model *m, const struct bn_tol *tol)
Definition: nmg_ck.c:1045
#define NMG_SHELL_MAGIC
Definition: magic.h:142
void nmg_edge_g_tabulate(struct bu_ptbl *tab, const uint32_t *magic_p)
Definition: nmg_info.c:2197
double dist
>= 0
Definition: tol.h:73
#define NMG_FACE_G_SNURB_MAGIC
Definition: magic.h:126
if lu s
Definition: nmg_mod.c:3860
void bu_ptbl_init(struct bu_ptbl *b, size_t len, const char *str)
Definition: ptbl.c:32
lu
Definition: nmg_mod.c:3855
double dist_sq
dist * dist
Definition: tol.h:74
#define SMALL_FASTF
Definition: defines.h:342
void nmg_ck_v_in_2fus(const struct vertex *vp, const struct faceuse *fu1, const struct faceuse *fu2, const struct bn_tol *tol)
Definition: nmg_ck.c:1519
Header file for the BRL-CAD common definitions.
void nmg_ck_vu(const uint32_t *parent, const struct vertexuse *vu, const char *str)
Definition: nmg_ck.c:681
void nmg_vregion(const struct bu_list *hp, const struct model *m)
Definition: nmg_ck.c:607
#define BU_LIST_NON_EMPTY(hp)
Definition: list.h:296
void bu_ptbl_reset(struct bu_ptbl *b)
Definition: ptbl.c:49
void nmg_ck_e(const struct edgeuse *eu, const struct edge *e, const char *str)
Definition: nmg_ck.c:649
#define NMG_LOOPUSE_MAGIC
Definition: magic.h:130
void nmg_vlu(const struct bu_list *hp, const uint32_t *up)
Definition: nmg_ck.c:382
void nmg_vedge(const struct edge *e, const struct edgeuse *eup)
Definition: nmg_ck.c:157
#define HIDDEN
Definition: common.h:86
NMG_CK_LOOPUSE(lu)
BU_LIST_DEQUEUE & eu1
Definition: nmg_mod.c:3839
int nmg_check_radial(const struct edgeuse *eu, const struct bn_tol *tol)
Definition: nmg_ck.c:1210
Definition: ptbl.h:62
Definition: color.c:49
#define NMG_EDGEUSE2_MAGIC
Definition: magic.h:119
struct bu_ptbl * tabl
Definition: nmg_ck.c:1579
void nmg_vvg(const struct vertex_g *vg)
Definition: nmg_ck.c:50
uint32_t NMG_debug
debug bits for NMG's see nmg.h
Definition: raytrace.h:1699
int nmg_eu_2s_orient_bad(const struct edgeuse *eu, const struct shell *s1, const struct shell *s2, const struct bn_tol *tol)
Definition: nmg_ck.c:1336
HIDDEN void nmg_ck_v_in_fus(uint32_t *vp, void *state, int unused)
Definition: nmg_ck.c:1585
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
#define BU_PTBL_GET(ptbl, i)
Definition: ptbl.h:108
#define BU_LIST_PNEXT_PLAST(structure, p)
Definition: list.h:432
void nmg_face_lu_plot(const struct loopuse *lu, const struct vertexuse *vu1, const struct vertexuse *vu2)
Definition: nmg_plot.c:1971
#define V3ARGS(a)
Definition: color.c:56
void nmg_ck_fg(const struct face *f, const struct face_g_plane *fg, const char *str)
Definition: nmg_ck.c:884
#define NEAR_ZERO(val, epsilon)
Definition: color.c:55
void nmg_pr_lu_briefly(const struct loopuse *lu, char *h)
Definition: nmg_pr.c:455
void nmg_vlg(const struct loop_g *lg)
Definition: nmg_ck.c:350
void nmg_veg(const uint32_t *eg)
Definition: nmg_ck.c:122
oldeumate l2 magic
Definition: nmg_mod.c:3843
#define UNUSED(parameter)
Definition: common.h:239
goto out
Definition: nmg_mod.c:3846
int nmg_ck_eg_verts(const struct edge_g_lseg *eg, const struct bn_tol *tol)
Definition: nmg_ck.c:990
struct faceuse * nmg_find_fu_of_vu(const struct vertexuse *vu)
Definition: nmg_info.c:304
Support for uniform tolerances.
Definition: tol.h:71
struct shell * nmg_find_s_of_eu(const struct edgeuse *eu)
Definition: nmg_info.c:235
#define BN_CK_TOL(_p)
Definition: tol.h:82
#define BU_LIST_FIRST_MAGIC(hp)
Definition: list.h:416
char * visited
Definition: nmg_ck.c:1578
void nmg_ck_fu(const struct shell *s, const struct faceuse *fu, const char *str)
Definition: nmg_ck.c:928
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
void nmg_ck_l(const struct loopuse *lu, const struct loop *l, const char *str)
Definition: nmg_ck.c:793
void nmg_ck_f(const struct faceuse *fu, const struct face *f, const char *str)
Definition: nmg_ck.c:905
#define NMG_VERTEXUSE_MAGIC
Definition: magic.h:145
void nmg_vshell(const struct bu_list *hp, const struct nmgregion *r)
Definition: nmg_ck.c:591
void nmg_ck_lueu(const struct loopuse *cklu, const char *s)
Definition: nmg_ck.c:1138
void nmg_visit(const uint32_t *magicp, const struct nmg_visit_handlers *htab, void *state)
Definition: nmg_visit.c:263
#define BU_LIST_MAIN_PTR(_type, _ptr2, _name2)
Definition: list.h:470
void nmg_vmodel(const struct model *m)
Definition: nmg_ck.c:635
#define NMG_FACE_G_PLANE_MAGIC
Definition: magic.h:125
void nmg_vvua(const uint32_t *vua)
Definition: nmg_ck.c:82
void bu_ptbl_free(struct bu_ptbl *b)
Definition: ptbl.c:226
#define BU_LIST_PPREV_CIRC(structure, p)
Definition: list.h:450
#define NMG_EDGE_G_LSEG_MAGIC
Definition: magic.h:122
#define ZERO(val)
Definition: units.c:38
struct bn_tol * tol
Definition: nmg_ck.c:1580
void nmg_vfg(const struct face_g_plane *fg)
Definition: nmg_ck.c:441
#define BU_PTBL_END(ptbl)
Definition: ptbl.h:106
#define NMG_EDGE_G_CNURB_MAGIC
Definition: magic.h:121
void nmg_pr_lu(const struct loopuse *lu, char *h)
Definition: nmg_pr.c:405
#define BU_LIST_PLAST_PNEXT(structure, p)
Definition: list.h:434
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
void nmg_pr_fu_around_eu(const struct edgeuse *eu, const struct bn_tol *tol)
Definition: nmg_pr.c:953
void nmg_ck_vs_in_region(const struct nmgregion *r, const struct bn_tol *tol)
Definition: nmg_ck.c:1624
Definition: color.c:51
void nmg_vsshell(const struct shell *s, const struct nmgregion *r)
Definition: nmg_ck.c:541
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
NMG_CK_SHELL(s)
void nmg_face_tabulate(struct bu_ptbl *tab, const uint32_t *magic_p)
Definition: nmg_info.c:2247
int nmg_ck_fg_verts(struct faceuse *fu1, struct face *f2, const struct bn_tol *tol)
Definition: nmg_fuse.c:1526
void nmg_vface(const struct face *f, const struct faceuse *fup)
Definition: nmg_ck.c:462
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
#define BU_LIST_HEAD_MAGIC
Definition: magic.h:56
void nmg_veu(const struct bu_list *hp, const uint32_t *up_magic_p)
Definition: nmg_ck.c:222
void bu_ck_list_magic(const struct bu_list *hd, const char *str, const uint32_t magic)
Definition: list.c:157
#define NMG_FACEUSE_MAGIC
Definition: magic.h:124
Definition: vls.h:56
int nmg_ck_closed_region(const struct nmgregion *r, const struct bn_tol *tol)
Definition: nmg_ck.c:1493
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
double fastf_t
Definition: defines.h:300
const char * bu_identify_magic(uint32_t magic)
eu2
Definition: nmg_mod.c:3875
char * nmg_orientation(int orientation)
Definition: nmg_pr.c:50
void nmg_vfu(const struct bu_list *hp, const struct shell *s)
Definition: nmg_ck.c:488
Definition: color.c:50
#define BU_LIST_FIRST(structure, hp)
Definition: list.h:312
void nmg_vvertex(const struct vertex *v, const struct vertexuse *vup)
Definition: nmg_ck.c:60
#define bu_strlcat(dst, src, size)
Definition: str.h:50
void nmg_ck_lu(const uint32_t *parent, const struct loopuse *lu, const char *str)
Definition: nmg_ck.c:816
struct rt_g RTG
Definition: globals.c:39
struct model * nmg_find_model(const uint32_t *magic_p_arg)
Definition: nmg_info.c:57