00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef lint
00038 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/nmg_manif.c,v 14.12 2006/09/16 02:04:25 lbutler Exp $ (ARL)";
00039 #endif
00040
00041 #include "common.h"
00042
00043
00044 #include <stdio.h>
00045 #ifdef HAVE_STRING_H
00046 #include <string.h>
00047 #else
00048 #include <strings.h>
00049 #endif
00050 #include "machine.h"
00051 #include "vmath.h"
00052 #include "nmg.h"
00053 #include "raytrace.h"
00054
00055 #define PAINT_INTERIOR 1
00056 #define PAINT_EXTERIOR 0
00057
00058 #define BU_LIST_LINK_CHECK( p ) \
00059 if (BU_LIST_PNEXT_PLAST(bu_list, p) != p || \
00060 BU_LIST_PLAST_PNEXT(bu_list, p) != p) { \
00061 bu_log("%s[%d]: linked list integrity check failed\n", \
00062 __FILE__, __LINE__); \
00063 bu_log("0x%08x->forw(0x%08x)->back = 0x%08x\n", \
00064 (p), (p)->forw, (p)->forw->back); \
00065 bu_log("0x%08x->back(0x%08x)->forw = 0x%08x\n", \
00066 (p), (p)->back, (p)->back->forw); \
00067 rt_bomb("Goodbye\n"); \
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 int
00080 nmg_dangling_face(const struct faceuse *fu, register const char *manifolds)
00081 {
00082 struct loopuse *lu;
00083 struct edgeuse *eu;
00084 const struct edgeuse *eur;
00085 struct faceuse *newfu;
00086
00087 NMG_CK_FACEUSE(fu);
00088
00089 if (rt_g.NMG_debug & DEBUG_MANIF)
00090 bu_log("nmg_dangling_face(0x%08x 0x%08x)\n", fu, manifolds);
00091
00092 for(BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
00093 NMG_CK_LOOPUSE(lu);
00094 BU_LIST_LINK_CHECK( &lu->l );
00095
00096 if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC) {
00097
00098
00099
00100
00101
00102
00103 for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
00104
00105 NMG_CK_EDGEUSE( eu );
00106 BU_LIST_LINK_CHECK( &eu->l );
00107
00108 eur = nmg_radial_face_edge_in_shell(eu);
00109 newfu = eur->up.lu_p->up.fu_p;
00110
00111
00112
00113
00114 while (manifolds &&
00115 NMG_MANIFOLDS(manifolds,newfu) & NMG_2MANIFOLD &&
00116 eur != eu->eumate_p) {
00117 eur = nmg_radial_face_edge_in_shell(
00118 eur->eumate_p);
00119 newfu = eur->up.lu_p->up.fu_p;
00120 }
00121
00122 if (eur == eu->eumate_p) {
00123 goto out;
00124 }
00125 }
00126 }
00127 }
00128 eur = (const struct edgeuse *)NULL;
00129
00130 out:
00131 if (rt_g.NMG_debug & DEBUG_BASIC) {
00132 struct bn_tol tol;
00133 tol.magic = BN_TOL_MAGIC;
00134 tol.dist = 1;
00135 tol.dist_sq = tol.dist * tol.dist;
00136 tol.perp = 1e-5;
00137 tol.para = 1 - tol.perp;
00138
00139 bu_log("nmg_dangling_face(fu=x%x, manifolds=x%x) dangling_eu=x%x\n", fu, manifolds, eur);
00140 if( eur ) nmg_pr_fu_around_eu( eur, &tol );
00141 }
00142 if ((rt_g.NMG_debug & DEBUG_MANIF) && (eur != (const struct edgeuse *)NULL) )
00143 bu_log( "\tdangling eu x%x\n", eur );
00144
00145 return eur != (const struct edgeuse *)NULL;
00146 }
00147
00148
00149
00150
00151
00152 static void paint_face(struct faceuse *fu, char *paint_table, int paint_color, char *paint_meaning, char *tbl)
00153 {
00154 struct faceuse *newfu;
00155 struct loopuse *lu;
00156 struct edgeuse *eu;
00157 const struct edgeuse *eur;
00158
00159 #if 1
00160 if (rt_g.NMG_debug & DEBUG_MANIF)
00161 bu_log("nmg_paint_face(%08x, %d)\n", fu, paint_color);
00162 #endif
00163 if (NMG_INDEX_VALUE(paint_table, fu->index) != 0)
00164 return;
00165
00166 NMG_INDEX_ASSIGN(paint_table, fu, paint_color);
00167
00168 for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
00169
00170 if (rt_g.NMG_debug & DEBUG_MANIF)
00171 bu_log( "\tlu=x%x\n", lu );
00172
00173 NMG_CK_LOOPUSE( lu );
00174 BU_LIST_LINK_CHECK( &lu->l );
00175
00176 if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
00177 continue;
00178
00179 for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
00180 if (rt_g.NMG_debug & DEBUG_MANIF)
00181 bu_log( "\t\teu=x%x\n", eu );
00182 NMG_CK_EDGEUSE(eu);
00183 NMG_CK_EDGEUSE(eu->eumate_p);
00184 eur = nmg_radial_face_edge_in_shell(eu);
00185 NMG_CK_EDGEUSE(eur);
00186 NMG_CK_FACEUSE(eur->up.lu_p->up.fu_p);
00187 newfu = eur->up.lu_p->up.fu_p;
00188
00189 if (rt_g.NMG_debug & DEBUG_MANIF)
00190 bu_log( "\t\t\teur=x%x, newfu=x%x\n", eur, newfu );
00191
00192 BU_LIST_LINK_CHECK( &eu->l );
00193 BU_LIST_LINK_CHECK( &eur->l );
00194
00195 while (NMG_MANIFOLDS(tbl, newfu) & NMG_2MANIFOLD &&
00196 eur != eu->eumate_p) {
00197 eur = nmg_radial_face_edge_in_shell(
00198 eur->eumate_p);
00199 newfu = eur->up.lu_p->up.fu_p;
00200
00201 if (rt_g.NMG_debug & DEBUG_MANIF)
00202 bu_log( "\t\t\teur=x%x, newfu=x%x\n", eur, newfu );
00203 }
00204
00205 if( newfu == fu->fumate_p )
00206 continue;
00207 else if (newfu->orientation == OT_SAME)
00208 paint_face(newfu,paint_table,paint_color,
00209 paint_meaning,tbl);
00210 else {
00211
00212 paint_meaning[paint_color] = PAINT_INTERIOR;
00213
00214 if (rt_g.NMG_debug & DEBUG_MANIF)
00215 bu_log( "\t---- Painting fu x%x as interior, new_fu = x%x, eu=x%x, eur=x%x\n", fu, newfu, eu, eur );
00216 }
00217 }
00218 }
00219 }
00220
00221 static void set_edge_sub_manifold(char *tbl, struct edgeuse *eu_p, char manifold)
00222 {
00223
00224 NMG_CK_EDGEUSE(eu_p);
00225 NMG_CK_EDGE(eu_p->e_p);
00226 NMG_CK_VERTEXUSE(eu_p->vu_p);
00227 NMG_CK_VERTEX(eu_p->vu_p->v_p);
00228
00229 NMG_SET_MANIFOLD(tbl, eu_p, manifold);
00230 NMG_SET_MANIFOLD(tbl, eu_p->e_p, manifold);
00231
00232 NMG_SET_MANIFOLD(tbl, eu_p->vu_p, manifold);
00233 NMG_SET_MANIFOLD(tbl, eu_p->vu_p->v_p, manifold);
00234 }
00235
00236
00237 static void set_loop_sub_manifold(char *tbl, struct loopuse *lu_p, char manifold)
00238 {
00239 struct edgeuse *eu_p;
00240 struct vertexuse *vu_p;
00241 #if 0
00242 if (rt_g.NMG_debug & DEBUG_MANIF)
00243 bu_log("nmg_set_loop_sub_manifold(%08x)\n", lu_p);
00244 #endif
00245 NMG_CK_LOOPUSE(lu_p);
00246
00247 NMG_SET_MANIFOLD(tbl, lu_p, manifold);
00248 NMG_SET_MANIFOLD(tbl, lu_p->l_p, manifold);
00249 if (BU_LIST_FIRST_MAGIC(&lu_p->down_hd) == NMG_VERTEXUSE_MAGIC) {
00250 vu_p = BU_LIST_FIRST(vertexuse, &lu_p->down_hd);
00251 NMG_SET_MANIFOLD(tbl, vu_p, manifold);
00252 NMG_SET_MANIFOLD(tbl, vu_p->v_p, manifold);
00253 } else if (BU_LIST_FIRST_MAGIC(&lu_p->down_hd) == NMG_EDGEUSE_MAGIC) {
00254 for (BU_LIST_FOR(eu_p, edgeuse, &lu_p->down_hd)) {
00255 BU_LIST_LINK_CHECK( &eu_p->l );
00256 set_edge_sub_manifold(tbl, eu_p, manifold);
00257 }
00258 } else
00259 rt_bomb("bad child of loopuse\n");
00260 }
00261 static void set_face_sub_manifold(char *tbl, struct faceuse *fu_p, char manifold)
00262 {
00263 struct loopuse *lu_p;
00264
00265 NMG_CK_FACEUSE(fu_p);
00266 NMG_CK_FACE(fu_p->f_p);
00267
00268 NMG_SET_MANIFOLD(tbl, fu_p, manifold);
00269 NMG_SET_MANIFOLD(tbl, fu_p->f_p, manifold);
00270 for (BU_LIST_FOR(lu_p, loopuse, &fu_p->lu_hd)) {
00271 BU_LIST_LINK_CHECK( &lu_p->l );
00272 set_loop_sub_manifold(tbl, lu_p, manifold);
00273 }
00274 }
00275
00276
00277
00278 char *
00279 nmg_shell_manifolds(struct shell *sp, char *tbl)
00280 {
00281 struct edgeuse *eu_p;
00282 struct loopuse *lu_p;
00283 struct faceuse *fu_p;
00284 char *paint_meaning, *paint_table, paint_color;
00285 int found;
00286
00287 if (rt_g.NMG_debug & DEBUG_MANIF)
00288 bu_log("nmg_shell_manifolds(%08x)\n", sp);
00289
00290 NMG_CK_SHELL(sp);
00291
00292 if (tbl == (char *)NULL)
00293 tbl = bu_calloc(sp->r_p->m_p->maxindex, 1, "manifold table");
00294
00295
00296
00297
00298 if (sp->vu_p) {
00299 NMG_CK_VERTEXUSE(sp->vu_p);
00300 NMG_SET_MANIFOLD(tbl, sp, NMG_0MANIFOLD);
00301 NMG_SET_MANIFOLD(tbl, sp->vu_p, NMG_0MANIFOLD);
00302 NMG_SET_MANIFOLD(tbl, sp->vu_p->v_p, NMG_0MANIFOLD);
00303 BU_LIST_LINK_CHECK( &sp->vu_p->l );
00304 }
00305
00306
00307
00308
00309 if (BU_LIST_NON_EMPTY(&sp->eu_hd)) {
00310
00311 for (BU_LIST_FOR(eu_p, edgeuse, &sp->eu_hd)) {
00312 BU_LIST_LINK_CHECK( &eu_p->l );
00313 set_edge_sub_manifold(tbl, eu_p, NMG_1MANIFOLD);
00314 }
00315 NMG_SET_MANIFOLD(tbl, sp, NMG_1MANIFOLD);
00316 }
00317
00318
00319
00320
00321 if (BU_LIST_NON_EMPTY(&sp->lu_hd)) {
00322
00323 for (BU_LIST_FOR(lu_p, loopuse, &sp->lu_hd)) {
00324 BU_LIST_LINK_CHECK( &lu_p->l );
00325
00326 set_loop_sub_manifold(tbl, lu_p, NMG_1MANIFOLD);
00327 }
00328 NMG_SET_MANIFOLD(tbl, sp, NMG_1MANIFOLD);
00329 }
00330
00331 if (rt_g.NMG_debug & DEBUG_MANIF)
00332 bu_log("starting manifold classification on shell faces\n");
00333
00334
00335
00336
00337 if (BU_LIST_IS_EMPTY(&sp->fu_hd))
00338 return tbl;
00339
00340
00341
00342
00343
00344 do {
00345 found = 0;
00346 for (BU_LIST_FOR(fu_p, faceuse, &sp->fu_hd)) {
00347 NMG_CK_FACEUSE(fu_p);
00348 BU_LIST_LINK_CHECK( &fu_p->l );
00349
00350
00351
00352
00353 if (NMG_MANIFOLDS(tbl,fu_p) & NMG_2MANIFOLD)
00354 continue;
00355
00356 if (nmg_dangling_face(fu_p, tbl)) {
00357 found = 1;
00358
00359 NMG_SET_MANIFOLD(tbl, fu_p, NMG_2MANIFOLD);
00360
00361 if (rt_g.NMG_debug & DEBUG_MANIF)
00362 bu_log("found dangling face\n");
00363 }
00364 }
00365 } while (found);
00366
00367
00368
00369
00370
00371 if (rt_g.NMG_debug & DEBUG_MANIF)
00372 bu_log("starting to paint non-dangling faces\n");
00373
00374 paint_meaning = bu_calloc(256, 1, "paint meaning table");
00375 paint_table = bu_calloc(sp->r_p->m_p->maxindex, 1, "paint table");
00376 paint_color = 1;
00377
00378 for (BU_LIST_FOR(fu_p, faceuse, &sp->fu_hd)) {
00379 BU_LIST_LINK_CHECK( &fu_p->l );
00380
00381 if (fu_p->orientation != OT_SAME ||
00382 NMG_INDEX_VALUE(paint_table, fu_p->index) != 0)
00383 continue;
00384
00385 paint_face(fu_p, paint_table, paint_color, paint_meaning, tbl);
00386 paint_color++;
00387 }
00388
00389
00390 if (rt_g.NMG_debug & DEBUG_MANIF)
00391 bu_log("painting done, looking at colors\n");
00392
00393
00394
00395
00396
00397
00398 for (BU_LIST_FOR(fu_p, faceuse, &sp->fu_hd)) {
00399 BU_LIST_LINK_CHECK( &fu_p->l );
00400
00401 paint_color = NMG_INDEX_VALUE(paint_table,
00402 fu_p->index);
00403
00404 if (NMG_INDEX_VALUE(paint_meaning, (int)paint_color) ==
00405 PAINT_INTERIOR) {
00406 set_face_sub_manifold(tbl, fu_p, NMG_2MANIFOLD);
00407 } else if (NMG_INDEX_VALUE(paint_meaning, (int)paint_color)
00408 == PAINT_EXTERIOR) {
00409 set_face_sub_manifold(tbl, fu_p, NMG_3MANIFOLD);
00410 }
00411 }
00412
00413 bu_free(paint_meaning, "paint meaning table");
00414 bu_free(paint_table, "paint table");
00415
00416 for (BU_LIST_FOR(fu_p, faceuse, &sp->fu_hd)) {
00417 BU_LIST_LINK_CHECK( &fu_p->l );
00418
00419 if (fu_p->orientation != OT_SAME)
00420 NMG_CP_MANIFOLD(tbl, fu_p, fu_p->fumate_p);
00421 }
00422
00423 return(tbl);
00424 }
00425
00426
00427 char *
00428 nmg_manifolds(struct model *m)
00429 {
00430 struct nmgregion *rp;
00431 struct shell *sp;
00432 char *tbl;
00433
00434
00435 NMG_CK_MODEL(m);
00436 if (rt_g.NMG_debug & DEBUG_MANIF)
00437 bu_log("nmg_manifolds(%08x)\n", m);
00438
00439 tbl = bu_calloc(m->maxindex, 1, "manifold table");
00440
00441
00442 for (BU_LIST_FOR(rp, nmgregion, &m->r_hd)) {
00443 NMG_CK_REGION(rp);
00444 BU_LIST_LINK_CHECK( &rp->l );
00445
00446 for (BU_LIST_FOR(sp, shell, &rp->s_hd)) {
00447
00448 NMG_CK_SHELL( sp );
00449 BU_LIST_LINK_CHECK( &sp->l );
00450
00451 nmg_shell_manifolds(sp, tbl);
00452
00453
00454
00455
00456 NMG_CP_MANIFOLD(tbl, rp, sp);
00457 }
00458 }
00459
00460 return(tbl);
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472