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
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #ifndef lint
00053 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/nmg_plot.c,v 14.14 2006/09/16 02:04:25 lbutler Exp $ (ARL)";
00054 #endif
00055
00056 #include "common.h"
00057
00058 #include <stdlib.h>
00059 #include <stdio.h>
00060 #include <string.h>
00061 #include <fcntl.h>
00062 #include <signal.h>
00063
00064 #include "machine.h"
00065 #include "vmath.h"
00066 #include "nmg.h"
00067 #include "raytrace.h"
00068 #include "nurb.h"
00069 #include "plot3.h"
00070
00071
00072 #define US_DELAY 10
00073
00074 void (*nmg_plot_anim_upcall)();
00075 void (*nmg_vlblock_anim_upcall)();
00076 void (*nmg_mged_debug_display_hack)();
00077 double nmg_eue_dist = 0.05;
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 void
00092 nmg_vu_to_vlist(struct bu_list *vhead, const struct vertexuse *vu)
00093 {
00094 struct vertex *v;
00095 register struct vertex_g *vg;
00096
00097 NMG_CK_VERTEXUSE(vu);
00098 v = vu->v_p;
00099 NMG_CK_VERTEX(v);
00100 vg = v->vg_p;
00101 if( vg ) {
00102
00103 NMG_CK_VERTEX_G(vg);
00104 RT_ADD_VLIST( vhead, vg->coord, BN_VLIST_LINE_MOVE );
00105 RT_ADD_VLIST( vhead, vg->coord, BN_VLIST_LINE_DRAW );
00106 }
00107 }
00108
00109
00110
00111
00112
00113
00114 void
00115 nmg_eu_to_vlist(struct bu_list *vhead, const struct bu_list *eu_hd)
00116 {
00117 struct edgeuse *eu;
00118 struct edgeuse *eumate;
00119 struct vertexuse *vu;
00120 struct vertexuse *vumate;
00121 register struct vertex_g *vg;
00122 register struct vertex_g *vgmate;
00123
00124
00125 for( BU_LIST_FOR( eu, edgeuse, eu_hd ) ) {
00126
00127 NMG_CK_EDGEUSE(eu);
00128 vu = eu->vu_p;
00129 NMG_CK_VERTEXUSE(vu);
00130 NMG_CK_VERTEX(vu->v_p);
00131 vg = vu->v_p->vg_p;
00132
00133 eumate = eu->eumate_p;
00134 NMG_CK_EDGEUSE(eumate);
00135 vumate = eumate->vu_p;
00136 NMG_CK_VERTEXUSE(vumate);
00137 NMG_CK_VERTEX(vumate->v_p);
00138 vgmate = vumate->v_p->vg_p;
00139
00140 if( !vg || !vgmate ) {
00141 bu_log("nmg_eu_to_vlist() no vg or mate?\n");
00142 continue;
00143 }
00144 NMG_CK_VERTEX_G(vg);
00145 NMG_CK_VERTEX_G(vgmate);
00146
00147 RT_ADD_VLIST( vhead, vg->coord, BN_VLIST_LINE_MOVE );
00148 RT_ADD_VLIST( vhead, vgmate->coord, BN_VLIST_LINE_DRAW );
00149 }
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159 void
00160 nmg_lu_to_vlist(struct bu_list *vhead, const struct loopuse *lu, int poly_markers, const vectp_t normal)
00161
00162
00163
00164
00165 {
00166 const struct edgeuse *eu;
00167 const struct vertexuse *vu;
00168 const struct vertex *v;
00169 register const struct vertex_g *vg;
00170 const struct vertex_g *first_vg;
00171 const struct vertexuse *first_vu;
00172 int isfirst;
00173 point_t centroid;
00174 int npoints;
00175
00176 BU_CK_LIST_HEAD(vhead);
00177
00178 NMG_CK_LOOPUSE(lu);
00179 if( BU_LIST_FIRST_MAGIC(&lu->down_hd)==NMG_VERTEXUSE_MAGIC ) {
00180
00181 vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
00182 nmg_vu_to_vlist( vhead, vu );
00183 return;
00184 }
00185
00186
00187 isfirst = 1;
00188 first_vg = (struct vertex_g *)0;
00189 first_vu = (struct vertexuse *)0;
00190 npoints = 0;
00191 VSETALL( centroid, 0 );
00192 for( BU_LIST_FOR( eu, edgeuse, &lu->down_hd ) ) {
00193
00194
00195 NMG_CK_EDGEUSE(eu);
00196 vu = eu->vu_p;
00197 NMG_CK_VERTEXUSE(vu);
00198 v = vu->v_p;
00199 NMG_CK_VERTEX(v);
00200 vg = v->vg_p;
00201 if( !vg ) {
00202 continue;
00203 }
00204 NMG_CK_VERTEX_G(vg);
00205 VADD2( centroid, centroid, vg->coord );
00206 npoints++;
00207 if (isfirst) {
00208 if( poly_markers & NMG_VLIST_STYLE_POLYGON ) {
00209
00210 RT_ADD_VLIST( vhead, normal, BN_VLIST_POLY_START );
00211 if( poly_markers & NMG_VLIST_STYLE_USE_VU_NORMALS
00212 && vu->a.magic_p ) {
00213 RT_ADD_VLIST( vhead,
00214 vu->a.plane_p->N,
00215 BN_VLIST_POLY_VERTNORM );
00216 }
00217 RT_ADD_VLIST( vhead, vg->coord, BN_VLIST_POLY_MOVE );
00218 } else {
00219
00220 RT_ADD_VLIST( vhead, vg->coord, BN_VLIST_LINE_MOVE );
00221 }
00222 isfirst = 0;
00223 first_vg = vg;
00224 first_vu = vu;
00225 } else {
00226 if( poly_markers & NMG_VLIST_STYLE_POLYGON ) {
00227 if( poly_markers & NMG_VLIST_STYLE_USE_VU_NORMALS
00228 && vu->a.magic_p ) {
00229 RT_ADD_VLIST( vhead,
00230 vu->a.plane_p->N,
00231 BN_VLIST_POLY_VERTNORM );
00232 }
00233 RT_ADD_VLIST( vhead, vg->coord, BN_VLIST_POLY_DRAW );
00234 } else {
00235
00236 RT_ADD_VLIST( vhead, vg->coord, BN_VLIST_LINE_DRAW );
00237 }
00238 }
00239
00240 if( !eu->g.magic_p )
00241 continue;
00242
00243
00244 if( *eu->g.magic_p != NMG_EDGE_G_CNURB_MAGIC ) continue;
00245
00246
00247 nmg_cnurb_to_vlist( vhead, eu, 10,
00248 (poly_markers & NMG_VLIST_STYLE_POLYGON ) ?
00249 BN_VLIST_POLY_DRAW : BN_VLIST_LINE_DRAW );
00250 }
00251
00252
00253 if( !isfirst && first_vg ) {
00254 if( poly_markers & NMG_VLIST_STYLE_POLYGON ) {
00255
00256 if( poly_markers & NMG_VLIST_STYLE_USE_VU_NORMALS
00257 && first_vu->a.magic_p ) {
00258 RT_ADD_VLIST( vhead,
00259 first_vu->a.plane_p->N,
00260 BN_VLIST_POLY_VERTNORM );
00261 }
00262 RT_ADD_VLIST( vhead, first_vg->coord, BN_VLIST_POLY_END );
00263 } else {
00264
00265 RT_ADD_VLIST( vhead, first_vg->coord, BN_VLIST_LINE_DRAW );
00266 }
00267 }
00268 if( (poly_markers & NMG_VLIST_STYLE_VISUALIZE_NORMALS) && npoints > 2 ) {
00269
00270 double f;
00271 vect_t tocent;
00272 point_t tip;
00273 struct faceuse *fu;
00274 struct face *fp;
00275
00276 if( *lu->up.magic_p == NMG_FACEUSE_MAGIC )
00277 {
00278 fu = lu->up.fu_p;
00279 NMG_CK_FACEUSE( fu );
00280
00281 fp = fu->f_p;
00282 }
00283 else
00284 fp = (struct face *)NULL;
00285
00286 f = 1.0 / npoints;
00287 VSCALE( centroid, centroid, f );
00288 VSUB2( tocent, first_vg->coord, centroid );
00289 f = MAGNITUDE( tocent ) * 0.5;
00290 if( *fp->g.magic_p != NMG_FACE_G_SNURB_MAGIC )
00291 {
00292
00293 RT_ADD_VLIST( vhead, centroid, BN_VLIST_LINE_MOVE );
00294 VJOIN1( tip, centroid, f, normal );
00295 RT_ADD_VLIST( vhead, tip, BN_VLIST_LINE_DRAW );
00296 }
00297
00298
00299 for( BU_LIST_FOR( eu, edgeuse, &lu->down_hd ) ) {
00300 struct vertexuse_a_plane *vua;
00301
00302 vu = eu->vu_p;
00303 if( !vu->a.magic_p || *vu->a.magic_p != NMG_VERTEXUSE_A_PLANE_MAGIC ) continue;
00304 vua = vu->a.plane_p;
00305 v = vu->v_p;
00306 vg = v->vg_p;
00307 if( !vg ) continue;
00308 NMG_CK_VERTEX_G(vg);
00309 RT_ADD_VLIST( vhead, vg->coord, BN_VLIST_LINE_MOVE );
00310 VJOIN1( tip, vg->coord, f, vua->N );
00311 RT_ADD_VLIST( vhead, tip, BN_VLIST_LINE_DRAW );
00312 }
00313 }
00314 }
00315
00316
00317
00318
00319 void
00320 nmg_snurb_fu_to_vlist(struct bu_list *vhead, const struct faceuse *fu, int poly_markers)
00321 {
00322 struct face_g_snurb *fg;
00323
00324 BU_CK_LIST_HEAD(vhead);
00325
00326 NMG_CK_FACEUSE(fu);
00327 NMG_CK_FACE(fu->f_p);
00328 fg = fu->f_p->g.snurb_p;
00329 NMG_CK_FACE_G_SNURB(fg);
00330
00331
00332 nmg_snurb_to_vlist( vhead, fg, 10 );
00333
00334 if( poly_markers & NMG_VLIST_STYLE_VISUALIZE_NORMALS )
00335 {
00336 fastf_t f;
00337 point_t uv_centroid;
00338 point_t mid_srf;
00339 point_t corner;
00340 vect_t fu_norm;
00341 vect_t tocent;
00342 point_t tip;
00343
00344 uv_centroid[0] = (fg->u.knots[fg->u.k_size-1] + fg->u.knots[0])/2.0;
00345 uv_centroid[1] = (fg->v.knots[fg->v.k_size-1] + fg->v.knots[0])/2.0;
00346 uv_centroid[2] = 1.0;
00347
00348 nmg_snurb_fu_get_norm( fu, uv_centroid[0], uv_centroid[1], fu_norm );
00349 nmg_snurb_fu_eval( fu, uv_centroid[0], uv_centroid[1], mid_srf );
00350
00351 nmg_snurb_fu_eval( fu, fg->u.knots[0], fg->v.knots[0], corner );
00352 VSUB2( tocent, corner, mid_srf );
00353 f = MAGNITUDE( tocent ) * 0.5;
00354
00355 RT_ADD_VLIST( vhead, mid_srf, BN_VLIST_LINE_MOVE );
00356 VJOIN1( tip, mid_srf, f, fu_norm );
00357 RT_ADD_VLIST( vhead, tip, BN_VLIST_LINE_DRAW );
00358 }
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 void
00372 nmg_s_to_vlist(struct bu_list *vhead, const struct shell *s, int poly_markers)
00373 {
00374 struct faceuse *fu;
00375 struct face_g_plane *fg;
00376 register struct loopuse *lu;
00377 vect_t normal;
00378
00379 NMG_CK_SHELL(s);
00380
00381
00382 for( BU_LIST_FOR( fu, faceuse, &s->fu_hd ) ) {
00383 vect_t n;
00384
00385
00386 NMG_CK_FACEUSE(fu);
00387 if (fu->orientation != OT_SAME) continue;
00388 NMG_CK_FACE(fu->f_p);
00389
00390 if( fu->f_p->g.magic_p && *fu->f_p->g.magic_p == NMG_FACE_G_SNURB_MAGIC ) {
00391
00392 if( !(poly_markers & NMG_VLIST_STYLE_NO_SURFACES) )
00393 nmg_snurb_fu_to_vlist( vhead, fu, poly_markers );
00394
00395 VSET( n, 1, 0, 0 );
00396 for( BU_LIST_FOR( lu, loopuse, &fu->lu_hd ) ) {
00397 nmg_lu_to_vlist( vhead, lu, poly_markers, n );
00398 }
00399 continue;
00400 }
00401
00402
00403 fg = fu->f_p->g.plane_p;
00404 NMG_CK_FACE_G_PLANE(fg);
00405 NMG_GET_FU_NORMAL( n, fu );
00406 for( BU_LIST_FOR( lu, loopuse, &fu->lu_hd ) ) {
00407 nmg_lu_to_vlist( vhead, lu, poly_markers, n );
00408 }
00409 }
00410
00411
00412 VSETALL(normal, 0);
00413 for( BU_LIST_FOR( lu, loopuse, &s->lu_hd ) ) {
00414 nmg_lu_to_vlist( vhead, lu, 0, normal );
00415 }
00416
00417
00418 nmg_eu_to_vlist( vhead, &s->eu_hd );
00419
00420
00421 if (s->vu_p) {
00422 nmg_vu_to_vlist( vhead, s->vu_p );
00423 }
00424 }
00425
00426
00427
00428
00429 void
00430 nmg_r_to_vlist(struct bu_list *vhead, const struct nmgregion *r, int poly_markers)
00431 {
00432 register struct shell *s;
00433
00434 NMG_CK_REGION( r );
00435 for( BU_LIST_FOR( s, shell, &r->s_hd ) ) {
00436 nmg_s_to_vlist( vhead, s, poly_markers );
00437 }
00438 }
00439
00440
00441
00442
00443
00444 void
00445 nmg_m_to_vlist(struct bu_list *vhead, struct model *m, int poly_markers)
00446 {
00447 register struct nmgregion *r;
00448
00449 NMG_CK_MODEL( m );
00450 for( BU_LIST_FOR( r, nmgregion, &m->r_hd ) ) {
00451 NMG_CK_REGION( r );
00452 nmg_r_to_vlist( vhead, r, poly_markers );
00453 }
00454 }
00455
00456
00457
00458
00459
00460
00461 #define LEE_DIVIDE_TOL (1.0e-5)
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476 void
00477 nmg_offset_eu_vert(fastf_t *base, const struct edgeuse *eu, const fastf_t *face_normal, int tip)
00478 {
00479 struct edgeuse *prev_eu;
00480 const struct edgeuse *this_eu;
00481 vect_t prev_vec;
00482 vect_t eu_vec;
00483 vect_t prev_left;
00484 vect_t eu_left;
00485 vect_t delta_vec;
00486 struct vertex_g *this_vg, *mate_vg, *prev_vg;
00487
00488 bzero( (char *)delta_vec, sizeof(vect_t)),
00489 prev_eu = BU_LIST_PPREV_CIRC( edgeuse, eu );
00490 this_eu = eu;
00491
00492 NMG_CK_EDGEUSE(this_eu);
00493 NMG_CK_VERTEXUSE(this_eu->vu_p);
00494 NMG_CK_VERTEX(this_eu->vu_p->v_p);
00495 this_vg = this_eu->vu_p->v_p->vg_p;
00496 NMG_CK_VERTEX_G(this_vg);
00497
00498 NMG_CK_EDGEUSE(this_eu->eumate_p);
00499 NMG_CK_VERTEXUSE(this_eu->eumate_p->vu_p);
00500 NMG_CK_VERTEX(this_eu->eumate_p->vu_p->v_p);
00501 mate_vg = this_eu->eumate_p->vu_p->v_p->vg_p;
00502 NMG_CK_VERTEX_G(mate_vg);
00503
00504 NMG_CK_EDGEUSE(prev_eu);
00505 NMG_CK_VERTEXUSE(prev_eu->vu_p);
00506 NMG_CK_VERTEX(prev_eu->vu_p->v_p);
00507 prev_vg = prev_eu->vu_p->v_p->vg_p;
00508 NMG_CK_VERTEX_G(prev_vg);
00509
00510
00511 VSUB2(eu_vec, mate_vg->coord, this_vg->coord);
00512 VUNITIZE(eu_vec);
00513 VCROSS(eu_left, face_normal, eu_vec);
00514
00515
00516
00517 VSUB2(prev_vec, this_vg->coord, prev_vg->coord);
00518 VUNITIZE(prev_vec);
00519 VCROSS(prev_left, face_normal, prev_vec);
00520
00521
00522 VADD2(delta_vec, prev_left, eu_left);
00523
00524 if (MAGSQ(delta_vec) > VDIVIDE_TOL) {
00525 VUNITIZE(delta_vec);
00526 VJOIN2(base, this_vg->coord,
00527 (nmg_eue_dist*1.3),delta_vec,
00528 (nmg_eue_dist*0.8),face_normal);
00529
00530 } else if (tip) {
00531 VJOIN2(base, this_vg->coord,
00532 (nmg_eue_dist*1.3),prev_left,
00533 (nmg_eue_dist*0.8),face_normal);
00534 } else {
00535 VJOIN2(base, this_vg->coord,
00536 (nmg_eue_dist*1.3),eu_left,
00537 (nmg_eue_dist*0.8),face_normal);
00538 }
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550 static void nmg_eu_coords(const struct edgeuse *eu, fastf_t *base, fastf_t *tip60)
00551 {
00552 point_t tip;
00553
00554 NMG_CK_EDGEUSE(eu);
00555
00556 if (*eu->up.magic_p == NMG_SHELL_MAGIC ||
00557 (*eu->up.magic_p == NMG_LOOPUSE_MAGIC &&
00558 *eu->up.lu_p->up.magic_p == NMG_SHELL_MAGIC) ) {
00559
00560 VMOVE( base, eu->vu_p->v_p->vg_p->coord );
00561 NMG_CK_EDGEUSE(eu->eumate_p);
00562 VMOVE( tip, eu->eumate_p->vu_p->v_p->vg_p->coord );
00563 }
00564 else if (*eu->up.magic_p == NMG_LOOPUSE_MAGIC &&
00565 *eu->up.lu_p->up.magic_p == NMG_FACEUSE_MAGIC) {
00566
00567 struct faceuse *fu;
00568 vect_t face_normal;
00569
00570 fu = eu->up.lu_p->up.fu_p;
00571 NMG_GET_FU_NORMAL( face_normal, fu );
00572
00573
00574 nmg_offset_eu_vert(base, eu, face_normal, 0);
00575 nmg_offset_eu_vert(tip, BU_LIST_PNEXT_CIRC(edgeuse, eu),
00576 face_normal, 1);
00577
00578 } else
00579 rt_bomb("nmg_eu_coords: bad edgeuse up. What's going on?\n");
00580
00581 VBLEND2( tip60, 0.4, base, 0.6, tip );
00582 }
00583
00584
00585
00586
00587
00588
00589 static void nmg_eu_radial(const struct edgeuse *eu, fastf_t *tip)
00590 {
00591 point_t b2, t2;
00592
00593 NMG_CK_EDGEUSE(eu->radial_p);
00594 NMG_CK_VERTEXUSE(eu->radial_p->vu_p);
00595 NMG_CK_VERTEX(eu->radial_p->vu_p->v_p);
00596 NMG_CK_VERTEX_G(eu->radial_p->vu_p->v_p->vg_p);
00597
00598 nmg_eu_coords(eu->radial_p, b2, t2);
00599
00600
00601 VCOMB2( tip, 0.8, t2, 0.2, b2 );
00602 }
00603
00604 #if 0
00605
00606
00607
00608
00609
00610 static void nmg_eu_last( eu, tip_out )
00611 const struct edgeuse *eu;
00612 point_t tip_out;
00613 {
00614 point_t radial_base;
00615 point_t radial_tip;
00616 point_t last_base;
00617 point_t last_tip;
00618 point_t p;
00619 struct edgeuse *eulast;
00620
00621 NMG_CK_EDGEUSE(eu);
00622 eulast = BU_LIST_PPREV_CIRC( edgeuse, eu );
00623 NMG_CK_EDGEUSE(eulast);
00624 NMG_CK_VERTEXUSE(eulast->vu_p);
00625 NMG_CK_VERTEX(eulast->vu_p->v_p);
00626 NMG_CK_VERTEX_G(eulast->vu_p->v_p->vg_p);
00627
00628 nmg_eu_coords(eulast->radial_p, radial_base, radial_tip);
00629
00630
00631 VCOMB2( p, 0.8, radial_tip, 0.2, radial_base );
00632
00633
00634 nmg_eu_coords(eulast, last_base, last_tip);
00635
00636
00637 VCOMB2( tip_out, 0.8, last_tip, 0.2, p );
00638 }
00639 #endif
00640
00641
00642
00643
00644
00645
00646 static void nmg_eu_next_base(const struct edgeuse *eu, fastf_t *next_base)
00647 {
00648 point_t t2;
00649 register struct edgeuse *nexteu;
00650
00651 NMG_CK_EDGEUSE(eu);
00652 nexteu = BU_LIST_PNEXT_CIRC( edgeuse, eu );
00653 NMG_CK_EDGEUSE(nexteu);
00654 NMG_CK_VERTEXUSE(nexteu->vu_p);
00655 NMG_CK_VERTEX(nexteu->vu_p->v_p);
00656 NMG_CK_VERTEX_G(nexteu->vu_p->v_p->vg_p);
00657
00658 nmg_eu_coords(nexteu, next_base, t2);
00659 }
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 void
00672 nmg_pl_v(FILE *fp, const struct vertex *v, long int *b)
00673 {
00674 pointp_t p;
00675 static char label[128];
00676
00677 NMG_INDEX_RETURN_IF_SET_ELSE_SET(b, v->index);
00678
00679 NMG_CK_VERTEX(v);
00680 NMG_CK_VERTEX_G(v->vg_p);
00681 p = v->vg_p->coord;
00682
00683 pl_color(fp, 255, 255, 255);
00684 if (rt_g.NMG_debug & DEBUG_LABEL_PTS) {
00685 (void)sprintf(label, "%g %g %g", p[0], p[1], p[2]);
00686 pdv_3move( fp, p );
00687 pl_label(fp, label);
00688 }
00689 pdv_3point(fp, p);
00690 }
00691
00692
00693
00694
00695 void
00696 nmg_pl_e(FILE *fp, const struct edge *e, long int *b, int red, int green, int blue)
00697 {
00698 pointp_t p0, p1;
00699 point_t end0, end1;
00700 vect_t v;
00701
00702 NMG_INDEX_RETURN_IF_SET_ELSE_SET(b, e->index);
00703
00704 NMG_CK_EDGEUSE(e->eu_p);
00705 NMG_CK_VERTEXUSE(e->eu_p->vu_p);
00706 NMG_CK_VERTEX(e->eu_p->vu_p->v_p);
00707 NMG_CK_VERTEX_G(e->eu_p->vu_p->v_p->vg_p);
00708 p0 = e->eu_p->vu_p->v_p->vg_p->coord;
00709
00710 NMG_CK_VERTEXUSE(e->eu_p->eumate_p->vu_p);
00711 NMG_CK_VERTEX(e->eu_p->eumate_p->vu_p->v_p);
00712 NMG_CK_VERTEX_G(e->eu_p->eumate_p->vu_p->v_p->vg_p);
00713 p1 = e->eu_p->eumate_p->vu_p->v_p->vg_p->coord;
00714
00715
00716
00717
00718
00719 VSUB2SCALE(v, p1, p0, 0.95);
00720 VADD2(end0, p0, v);
00721 VSUB2(end1, p1, v);
00722
00723 pl_color(fp, red, green, blue);
00724 pdv_3line( fp, end0, end1 );
00725
00726 nmg_pl_v(fp, e->eu_p->vu_p->v_p, b);
00727 nmg_pl_v(fp, e->eu_p->eumate_p->vu_p->v_p, b);
00728 }
00729
00730
00731
00732
00733 void
00734 nmg_pl_eu(FILE *fp, const struct edgeuse *eu, long int *b, int red, int green, int blue)
00735 {
00736 point_t base, tip;
00737 point_t radial_tip;
00738 point_t next_base;
00739
00740 NMG_CK_EDGEUSE(eu);
00741 NMG_CK_EDGE(eu->e_p);
00742 NMG_CK_VERTEXUSE(eu->vu_p);
00743 NMG_CK_VERTEX(eu->vu_p->v_p);
00744 NMG_CK_VERTEX_G(eu->vu_p->v_p->vg_p);
00745
00746 NMG_CK_VERTEXUSE(eu->eumate_p->vu_p);
00747 NMG_CK_VERTEX(eu->eumate_p->vu_p->v_p);
00748 NMG_CK_VERTEX_G(eu->eumate_p->vu_p->v_p->vg_p);
00749
00750 NMG_INDEX_RETURN_IF_SET_ELSE_SET(b, eu->index);
00751
00752 nmg_pl_e(fp, eu->e_p, b, red, green, blue);
00753
00754 if (*eu->up.magic_p == NMG_LOOPUSE_MAGIC &&
00755 *eu->up.lu_p->up.magic_p == NMG_FACEUSE_MAGIC) {
00756
00757 nmg_eu_coords(eu, base, tip);
00758 if (eu->up.lu_p->up.fu_p->orientation == OT_SAME)
00759 red += 50;
00760 else if (eu->up.lu_p->up.fu_p->orientation == OT_OPPOSITE)
00761 red -= 50;
00762 else
00763 red = green = blue = 255;
00764
00765 pl_color(fp, red, green, blue);
00766 pdv_3line( fp, base, tip );
00767
00768 nmg_eu_radial( eu, radial_tip );
00769 pl_color(fp, red, green-20, blue);
00770 pdv_3line( fp, tip, radial_tip );
00771
00772 pl_color(fp, 0, 100, 0);
00773 nmg_eu_next_base( eu, next_base );
00774 pdv_3line( fp, tip, next_base );
00775
00776
00777
00778
00779
00780
00781 }
00782 }
00783
00784
00785
00786
00787 void
00788 nmg_pl_lu(FILE *fp, const struct loopuse *lu, long int *b, int red, int green, int blue)
00789 {
00790 struct bn_vlblock *vbp;
00791
00792 vbp = rt_vlblock_init();
00793 nmg_vlblock_lu(vbp, lu, b, red, green, blue, 0, 0);
00794 rt_plot_vlblock(fp, vbp);
00795 rt_vlblock_free(vbp);
00796 }
00797
00798
00799
00800
00801 void
00802 nmg_pl_fu(FILE *fp, const struct faceuse *fu, long int *b, int red, int green, int blue)
00803 {
00804 struct loopuse *lu;
00805 struct bn_vlblock *vbp;
00806 int loopnum = 0;
00807
00808 NMG_CK_FACEUSE(fu);
00809 NMG_INDEX_RETURN_IF_SET_ELSE_SET(b, fu->index);
00810
00811 vbp = rt_vlblock_init();
00812
00813 for( BU_LIST_FOR( lu, loopuse, &fu->lu_hd ) ) {
00814 nmg_vlblock_lu(vbp, lu, b, red, green, blue, 1, loopnum++);
00815 }
00816
00817 rt_plot_vlblock(fp, vbp);
00818 rt_vlblock_free(vbp);
00819 }
00820
00821
00822
00823
00824
00825
00826
00827 void
00828 nmg_pl_s(FILE *fp, const struct shell *s)
00829 {
00830 struct bn_vlblock *vbp;
00831
00832 vbp = rt_vlblock_init();
00833 nmg_vlblock_s(vbp, s, 0);
00834 rt_plot_vlblock(fp, vbp);
00835 rt_vlblock_free(vbp);
00836 }
00837
00838 void
00839 nmg_pl_shell(FILE *fp, const struct shell *s, int fancy)
00840 {
00841 struct bn_vlblock *vbp;
00842
00843 vbp = rt_vlblock_init();
00844 nmg_vlblock_s(vbp, s, fancy);
00845 rt_plot_vlblock(fp, vbp);
00846 rt_vlblock_free(vbp);
00847 }
00848
00849
00850
00851
00852 void
00853 nmg_pl_r(FILE *fp, const struct nmgregion *r)
00854 {
00855 struct bn_vlblock *vbp;
00856
00857 vbp = rt_vlblock_init();
00858 nmg_vlblock_r(vbp, r, 0);
00859 rt_plot_vlblock(fp, vbp);
00860 rt_vlblock_free(vbp);
00861 }
00862
00863
00864
00865
00866 void
00867 nmg_pl_m(FILE *fp, const struct model *m)
00868 {
00869 struct bn_vlblock *vbp;
00870
00871 vbp = rt_vlblock_init();
00872 nmg_vlblock_m(vbp, m, 0);
00873 rt_plot_vlblock(fp, vbp);
00874 rt_vlblock_free(vbp);
00875 }
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888 void
00889 nmg_vlblock_v(struct bn_vlblock *vbp, const struct vertex *v, long int *tab)
00890 {
00891 pointp_t p;
00892 struct bu_list *vh;
00893
00894 BN_CK_VLBLOCK(vbp);
00895 NMG_CK_VERTEX(v);
00896 NMG_INDEX_RETURN_IF_SET_ELSE_SET( tab, v->index );
00897
00898 NMG_CK_VERTEX_G(v->vg_p);
00899 p = v->vg_p->coord;
00900
00901 vh = rt_vlblock_find( vbp, 255, 255, 255 );
00902 #if 0
00903 if (rt_g.NMG_debug & DEBUG_LABEL_PTS) {
00904 static char label[128];
00905 mat_t mat;
00906 MAT_IDN(mat);
00907 (void)sprintf(label, "%g %g %g", p[0], p[1], p[2]);
00908
00909 bn_vlist_3string( vh, vbp->free_vlist_hd, label, p, mat, scale );
00910 }
00911 #endif
00912 RT_ADD_VLIST( vh, p, BN_VLIST_LINE_MOVE );
00913 RT_ADD_VLIST( vh, p, BN_VLIST_LINE_DRAW );
00914 }
00915
00916
00917
00918
00919 void
00920 nmg_vlblock_e(struct bn_vlblock *vbp, const struct edge *e, long int *tab, int red, int green, int blue, int fancy)
00921 {
00922 pointp_t p0, p1;
00923 point_t end0, end1;
00924 vect_t v;
00925 struct bu_list *vh;
00926
00927 BN_CK_VLBLOCK(vbp);
00928 NMG_CK_EDGE(e);
00929 NMG_INDEX_RETURN_IF_SET_ELSE_SET( tab, e->index );
00930
00931 NMG_CK_EDGEUSE(e->eu_p);
00932 NMG_CK_VERTEXUSE(e->eu_p->vu_p);
00933 NMG_CK_VERTEX(e->eu_p->vu_p->v_p);
00934 NMG_CK_VERTEX_G(e->eu_p->vu_p->v_p->vg_p);
00935 p0 = e->eu_p->vu_p->v_p->vg_p->coord;
00936
00937 NMG_CK_VERTEXUSE(e->eu_p->eumate_p->vu_p);
00938 NMG_CK_VERTEX(e->eu_p->eumate_p->vu_p->v_p);
00939 NMG_CK_VERTEX_G(e->eu_p->eumate_p->vu_p->v_p->vg_p);
00940 p1 = e->eu_p->eumate_p->vu_p->v_p->vg_p->coord;
00941
00942
00943
00944
00945
00946 VSUB2SCALE(v, p1, p0, 0.90);
00947 VADD2(end0, p0, v);
00948 VSUB2(end1, p1, v);
00949
00950 vh = rt_vlblock_find( vbp, red, green, blue );
00951 RT_ADD_VLIST( vh, end0, BN_VLIST_LINE_MOVE );
00952 RT_ADD_VLIST( vh, end1, BN_VLIST_LINE_DRAW );
00953
00954 nmg_vlblock_v(vbp, e->eu_p->vu_p->v_p, tab);
00955 nmg_vlblock_v(vbp, e->eu_p->eumate_p->vu_p->v_p, tab);
00956 }
00957
00958
00959
00960
00961 void
00962 nmg_vlblock_eu(struct bn_vlblock *vbp, const struct edgeuse *eu, long int *tab, int red, int green, int blue, int fancy, int loopnum)
00963 {
00964 point_t base, tip;
00965 point_t radial_tip;
00966 point_t next_base;
00967 struct bu_list *vh;
00968
00969 BN_CK_VLBLOCK(vbp);
00970 NMG_CK_EDGEUSE(eu);
00971 NMG_INDEX_RETURN_IF_SET_ELSE_SET( tab, eu->index );
00972
00973 NMG_CK_EDGE(eu->e_p);
00974 NMG_CK_VERTEXUSE(eu->vu_p);
00975 NMG_CK_VERTEX(eu->vu_p->v_p);
00976 NMG_CK_VERTEX_G(eu->vu_p->v_p->vg_p);
00977
00978 NMG_CK_VERTEXUSE(eu->eumate_p->vu_p);
00979 NMG_CK_VERTEX(eu->eumate_p->vu_p->v_p);
00980 NMG_CK_VERTEX_G(eu->eumate_p->vu_p->v_p->vg_p);
00981
00982 nmg_vlblock_e(vbp, eu->e_p, tab, red, green, blue, fancy);
00983
00984 if( !fancy ) return;
00985
00986 if (*eu->up.magic_p == NMG_LOOPUSE_MAGIC &&
00987 *eu->up.lu_p->up.magic_p == NMG_FACEUSE_MAGIC) {
00988
00989
00990
00991
00992 if ( (eu->up.lu_p->up.fu_p->orientation == OT_SAME &&
00993 (fancy & 1) == 0) ||
00994 (eu->up.lu_p->up.fu_p->orientation == OT_OPPOSITE &&
00995 (fancy & 2) == 0) )
00996 return;
00997
00998 nmg_eu_coords(eu, base, tip);
00999
01000
01001
01002
01003 if (eu->up.lu_p->up.fu_p->orientation == OT_SAME) {
01004 if (eu->up.lu_p->orientation == OT_SAME) {
01005
01006 red = 75;
01007 green = 250;
01008 blue = 75;
01009 } else if (eu->up.lu_p->orientation == OT_OPPOSITE) {
01010
01011 red = 250;
01012 green = 250;
01013 blue = 75;
01014 } else {
01015 red = 250;
01016 green = 50;
01017 blue = 250;
01018 }
01019 } else if (eu->up.lu_p->up.fu_p->orientation == OT_OPPOSITE) {
01020 if (eu->up.lu_p->orientation == OT_SAME) {
01021
01022 red = 100;
01023 green = 100;
01024 blue = 250;
01025 } else if (eu->up.lu_p->orientation == OT_OPPOSITE) {
01026
01027 red = 200;
01028 green = 100;
01029 blue = 250;
01030 } else {
01031
01032 red = 125;
01033 green = 0;
01034 blue = 125;
01035 }
01036 } else
01037 red = green = blue = 255;
01038
01039
01040
01041
01042 vh = rt_vlblock_find( vbp, red, green, blue );
01043 RT_ADD_VLIST( vh, base, BN_VLIST_LINE_MOVE );
01044 RT_ADD_VLIST( vh, tip, BN_VLIST_LINE_DRAW );
01045
01046
01047
01048
01049
01050
01051
01052
01053 nmg_eu_radial( eu, radial_tip );
01054 vh = rt_vlblock_find( vbp, red, green-20, blue );
01055 RT_ADD_VLIST( vh, tip, BN_VLIST_LINE_MOVE );
01056 RT_ADD_VLIST( vh, radial_tip, BN_VLIST_LINE_DRAW );
01057
01058
01059
01060
01061
01062
01063
01064 nmg_eu_next_base( eu, next_base );
01065 red *= 0.5;
01066 green *= 0.5;
01067 blue *= 0.5;
01068 vh = rt_vlblock_find( vbp, red, green, blue );
01069 RT_ADD_VLIST( vh, tip, BN_VLIST_LINE_MOVE );
01070 RT_ADD_VLIST( vh, next_base, BN_VLIST_LINE_DRAW );
01071 }
01072 }
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082 void
01083 nmg_vlblock_euleft(struct bu_list *vh, const struct edgeuse *eu, const fastf_t *center, const fastf_t *mat, const fastf_t *xvec, const fastf_t *yvec, double len, const struct bn_tol *tol)
01084 {
01085 vect_t left;
01086 point_t tip;
01087 fastf_t fan_len;
01088 fastf_t char_scale;
01089 double ang;
01090 char str[128];
01091
01092 NMG_CK_EDGEUSE(eu);
01093 BN_CK_TOL(tol);
01094
01095 if( nmg_find_eu_leftvec( left, eu ) < 0 ) return;
01096
01097
01098 fan_len = len * 0.2;
01099 VJOIN1( tip, center, fan_len, left );
01100
01101 RT_ADD_VLIST( vh, center, BN_VLIST_LINE_MOVE );
01102 RT_ADD_VLIST( vh, tip, BN_VLIST_LINE_DRAW );
01103
01104 ang = bn_angle_measure( left, xvec, yvec ) * bn_radtodeg;
01105 sprintf( str, "%g", ang );
01106
01107
01108 char_scale = len * 0.05;
01109 bn_vlist_3string( vh, &rt_g.rtg_vlfree, str, tip, mat, char_scale );
01110 }
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122 void
01123 nmg_vlblock_around_eu(struct bn_vlblock *vbp, const struct edgeuse *arg_eu, long int *tab, int fancy, const struct bn_tol *tol)
01124 {
01125 const struct edgeuse *orig_eu;
01126 register const struct edgeuse *eu;
01127 vect_t xvec, yvec, zvec;
01128 point_t center;
01129 mat_t mat;
01130 struct bu_list *vh;
01131 fastf_t len;
01132
01133 BN_CK_VLBLOCK(vbp);
01134 NMG_CK_EDGEUSE(arg_eu);
01135 BN_CK_TOL(tol);
01136
01137 if( fancy ) {
01138 VSUB2( xvec, arg_eu->eumate_p->vu_p->v_p->vg_p->coord,
01139 arg_eu->vu_p->v_p->vg_p->coord );
01140 len = MAGNITUDE( xvec );
01141
01142
01143 nmg_eu_2vecs_perp( xvec, yvec, zvec, arg_eu, tol );
01144
01145
01146
01147
01148 MAT_ZERO( mat );
01149 mat[0] = xvec[X];
01150 mat[4] = xvec[Y];
01151 mat[8] = xvec[Z];
01152
01153 mat[1] = yvec[X];
01154 mat[5] = yvec[Y];
01155 mat[9] = yvec[Z];
01156
01157 mat[2] = zvec[X];
01158 mat[6] = zvec[Y];
01159 mat[10] = zvec[Z];
01160 mat[15] = 1;
01161
01162 VADD2SCALE( center, arg_eu->vu_p->v_p->vg_p->coord,
01163 arg_eu->eumate_p->vu_p->v_p->vg_p->coord, 0.5 );
01164
01165
01166 vh = rt_vlblock_find( vbp, 255, 200, 0 );
01167 } else {
01168 vh = (struct bu_list *)NULL;
01169 len = 1;
01170 }
01171
01172 orig_eu = arg_eu->eumate_p;
01173
01174 eu = orig_eu;
01175 do {
01176 if(fancy) nmg_vlblock_euleft( vh, eu, center, mat, xvec, yvec, len, tol );
01177
01178 nmg_vlblock_eu(vbp, eu, tab, 80, 100, 170, 3, 0);
01179 eu = eu->eumate_p;
01180
01181 nmg_vlblock_eu(vbp, eu, tab, 80, 100, 170, 3, 0);
01182 eu = eu->radial_p;
01183 } while( eu != orig_eu );
01184 }
01185
01186
01187
01188
01189 void
01190 nmg_vlblock_lu(struct bn_vlblock *vbp, const struct loopuse *lu, long int *tab, int red, int green, int blue, int fancy, int loopnum)
01191 {
01192 struct edgeuse *eu;
01193 long magic1;
01194 struct vertexuse *vu;
01195
01196 BN_CK_VLBLOCK(vbp);
01197 NMG_CK_LOOPUSE(lu);
01198 NMG_INDEX_RETURN_IF_SET_ELSE_SET( tab, lu->index );
01199
01200 magic1 = BU_LIST_FIRST_MAGIC( &lu->down_hd );
01201 if (magic1 == NMG_VERTEXUSE_MAGIC &&
01202 lu->orientation != OT_BOOLPLACE) {
01203 vu = BU_LIST_PNEXT(vertexuse, &lu->down_hd);
01204 NMG_CK_VERTEXUSE(vu);
01205 nmg_vlblock_v(vbp, vu->v_p, tab);
01206 } else if (magic1 == NMG_EDGEUSE_MAGIC) {
01207 for( BU_LIST_FOR( eu, edgeuse, &lu->down_hd ) ) {
01208 nmg_vlblock_eu(vbp, eu, tab, red, green, blue,
01209 fancy, loopnum);
01210 }
01211 }
01212 }
01213
01214
01215
01216
01217 void
01218 nmg_vlblock_fu(struct bn_vlblock *vbp, const struct faceuse *fu, long int *tab, int fancy)
01219 {
01220 struct loopuse *lu;
01221 int loopnum = 0;
01222
01223 BN_CK_VLBLOCK(vbp);
01224 NMG_CK_FACEUSE(fu);
01225 NMG_INDEX_RETURN_IF_SET_ELSE_SET( tab, fu->index );
01226
01227 for( BU_LIST_FOR( lu, loopuse, &fu->lu_hd ) ) {
01228
01229 if( fancy ) {
01230 nmg_vlblock_lu(vbp, lu, tab, 80, 100, 170, fancy, loopnum++ );
01231 } else {
01232
01233 nmg_vlblock_lu(vbp, lu, tab, 80, 100, 170, 0, loopnum++ );
01234 }
01235 }
01236 }
01237
01238
01239
01240
01241 void
01242 nmg_vlblock_s(struct bn_vlblock *vbp, const struct shell *s, int fancy)
01243 {
01244 struct faceuse *fu;
01245 struct loopuse *lu;
01246 struct edgeuse *eu;
01247 struct model *m;
01248 long *tab;
01249
01250 BN_CK_VLBLOCK(vbp);
01251 NMG_CK_SHELL(s);
01252 NMG_CK_REGION(s->r_p);
01253 m = s->r_p->m_p;
01254 NMG_CK_MODEL(m);
01255
01256
01257 tab = (long *)bu_calloc( m->maxindex+1, sizeof(long),
01258 "nmg_vlblock_s tab[]");
01259
01260 for( BU_LIST_FOR( fu, faceuse, &s->fu_hd ) ) {
01261 NMG_CK_FACEUSE(fu);
01262 nmg_vlblock_fu(vbp, fu, tab, fancy );
01263 }
01264
01265 for( BU_LIST_FOR( lu, loopuse, &s->lu_hd ) ) {
01266 NMG_CK_LOOPUSE(lu);
01267 if( fancy ) {
01268 nmg_vlblock_lu(vbp, lu, tab, 255, 0, 0, fancy, 0);
01269 } else {
01270
01271 nmg_vlblock_lu(vbp, lu, tab, 200, 0, 0, 0, 0);
01272 }
01273 }
01274
01275 for( BU_LIST_FOR( eu, edgeuse, &s->eu_hd ) ) {
01276 NMG_CK_EDGEUSE(eu);
01277 NMG_CK_EDGE(eu->e_p);
01278
01279 if( fancy ) {
01280 nmg_vlblock_eu(vbp, eu, tab, 200, 200, 0, fancy, 0 );
01281 } else {
01282
01283 nmg_vlblock_eu(vbp, eu, tab, 200, 200, 0, 0, 0);
01284 }
01285 }
01286 if (s->vu_p) {
01287 nmg_vlblock_v(vbp, s->vu_p->v_p, tab );
01288 }
01289
01290 bu_free( (char *)tab, "nmg_vlblock_s tab[]" );
01291 }
01292
01293
01294
01295
01296 void
01297 nmg_vlblock_r(struct bn_vlblock *vbp, const struct nmgregion *r, int fancy)
01298 {
01299 struct shell *s;
01300
01301 BN_CK_VLBLOCK(vbp);
01302 NMG_CK_REGION(r);
01303
01304 for( BU_LIST_FOR( s, shell, &r->s_hd ) ) {
01305 nmg_vlblock_s(vbp, s, fancy);
01306 }
01307 }
01308
01309
01310
01311
01312 void
01313 nmg_vlblock_m(struct bn_vlblock *vbp, const struct model *m, int fancy)
01314 {
01315 struct nmgregion *r;
01316
01317 BN_CK_VLBLOCK(vbp);
01318 NMG_CK_MODEL(m);
01319
01320 for( BU_LIST_FOR( r, nmgregion, &m->r_hd ) ) {
01321 nmg_vlblock_r(vbp, r, fancy);
01322 }
01323 }
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335 void
01336 nmg_pl_edges_in_2_shells(struct bn_vlblock *vbp, long int *b, const struct edgeuse *eu, int fancy, const struct bn_tol *tol)
01337 {
01338 const struct edgeuse *eur;
01339 const struct shell *s;
01340
01341 BN_CK_TOL(tol);
01342 eur = eu;
01343 NMG_CK_EDGEUSE(eu);
01344 NMG_CK_LOOPUSE(eu->up.lu_p);
01345 NMG_CK_FACEUSE(eu->up.lu_p->up.fu_p);
01346 s = eu->up.lu_p->up.fu_p->s_p;
01347 NMG_CK_SHELL(s);
01348
01349 do {
01350 NMG_CK_EDGEUSE(eur);
01351
01352 if (*eur->up.magic_p == NMG_LOOPUSE_MAGIC &&
01353 *eur->up.lu_p->up.magic_p == NMG_FACEUSE_MAGIC &&
01354 eur->up.lu_p->up.fu_p->s_p != s) {
01355 nmg_vlblock_around_eu(vbp, eu, b, fancy, tol);
01356 break;
01357 }
01358
01359 eur = eur->radial_p->eumate_p;
01360 } while (eur != eu);
01361 }
01362
01363
01364
01365
01366
01367
01368 void
01369 nmg_pl_isect(const char *filename, const struct shell *s, const struct bn_tol *tol)
01370 {
01371 struct faceuse *fu;
01372 struct loopuse *lu;
01373 struct edgeuse *eu;
01374 long *b;
01375 FILE *fp;
01376 long magic1;
01377 struct bn_vlblock *vbp;
01378
01379 NMG_CK_SHELL(s);
01380 BN_CK_TOL(tol);
01381
01382 if ((fp=fopen(filename, "w")) == (FILE *)NULL) {
01383 (void)perror(filename);
01384 bu_bomb("unable to open file for writing");
01385 }
01386
01387 b = (long *)bu_calloc( s->r_p->m_p->maxindex+1, sizeof(long),
01388 "nmg_pl_isect flags[]" );
01389
01390 vbp = rt_vlblock_init();
01391
01392 bu_log("overlay %s\n", filename);
01393 if( s->sa_p ) {
01394 NMG_CK_SHELL_A( s->sa_p );
01395 #if 0
01396 pdv_3space( fp, s->sa_p->min_pt, s->sa_p->max_pt );
01397 #endif
01398 }
01399
01400 for( BU_LIST_FOR( fu, faceuse, &s->fu_hd ) ) {
01401 NMG_CK_FACEUSE(fu);
01402 for( BU_LIST_FOR( lu, loopuse, &fu->lu_hd ) ) {
01403 NMG_CK_LOOPUSE(lu);
01404 magic1 = BU_LIST_FIRST_MAGIC( &lu->down_hd );
01405 if (magic1 == NMG_EDGEUSE_MAGIC) {
01406 for( BU_LIST_FOR( eu, edgeuse, &lu->down_hd ) ) {
01407 NMG_CK_EDGEUSE(eu);
01408 nmg_pl_edges_in_2_shells(vbp, b, eu, 0, tol);
01409 }
01410 } else if (magic1 == NMG_VERTEXUSE_MAGIC) {
01411 ;
01412 } else {
01413 rt_bomb("nmg_pl_isect() bad loopuse down\n");
01414 }
01415 }
01416 }
01417
01418 rt_plot_vlblock(fp, vbp);
01419 rt_vlblock_free(vbp);
01420
01421 bu_free( (char *)b, "nmg_pl_isect flags[]" );
01422
01423 (void)fclose(fp);
01424 }
01425
01426
01427
01428
01429
01430
01431 void
01432 nmg_pl_comb_fu(int num1, int num2, const struct faceuse *fu1)
01433 {
01434 FILE *fp;
01435 char name[64];
01436 int do_plot = 0;
01437 int do_anim = 0;
01438 struct model *m;
01439 long *tab;
01440 struct bn_vlblock *vbp;
01441
01442 if(rt_g.NMG_debug & DEBUG_PLOTEM &&
01443 rt_g.NMG_debug & DEBUG_FCUT ) do_plot = 1;
01444 if( rt_g.NMG_debug & DEBUG_PL_ANIM ) do_anim = 1;
01445
01446 if( !do_plot && !do_anim ) return;
01447
01448 m = nmg_find_model( &fu1->l.magic );
01449 NMG_CK_MODEL(m);
01450
01451 tab = (long *)bu_calloc( m->maxindex+1, sizeof(long),
01452 "nmg_pl_comb_fu tab[]");
01453
01454 vbp = rt_vlblock_init();
01455
01456 nmg_vlblock_fu(vbp, fu1, tab, 3);
01457
01458 if( do_plot ) {
01459 (void)sprintf(name, "comb%d.%d.pl", num1, num2);
01460 if ((fp=fopen(name, "w")) == (FILE *)NULL) {
01461 (void)perror(name);
01462 return;
01463 }
01464 bu_log("overlay %s\n", name);
01465
01466 rt_plot_vlblock(fp, vbp);
01467
01468 (void)fclose(fp);
01469 }
01470
01471 if( do_anim ) {
01472 if( nmg_vlblock_anim_upcall ) {
01473 (*nmg_vlblock_anim_upcall)( vbp,
01474 (rt_g.NMG_debug&DEBUG_PL_SLOW) ? US_DELAY : 0,
01475 0 );
01476 } else {
01477 bu_log("null nmg_vlblock_anim_upcall, no animation\n");
01478 }
01479 }
01480 rt_vlblock_free(vbp);
01481 bu_free( (char *)tab, "nmg_pl_comb_fu tab[]" );
01482 }
01483
01484
01485
01486
01487
01488
01489
01490
01491 void
01492 nmg_pl_2fu(const char *str, int unused, const struct faceuse *fu1, const struct faceuse *fu2, int show_mates)
01493 {
01494 FILE *fp;
01495 char name[32];
01496 struct model *m;
01497 long *tab;
01498 static int num = 1;
01499 struct bn_vlblock *vbp;
01500
01501 if( (rt_g.NMG_debug & (DEBUG_PLOTEM|DEBUG_PL_ANIM)) == 0 ) return;
01502
01503 m = nmg_find_model( &fu1->l.magic );
01504 NMG_CK_MODEL(m);
01505
01506 tab = (long *)bu_calloc( m->maxindex+1, sizeof(long),
01507 "nmg_pl_comb_fu tab[]");
01508
01509
01510 vbp = rt_vlblock_init();
01511
01512 nmg_vlblock_fu( vbp, fu1, tab, 3);
01513 if( show_mates )
01514 nmg_vlblock_fu( vbp, fu1->fumate_p, tab, 3);
01515
01516 nmg_vlblock_fu( vbp, fu2, tab, 3);
01517 if( show_mates )
01518 nmg_vlblock_fu( vbp, fu2->fumate_p, tab, 3);
01519
01520 if( rt_g.NMG_debug & DEBUG_PLOTEM ) {
01521 (void)sprintf(name, str, num++);
01522 bu_log("overlay %s\n", name);
01523 if ((fp=fopen(name, "w")) == (FILE *)NULL) {
01524 perror(name);
01525 return;
01526 }
01527 rt_plot_vlblock( fp, vbp );
01528 (void)fclose(fp);
01529 }
01530
01531 if( rt_g.NMG_debug & DEBUG_PL_ANIM ) {
01532
01533 if( nmg_vlblock_anim_upcall ) {
01534 (*nmg_vlblock_anim_upcall)( vbp,
01535 (rt_g.NMG_debug&DEBUG_PL_SLOW) ? US_DELAY : 0,
01536 0 );
01537 }
01538 }
01539
01540 rt_vlblock_free(vbp);
01541 bu_free( (char *)tab, "nmg_pl_2fu tab[]" );
01542 }
01543
01544
01545
01546
01547
01548
01549
01550 int nmg_class_nothing_broken=1;
01551 static long **global_classlist;
01552 static long *broken_tab;
01553 static int broken_tab_len;
01554 static int broken_color;
01555 static unsigned char broken_colors[][3] = {
01556 { 100, 100, 255 },
01557 { 255, 50, 50 },
01558 { 255, 50, 255 },
01559 { 50, 255, 50 },
01560 { 255, 255, 255 },
01561 { 255, 255, 125 }
01562 };
01563 #define PICK_BROKEN_COLOR(p) { \
01564 if (global_classlist == (long **)NULL) { \
01565 broken_color = 5; \
01566 } else if( NMG_INDEX_TEST(global_classlist[NMG_CLASS_AinB], (p)) ) \
01567 broken_color = NMG_CLASS_AinB; \
01568 else if( NMG_INDEX_TEST(global_classlist[NMG_CLASS_AonBshared], (p)) ) \
01569 broken_color = NMG_CLASS_AonBshared; \
01570 else if( NMG_INDEX_TEST(global_classlist[NMG_CLASS_AonBanti], (p)) ) \
01571 broken_color = NMG_CLASS_AonBanti; \
01572 else if ( NMG_INDEX_TEST(global_classlist[NMG_CLASS_AoutB], (p)) ) \
01573 broken_color = NMG_CLASS_AoutB; \
01574 else \
01575 broken_color = 4;}
01576
01577
01578
01579
01580 static void
01581 show_broken_vu(struct bn_vlblock *vbp, const struct vertexuse *vu, int fancy)
01582 {
01583 pointp_t p;
01584 struct bu_list *vh;
01585 struct vertex *v;
01586 point_t pt;
01587
01588 NMG_CK_VERTEXUSE(vu);
01589 v = vu->v_p;
01590 NMG_CK_VERTEX(v);
01591 NMG_CK_VERTEX_G(v->vg_p);
01592
01593 NMG_INDEX_RETURN_IF_SET_ELSE_SET( broken_tab, v->index );
01594
01595 NMG_CK_VERTEX_G(v->vg_p);
01596 p = v->vg_p->coord;
01597
01598 PICK_BROKEN_COLOR(vu->v_p);
01599 if (broken_color == 4) {
01600
01601 PICK_BROKEN_COLOR(vu);
01602
01603 }
01604 vh = rt_vlblock_find( vbp,
01605 broken_colors[broken_color][0], broken_colors[broken_color][1], broken_colors[broken_color][2]);
01606
01607 RT_ADD_VLIST( vh, p, BN_VLIST_LINE_MOVE );
01608 RT_ADD_VLIST( vh, p, BN_VLIST_LINE_DRAW );
01609
01610
01611 VMOVE(pt, p);
01612 pt[0] += 0.05;
01613 RT_ADD_VLIST( vh, pt, BN_VLIST_LINE_MOVE );
01614 VMOVE(pt, p);
01615 pt[0] -= 0.05;
01616 RT_ADD_VLIST( vh, pt, BN_VLIST_LINE_DRAW );
01617
01618 VMOVE(pt, p);
01619 pt[1] += 0.05;
01620 RT_ADD_VLIST( vh, pt, BN_VLIST_LINE_MOVE );
01621 VMOVE(pt, p);
01622 pt[1] -= 0.05;
01623 RT_ADD_VLIST( vh, pt, BN_VLIST_LINE_DRAW );
01624
01625 VMOVE(pt, p);
01626 pt[2] += 0.05;
01627 RT_ADD_VLIST( vh, pt, BN_VLIST_LINE_MOVE );
01628 VMOVE(pt, p);
01629 pt[2] -= 0.05;
01630 RT_ADD_VLIST( vh, pt, BN_VLIST_LINE_DRAW );
01631
01632 RT_ADD_VLIST( vh, p, BN_VLIST_LINE_MOVE );
01633 }
01634
01635 static void
01636 show_broken_e(struct bn_vlblock *vbp, const struct edgeuse *eu, int fancy)
01637 {
01638 pointp_t p0, p1;
01639 point_t end0, end1;
01640 vect_t v;
01641 struct bu_list *vh;
01642
01643 NMG_CK_VERTEXUSE(eu->vu_p);
01644 NMG_CK_VERTEX(eu->vu_p->v_p);
01645 NMG_CK_VERTEX_G(eu->vu_p->v_p->vg_p);
01646 NMG_CK_VERTEXUSE(eu->eumate_p->vu_p);
01647 NMG_CK_VERTEX(eu->eumate_p->vu_p->v_p);
01648 NMG_CK_VERTEX_G(eu->eumate_p->vu_p->v_p->vg_p);
01649
01650 NMG_INDEX_RETURN_IF_SET_ELSE_SET( broken_tab, eu->e_p->index );
01651
01652 p0 = eu->vu_p->v_p->vg_p->coord;
01653 p1 = eu->eumate_p->vu_p->v_p->vg_p->coord;
01654
01655
01656
01657
01658
01659 VSUB2SCALE(v, p1, p0, 0.90);
01660 VADD2(end0, p0, v);
01661 VSUB2(end1, p1, v);
01662
01663
01664 PICK_BROKEN_COLOR(eu->e_p);
01665 if (broken_color == 4) {
01666
01667 PICK_BROKEN_COLOR(eu);
01668
01669 }
01670
01671 vh = rt_vlblock_find( vbp,
01672 broken_colors[broken_color][0], broken_colors[broken_color][1], broken_colors[broken_color][2]);
01673
01674 RT_ADD_VLIST( vh, end0, BN_VLIST_LINE_MOVE );
01675 RT_ADD_VLIST( vh, end1, BN_VLIST_LINE_DRAW );
01676
01677 show_broken_vu(vbp, eu->vu_p, fancy);
01678 show_broken_vu(vbp, eu->eumate_p->vu_p, fancy);
01679
01680 }
01681
01682
01683 static void
01684 show_broken_eu(struct bn_vlblock *vbp, const struct edgeuse *eu, int fancy)
01685 {
01686 struct bu_list *vh;
01687 int red, green, blue;
01688 point_t base, tip;
01689 point_t radial_tip;
01690 point_t next_base;
01691
01692 NMG_CK_EDGEUSE(eu);
01693 NMG_CK_EDGE(eu->e_p);
01694
01695 show_broken_e(vbp, eu, fancy);
01696
01697 if (!fancy) return;
01698
01699
01700 if (*eu->up.magic_p == NMG_LOOPUSE_MAGIC &&
01701 *eu->up.lu_p->up.magic_p == NMG_FACEUSE_MAGIC) {
01702
01703 red = broken_colors[broken_color][0];
01704 green = broken_colors[broken_color][1];
01705 blue = broken_colors[broken_color][2];
01706
01707 nmg_eu_coords(eu, base, tip);
01708 if (eu->up.lu_p->up.fu_p->orientation == OT_SAME)
01709 red += 50;
01710 else if (eu->up.lu_p->up.fu_p->orientation == OT_OPPOSITE)
01711 red -= 50;
01712 else
01713 red = green = blue = 255;
01714
01715 vh = rt_vlblock_find( vbp, red, green, blue );
01716 RT_ADD_VLIST( vh, base, BN_VLIST_LINE_MOVE );
01717 RT_ADD_VLIST( vh, tip, BN_VLIST_LINE_DRAW );
01718
01719 nmg_eu_radial( eu, radial_tip );
01720 vh = rt_vlblock_find( vbp, red, green-20, blue );
01721 RT_ADD_VLIST( vh, tip, BN_VLIST_LINE_MOVE );
01722 RT_ADD_VLIST( vh, radial_tip, BN_VLIST_LINE_DRAW );
01723
01724 nmg_eu_next_base( eu, next_base );
01725 vh = rt_vlblock_find( vbp, 0, 100, 0 );
01726 RT_ADD_VLIST( vh, tip, BN_VLIST_LINE_MOVE );
01727 RT_ADD_VLIST( vh, next_base, BN_VLIST_LINE_DRAW );
01728 }
01729
01730 }
01731
01732 static void
01733 show_broken_lu(struct bn_vlblock *vbp, const struct loopuse *lu, int fancy)
01734 {
01735 register struct edgeuse *eu;
01736 struct bu_list *vh;
01737 vect_t n;
01738
01739 NMG_CK_LOOPUSE(lu);
01740
01741 if( BU_LIST_FIRST_MAGIC(&lu->down_hd)==NMG_VERTEXUSE_MAGIC ) {
01742 register struct vertexuse *vu;
01743 vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
01744 show_broken_vu(vbp, vu, fancy);
01745 return;
01746 }
01747
01748 if (rt_g.NMG_debug & DEBUG_GRAPHCL) {
01749 for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd))
01750 show_broken_eu(vbp, eu, fancy);
01751 }
01752
01753
01754
01755
01756 PICK_BROKEN_COLOR(lu->l_p);
01757 vh = rt_vlblock_find( vbp,
01758 broken_colors[broken_color][0], broken_colors[broken_color][1], broken_colors[broken_color][2]);
01759
01760 if( *lu->up.magic_p == NMG_FACEUSE_MAGIC ) {
01761 NMG_GET_FU_NORMAL( n, lu->up.fu_p );
01762 } else {
01763
01764 VSET( n, 0, 0, 1 );
01765 }
01766
01767 if ((rt_g.NMG_debug & (DEBUG_GRAPHCL|DEBUG_PL_LOOP)) == (DEBUG_PL_LOOP) ) {
01768
01769 nmg_lu_to_vlist( vh, lu, 0, n );
01770 } else if ((rt_g.NMG_debug & (DEBUG_GRAPHCL|DEBUG_PL_LOOP)) == (DEBUG_GRAPHCL|DEBUG_PL_LOOP) ) {
01771
01772 nmg_lu_to_vlist( vh, lu, 1, n );
01773 } else {
01774
01775 }
01776 }
01777
01778
01779
01780 static void
01781 show_broken_fu(struct bn_vlblock *vbp, const struct faceuse *fu, int fancy)
01782 {
01783 register struct loopuse *lu;
01784
01785 NMG_CK_FACEUSE(fu);
01786 for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
01787 show_broken_lu(vbp, lu, fancy);
01788 }
01789 }
01790
01791 static void
01792 show_broken_s(struct bn_vlblock *vbp, const struct shell *s, int fancy)
01793 {
01794 struct faceuse *fu;
01795 struct loopuse *lu;
01796 struct edgeuse *eu;
01797
01798 NMG_CK_SHELL(s);
01799 for ( BU_LIST_FOR(fu, faceuse, &s->fu_hd ))
01800 show_broken_fu(vbp, fu, fancy);
01801 for ( BU_LIST_FOR(lu, loopuse, &s->lu_hd ))
01802 show_broken_lu(vbp, lu, fancy);
01803 for ( BU_LIST_FOR(eu, edgeuse, &s->eu_hd ))
01804 show_broken_eu(vbp, eu, fancy);
01805 if ( s->vu_p )
01806 show_broken_vu(vbp, s->vu_p, fancy);
01807 }
01808 static void
01809 show_broken_r(struct bn_vlblock *vbp, const struct nmgregion *r, int fancy)
01810 {
01811 register struct shell *s;
01812
01813 NMG_CK_REGION(r);
01814 for ( BU_LIST_FOR(s, shell, & r->s_hd))
01815 show_broken_s(vbp, s, fancy);
01816 }
01817
01818 static void
01819 show_broken_m(struct bn_vlblock *vbp, const struct model *m, int fancy)
01820 {
01821 register struct nmgregion *r;
01822
01823 NMG_CK_MODEL(m);
01824 for (BU_LIST_FOR(r, nmgregion, &m->r_hd))
01825 show_broken_r(vbp, r, fancy);
01826 }
01827
01828 static struct bn_vlblock *vbp = (struct bn_vlblock *)NULL;
01829 static int stepalong = 0;
01830
01831 void
01832 nmg_plot_sigstepalong(int i)
01833 {
01834 stepalong=1;
01835 }
01836
01837
01838
01839
01840
01841
01842
01843 void
01844 nmg_show_broken_classifier_stuff(long int *p, long int **classlist, int all_new, int fancy, const char *a_string)
01845 {
01846 struct model *m;
01847
01848
01849
01850 global_classlist = classlist;
01851
01852 nmg_class_nothing_broken = 0;
01853
01854 if (!vbp)
01855 vbp = rt_vlblock_init();
01856 else if (all_new) {
01857 rt_vlblock_free(vbp);
01858 vbp = (struct bn_vlblock *)NULL;
01859 vbp = rt_vlblock_init();
01860 }
01861
01862 m = nmg_find_model(p);
01863
01864 if (!broken_tab) {
01865 broken_tab = (long *)bu_calloc( m->maxindex+1, sizeof(long),
01866 "nmg_vlblock_s tab[]");
01867 broken_tab_len = m->maxindex+1;
01868 } else {
01869 if( broken_tab_len < m->maxindex+1 ) {
01870 bu_log("nmg_show_broken_classifier_stuff() maxindex increased! was %d, now %d\n",
01871 broken_tab_len, m->maxindex+1 );
01872 broken_tab = (long *)rt_realloc( (char *)broken_tab,
01873 (m->maxindex+1) * sizeof(long),
01874 "nmg_vlblock_s tab[] enlargement");
01875 broken_tab_len = m->maxindex+1;
01876 }
01877 if (all_new) {
01878 bzero( (char *)broken_tab, (m->maxindex+1) * sizeof(long));
01879 }
01880 }
01881
01882
01883 switch (*p) {
01884 case NMG_MODEL_MAGIC:
01885 show_broken_m( vbp, (struct model *)p, fancy);
01886 break;
01887 case NMG_REGION_MAGIC:
01888 show_broken_r( vbp, (struct nmgregion *)p, fancy);
01889 break;
01890 case NMG_SHELL_MAGIC:
01891 show_broken_s( vbp, (struct shell *)p, fancy);
01892 break;
01893 case NMG_FACE_MAGIC:
01894 show_broken_fu( vbp, ((struct face *)p)->fu_p, fancy);
01895 break;
01896 case NMG_FACEUSE_MAGIC:
01897 show_broken_fu( vbp, (struct faceuse *)p, fancy);
01898 #if 0
01899 {
01900 struct bn_vlblock *vbp2 = vbp;
01901 register struct loopuse *lu;
01902 struct faceuse *fu = (struct faceuse *)p;
01903 int i;
01904 void (*cur_sigint)();
01905
01906 cur_sigint = signal(SIGINT, nmg_plot_sigstepalong);
01907 for (stepalong=0;!stepalong;) {
01908 for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
01909 nmg_show_broken_classifier_stuff(lu, classlist, 1, fancy);
01910 for (i=0 ; ++i ; );
01911 }
01912 }
01913 signal(SIGINT, cur_sigint);
01914
01915 show_broken_fu( vbp, (struct faceuse *)p, fancy);
01916 }
01917 #endif
01918 break;
01919 case NMG_LOOPUSE_MAGIC:
01920 show_broken_lu( vbp, (struct loopuse *)p, fancy);
01921 break;
01922 case NMG_EDGE_MAGIC:
01923 show_broken_eu( vbp, ((struct edge *)p)->eu_p, fancy);
01924 break;
01925 case NMG_EDGEUSE_MAGIC:
01926 show_broken_eu( vbp, (struct edgeuse *)p, fancy);
01927 break;
01928 case NMG_VERTEXUSE_MAGIC:
01929 show_broken_vu( vbp, (struct vertexuse *)p, fancy);
01930 break;
01931 default: fprintf(stderr, "Unknown magic number %ld %0lx %lu %0lx\n", *p, *p, (unsigned long)p, (unsigned long)p);
01932 break;
01933 }
01934
01935
01936
01937
01938 if( nmg_vlblock_anim_upcall ) {
01939 void (*cur_sigint)();
01940
01941 if (!a_string) {
01942 (*nmg_vlblock_anim_upcall)( vbp,
01943 (rt_g.NMG_debug&DEBUG_PL_SLOW) ? US_DELAY : 0,
01944 1 );
01945 } else {
01946
01947 bu_log("NMG Intermediate display Ctrl-C to continue (%s)\n", a_string);
01948 cur_sigint = signal(SIGINT, nmg_plot_sigstepalong);
01949 (*nmg_vlblock_anim_upcall)( vbp,
01950 (rt_g.NMG_debug&DEBUG_PL_SLOW) ? US_DELAY : 0,
01951 1 );
01952 for (stepalong = 0; !stepalong ; ) {
01953 (*nmg_mged_debug_display_hack)();
01954 }
01955 signal(SIGINT, cur_sigint);
01956 bu_log("Continuing\n");
01957 }
01958 } else {
01959
01960 char buf[128];
01961 static int num=0;
01962 FILE *fp;
01963
01964 sprintf( buf, "cbroke%d.pl", num++ );
01965 if( (fp = fopen(buf, "w")) ) {
01966 rt_plot_vlblock(fp, vbp);
01967 fclose(fp);
01968 bu_log("overlay %s for %s\n", buf, a_string);
01969 }
01970
01971 rt_vlblock_free(vbp);
01972 vbp = (struct bn_vlblock *)NULL;
01973 bu_free((char *)broken_tab, "broken_tab");
01974 broken_tab = (long *)NULL;
01975 broken_tab_len = 0;
01976 }
01977 }
01978
01979
01980
01981
01982 void
01983 nmg_face_plot(const struct faceuse *fu)
01984 {
01985 FILE *fp;
01986 char name[32];
01987 extern void (*nmg_vlblock_anim_upcall)();
01988 struct model *m;
01989 struct bn_vlblock *vbp;
01990 long *tab;
01991 int fancy;
01992 static int num = 1;
01993
01994 if( (rt_g.NMG_debug & (DEBUG_PLOTEM|DEBUG_PL_ANIM)) == 0 ) return;
01995
01996 NMG_CK_FACEUSE(fu);
01997
01998 m = nmg_find_model( (long *)fu );
01999 NMG_CK_MODEL(m);
02000
02001
02002 tab = (long *)bu_calloc( m->maxindex+1, sizeof(long),
02003 "nmg_face_plot tab[]");
02004
02005 vbp = rt_vlblock_init();
02006
02007 fancy = 3;
02008 nmg_vlblock_fu(vbp, fu, tab, fancy );
02009
02010 if( rt_g.NMG_debug & DEBUG_PLOTEM ) {
02011 (void)sprintf(name, "face%d.pl", num++);
02012 bu_log("overlay %s\n", name);
02013 if ((fp=fopen(name, "w")) == (FILE *)NULL) {
02014 perror(name);
02015 return;
02016 }
02017 rt_plot_vlblock( fp, vbp );
02018 (void)fclose(fp);
02019 }
02020
02021 if( rt_g.NMG_debug & DEBUG_PL_ANIM ) {
02022
02023 if( nmg_vlblock_anim_upcall ) {
02024
02025 (*nmg_vlblock_anim_upcall)( vbp,
02026 (rt_g.NMG_debug&DEBUG_PL_SLOW) ? 750000 : 0,
02027 0 );
02028 } else {
02029 bu_log("null nmg_vlblock_anim_upcall, no animation\n");
02030 }
02031 }
02032 rt_vlblock_free(vbp);
02033 bu_free( (char *)tab, "nmg_face_plot tab[]" );
02034
02035 }
02036
02037
02038
02039
02040
02041
02042 void
02043 nmg_2face_plot(const struct faceuse *fu1, const struct faceuse *fu2)
02044 {
02045 extern void (*nmg_vlblock_anim_upcall)();
02046 struct model *m;
02047 struct bn_vlblock *vbp;
02048 long *tab;
02049 int fancy;
02050
02051 if( ! (rt_g.NMG_debug & DEBUG_PL_ANIM) ) return;
02052
02053 NMG_CK_FACEUSE(fu1);
02054 NMG_CK_FACEUSE(fu2);
02055
02056 m = nmg_find_model( (long *)fu1 );
02057 NMG_CK_MODEL(m);
02058
02059
02060 tab = (long *)bu_calloc( m->maxindex+1, sizeof(long),
02061 "nmg_2face_plot tab[]");
02062
02063 vbp = rt_vlblock_init();
02064
02065 fancy = 3;
02066 nmg_vlblock_fu(vbp, fu1, tab, fancy );
02067 nmg_vlblock_fu(vbp, fu2, tab, fancy );
02068
02069
02070 if( nmg_vlblock_anim_upcall ) {
02071
02072 (*nmg_vlblock_anim_upcall)( vbp,
02073 (rt_g.NMG_debug&DEBUG_PL_SLOW) ? 750000 : 0,
02074 0 );
02075 } else {
02076 bu_log("null nmg_vlblock_anim_upcall, no animation\n");
02077 }
02078 rt_vlblock_free(vbp);
02079 bu_free( (char *)tab, "nmg_2face_plot tab[]" );
02080
02081 }
02082
02083
02084
02085
02086
02087
02088 void
02089 nmg_face_lu_plot(const struct loopuse *lu, const struct vertexuse *vu1, const struct vertexuse *vu2)
02090 {
02091 FILE *fp;
02092 struct model *m;
02093 long *b;
02094 char buf[128];
02095 static int num = 0;
02096 vect_t dir;
02097 point_t p1, p2;
02098
02099 if(!(rt_g.NMG_debug&DEBUG_PLOTEM)) return;
02100
02101 NMG_CK_LOOPUSE(lu);
02102 NMG_CK_VERTEXUSE(vu1);
02103 NMG_CK_VERTEXUSE(vu2);
02104
02105 m = nmg_find_model((long *)lu);
02106 sprintf(buf, "loop%d.pl", num++ );
02107
02108 if( (fp = fopen(buf, "w")) == NULL ) {
02109 perror(buf);
02110 return;
02111 }
02112 b = (long *)bu_calloc( m->maxindex, sizeof(long), "nmg_face_lu_plot flag[]" );
02113 nmg_pl_lu(fp, lu, b, 255, 0, 0);
02114
02115
02116
02117
02118
02119
02120 pl_color(fp, 255, 255, 0);
02121 VSUB2( dir, vu2->v_p->vg_p->coord, vu1->v_p->vg_p->coord );
02122 VJOIN1( p1, vu1->v_p->vg_p->coord, -0.1, dir );
02123 pdv_3line(fp, p1, vu1->v_p->vg_p->coord );
02124 VJOIN1( p2, vu1->v_p->vg_p->coord, 1.1, dir );
02125 pdv_3line(fp, vu2->v_p->vg_p->coord, p2 );
02126
02127 fclose(fp);
02128 bu_log("overlay %s\n", buf);
02129 bu_free( (char *)b, "nmg_face_lu_plot flag[]" );
02130 }
02131
02132
02133
02134
02135
02136
02137 void
02138 nmg_plot_lu_ray(const struct loopuse *lu, const struct vertexuse *vu1, const struct vertexuse *vu2, const fastf_t *left)
02139 {
02140 FILE *fp;
02141 struct model *m;
02142 long *b;
02143 char buf[128];
02144 static int num = 0;
02145 vect_t dir;
02146 point_t p1, p2;
02147 fastf_t left_mag;
02148
02149 if(!(rt_g.NMG_debug&DEBUG_PLOTEM)) return;
02150
02151 NMG_CK_LOOPUSE(lu);
02152 NMG_CK_VERTEXUSE(vu1);
02153 NMG_CK_VERTEXUSE(vu2);
02154
02155 m = nmg_find_model((long *)lu);
02156 sprintf(buf, "loop%d.pl", num++ );
02157
02158 if( (fp = fopen(buf, "w")) == NULL ) {
02159 perror(buf);
02160 return;
02161 }
02162 b = (long *)bu_calloc( m->maxindex, sizeof(long), "nmg_plot_lu_ray flag[]" );
02163 nmg_pl_lu(fp, lu, b, 255, 0, 0);
02164
02165
02166
02167
02168
02169
02170 pl_color(fp, 255, 255, 0);
02171 VSUB2( dir, vu2->v_p->vg_p->coord, vu1->v_p->vg_p->coord );
02172 VJOIN1( p1, vu1->v_p->vg_p->coord, -0.1, dir );
02173 pdv_3line(fp, p1, vu1->v_p->vg_p->coord );
02174 VJOIN1( p2, vu1->v_p->vg_p->coord, 1.1, dir );
02175 pdv_3line(fp, vu2->v_p->vg_p->coord, p2 );
02176
02177
02178 left_mag = 0.1 * MAGNITUDE(dir);
02179 VJOIN1( p2, p1, left_mag, left );
02180 pdv_3line(fp, p1, p2);
02181
02182 fclose(fp);
02183 bu_log("overlay %s\n", buf);
02184 bu_free( (char *)b, "nmg_plot_lu_ray flag[]" );
02185 }
02186
02187
02188
02189
02190 void
02191 nmg_plot_ray_face(const char *fname, fastf_t *pt, const fastf_t *dir, const struct faceuse *fu)
02192 {
02193 FILE *fd;
02194 long *b;
02195 point_t pp;
02196 static int i=0;
02197 char name[1024] = {0};
02198
02199 if ( ! (rt_g.NMG_debug & DEBUG_NMGRT) )
02200 return;
02201
02202 sprintf(name, "%s%0d.pl", fname, i++);
02203 if ((fd = fopen(name, "w")) == (FILE *)NULL) {
02204 perror(name);
02205 bu_log("plot_ray_face cannot open %s", name);
02206 rt_bomb("aborting");
02207 }
02208
02209 b = (long *)bu_calloc( fu->s_p->r_p->m_p->maxindex, sizeof(long), "bit vec");
02210
02211 nmg_pl_fu(fd, fu, b, 200, 200, 200);
02212
02213 bu_free((char *)b, "bit vec");
02214
02215 VSCALE(pp, dir, 1000.0);
02216 VADD2(pp, pt, pp);
02217 pdv_3line( fd, pt, pp );
02218 (void)fclose(fd);
02219 bu_log("overlay %s\n", name);
02220 }
02221
02222
02223
02224
02225
02226
02227
02228
02229 void
02230 nmg_plot_lu_around_eu(const char *prefix, const struct edgeuse *eu, const struct bn_tol *tol)
02231 {
02232 char file[256];
02233 static int num=0;
02234 struct model *m;
02235 struct bn_vlblock *vbp;
02236 long *tab;
02237 const struct edgeuse *eur;
02238 FILE *fp;
02239
02240 NMG_CK_EDGEUSE(eu);
02241 BN_CK_TOL(tol);
02242
02243 sprintf(file, "%s%0d.pl", prefix, num++);
02244 bu_log("overlay %s\n", file);
02245 if ((fp = fopen(file, "w")) == (FILE *)NULL) {
02246 bu_log("plot_lu_around_eu() cannot open %s", file);
02247 return;
02248 }
02249
02250 m = nmg_find_model( (long *)eu );
02251 NMG_CK_MODEL(m);
02252 tab = (long *)bu_calloc( m->maxindex, sizeof(long), "bit vec");
02253
02254 vbp = rt_vlblock_init();
02255
02256
02257 nmg_vlblock_around_eu(vbp, eu, tab, 3, tol );
02258
02259 eur = eu;
02260 do {
02261 NMG_CK_EDGEUSE(eur);
02262
02263 if (*eur->up.magic_p == NMG_LOOPUSE_MAGIC ) {
02264
02265 nmg_vlblock_lu(vbp, eur->up.lu_p, tab, 80, 100, 170, 0, 0 );
02266 }
02267 eur = eur->radial_p->eumate_p;
02268 } while (eur != eu);
02269
02270 rt_plot_vlblock( fp, vbp );
02271 (void)fclose(fp);
02272 rt_vlblock_free(vbp);
02273 bu_free((char *)tab, "bit vec");
02274 }
02275
02276
02277
02278
02279
02280
02281
02282 int
02283 nmg_snurb_to_vlist(struct bu_list *vhead, const struct face_g_snurb *fg, int n_interior)
02284
02285
02286
02287 {
02288 register int i;
02289 register int j;
02290 register fastf_t * vp;
02291 struct knot_vector tkv1,
02292 tkv2,
02293 tau1,
02294 tau2;
02295 struct face_g_snurb *r, *c;
02296 int coords;
02297
02298 BU_CK_LIST_HEAD( vhead );
02299 NMG_CK_FACE_G_SNURB(fg);
02300
02301 rt_nurb_kvgen( &tkv1,
02302 fg->u.knots[0],
02303 fg->u.knots[fg->u.k_size-1], n_interior, (struct resource *)NULL);
02304
02305 rt_nurb_kvgen( &tkv2,
02306 fg->v.knots[0],
02307 fg->v.knots[fg->v.k_size-1], n_interior, (struct resource *)NULL);
02308
02309 rt_nurb_kvmerge(&tau1, &tkv1, &fg->u, (struct resource *)NULL);
02310 rt_nurb_kvmerge(&tau2, &tkv2, &fg->v, (struct resource *)NULL);
02311
02312
02313
02314 r = rt_nurb_s_refine( fg, RT_NURB_SPLIT_COL, &tau2, (struct resource *)NULL);
02315 NMG_CK_SNURB(r);
02316 c = rt_nurb_s_refine( r, RT_NURB_SPLIT_ROW, &tau1, (struct resource *)NULL);
02317 NMG_CK_SNURB(c);
02318
02319 coords = RT_NURB_EXTRACT_COORDS(c->pt_type);
02320
02321 if( RT_NURB_IS_PT_RATIONAL(c->pt_type))
02322 {
02323 vp = c->ctl_points;
02324 for(i= 0;
02325 i < c->s_size[0] * c->s_size[1];
02326 i++)
02327 {
02328 FAST fastf_t div;
02329 vp[0] *= (div = 1/vp[3]);
02330 vp[1] *= div;
02331 vp[2] *= div;
02332 vp[3] *= div;
02333 vp += coords;
02334 }
02335 }
02336
02337 vp = c->ctl_points;
02338 for( i = 0; i < c->s_size[0]; i++)
02339 {
02340 RT_ADD_VLIST( vhead, vp, BN_VLIST_LINE_MOVE );
02341 vp += coords;
02342 for( j = 1; j < c->s_size[1]; j++)
02343 {
02344 RT_ADD_VLIST( vhead, vp, BN_VLIST_LINE_DRAW );
02345 vp += coords;
02346 }
02347 }
02348
02349 for( j = 0; j < c->s_size[1]; j++)
02350 {
02351 int stride;
02352
02353 stride = c->s_size[1] * coords;
02354 vp = &c->ctl_points[j * coords];
02355 RT_ADD_VLIST( vhead, vp, BN_VLIST_LINE_MOVE );
02356 vp += stride;
02357 for( i = 1; i < c->s_size[0]; i++)
02358 {
02359 RT_ADD_VLIST( vhead, vp, BN_VLIST_LINE_DRAW );
02360 vp += stride;
02361 }
02362 }
02363 rt_nurb_free_snurb(c, (struct resource *)NULL);
02364 rt_nurb_free_snurb(r, (struct resource *)NULL);
02365
02366 bu_free( (char *) tau1.knots, "rt_nurb_plot:tau1.knots");
02367 bu_free( (char *) tau2.knots, "rt_nurb_plot:tau2.knots");
02368 bu_free( (char *) tkv1.knots, "rt_nurb_plot:tkv1>knots");
02369 bu_free( (char *) tkv2.knots, "rt_nurb_plot:tkv2.knots");
02370
02371 return(0);
02372 }
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386 void
02387 nmg_cnurb_to_vlist(struct bu_list *vhead, const struct edgeuse *eu, int n_interior, int cmd)
02388
02389
02390
02391
02392 {
02393 const struct edge_g_cnurb *eg;
02394 const struct faceuse *fu;
02395 register int i;
02396 register fastf_t *vp = (fastf_t *)NULL;
02397 struct edge_g_cnurb n;
02398 const struct edge_g_cnurb *c;
02399 int coords;
02400
02401 BU_CK_LIST_HEAD( vhead );
02402 NMG_CK_EDGEUSE(eu);
02403 eg = eu->g.cnurb_p;
02404 NMG_CK_EDGE_G_CNURB(eg);
02405
02406 fu = nmg_find_fu_of_eu(eu);
02407 NMG_CK_FACEUSE(fu);
02408 if (rt_g.NMG_debug & DEBUG_BASIC) {
02409 bu_log("nmg_cnurb_to_vlist() eu=x%x, n=%d, order=%d\n",
02410 eu, n_interior, eg->order);
02411 }
02412
02413 if( eg->order <= 0 ) {
02414
02415 if( *fu->f_p->g.magic_p == NMG_FACE_G_PLANE_MAGIC )
02416 return;
02417
02418
02419 n.order = 2;
02420 n.l.magic = RT_CNURB_MAGIC;
02421 rt_nurb_gen_knot_vector( &n.k, n.order, 0.0, 1.0, (struct resource *)NULL );
02422 n.c_size = 2;
02423 n.pt_type = RT_NURB_MAKE_PT_TYPE(2, RT_NURB_PT_UV, RT_NURB_PT_NONRAT );
02424 n.ctl_points = (fastf_t *)bu_malloc(
02425 sizeof(fastf_t) * RT_NURB_EXTRACT_COORDS(n.pt_type) *
02426 n.c_size, "nmg_cnurb_to_vlist() order0 ctl_points[]");
02427
02428 NMG_CK_VERTEXUSE_A_CNURB(eu->vu_p->a.cnurb_p);
02429 n.ctl_points[0] = eu->vu_p->a.cnurb_p->param[0];
02430 n.ctl_points[1] = eu->vu_p->a.cnurb_p->param[1];
02431 n.ctl_points[2] = eu->eumate_p->vu_p->a.cnurb_p->param[0];
02432 n.ctl_points[3] = eu->eumate_p->vu_p->a.cnurb_p->param[1];
02433 c = &n;
02434 } else {
02435
02436 c = eg;
02437 }
02438
02439 NMG_CK_CNURB( c );
02440
02441 coords = RT_NURB_EXTRACT_COORDS( c->pt_type );
02442
02443 if( *fu->f_p->g.magic_p == NMG_FACE_G_PLANE_MAGIC ) {
02444
02445
02446 vp = c->ctl_points;
02447
02448 for( i = 1; i < c->c_size-1; i++) {
02449 RT_ADD_VLIST( vhead, vp, cmd );
02450 vp += coords;
02451 }
02452 } else {
02453 const struct face_g_snurb *s;
02454 fastf_t final[4];
02455 fastf_t inv_homo;
02456 fastf_t param_delta;
02457 fastf_t crv_param;
02458
02459
02460 if( coords != 2 && !RT_NURB_IS_PT_RATIONAL(c->pt_type) ) bu_log("nmg_cnurb_to_vlist() coords=%d\n", coords);
02461 s = fu->f_p->g.snurb_p;
02462
02463
02464
02465
02466
02467 param_delta = (c->k.knots[c->k.k_size-1] - c->k.knots[0])/(fastf_t)(n_interior+1);
02468 crv_param = c->k.knots[0];
02469 for( i = 0; i < n_interior; i++) {
02470 point_t uvw;
02471
02472
02473 crv_param += param_delta;
02474
02475 VSETALL(uvw,0);
02476
02477 rt_nurb_c_eval( c, crv_param, uvw );
02478
02479 if( RT_NURB_IS_PT_RATIONAL( c->pt_type ) )
02480 {
02481 uvw[0] = uvw[0]/uvw[2];
02482 uvw[1] = uvw[1]/uvw[2];
02483 }
02484
02485
02486 rt_nurb_s_eval( s, uvw[0], uvw[1], final );
02487
02488 if( RT_NURB_IS_PT_RATIONAL( s->pt_type ) )
02489 {
02490
02491 inv_homo = 1.0/final[3];
02492 VSCALE( final, final, inv_homo );
02493 }
02494
02495 RT_ADD_VLIST( vhead, final, cmd );
02496 vp += coords;
02497 }
02498 }
02499
02500 if( eg->order <= 0 ) {
02501 bu_free( (char *)n.k.knots, "nmg_cnurb_to_vlist() n.knot.knots");
02502 bu_free( (char *)n.ctl_points, "nmg_cnurb_to_vlist() ctl_points");
02503 }
02504 }
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514