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
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #ifndef lint
00069 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/nmg_mk.c,v 14.15 2006/09/16 02:04:25 lbutler Exp $ (ARL)";
00070 #endif
00071
00072 #include "common.h"
00073
00074 #include <stddef.h>
00075 #include <stdio.h>
00076 #include <math.h>
00077 #include <string.h>
00078
00079 #include "machine.h"
00080 #include "vmath.h"
00081 #include "nmg.h"
00082 #include "raytrace.h"
00083 #include "nurb.h"
00084
00085 static struct vertexuse *nmg_mvu BU_ARGS( (struct vertex *v, long *upptr,
00086 struct model *m) );
00087 static struct vertexuse *nmg_mvvu BU_ARGS( (long *upptr, struct model *m) );
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 struct model *
00262 nmg_mm(void)
00263 {
00264 struct model *m;
00265
00266 BU_GETSTRUCT( m, model );
00267
00268 BU_LIST_INIT( &m->r_hd );
00269 m->index = 0;
00270 m->maxindex = 1;
00271 m->magic = NMG_MODEL_MAGIC;
00272
00273 if (rt_g.NMG_debug & DEBUG_BASIC) {
00274 bu_log("nmg_mm() returns model x%x\n", m );
00275 }
00276
00277 return(m);
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 struct model *
00294 nmg_mmr(void)
00295 {
00296 struct model *m;
00297 struct nmgregion *r;
00298
00299 m = nmg_mm();
00300 GET_REGION(r, m);
00301
00302 r->m_p = m;
00303
00304 r->ra_p = (struct nmgregion_a *)NULL;
00305 BU_LIST_INIT( &r->s_hd );
00306 r->l.magic = NMG_REGION_MAGIC;
00307
00308 BU_LIST_APPEND( &m->r_hd, &r->l );
00309
00310 if (rt_g.NMG_debug & DEBUG_BASIC) {
00311 bu_log("nmg_mmr() returns model x%x with region x%x\n", m , r );
00312 }
00313
00314 return(m);
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 struct nmgregion *
00333 nmg_mrsv(struct model *m)
00334 {
00335 struct nmgregion *r;
00336
00337 NMG_CK_MODEL(m);
00338
00339 GET_REGION(r, m);
00340 r->m_p = m;
00341 r->ra_p = (struct nmgregion_a *) NULL;
00342
00343 BU_LIST_INIT( &r->s_hd );
00344 r->l.magic = NMG_REGION_MAGIC;
00345
00346 (void)nmg_msv(r);
00347
00348
00349 BU_LIST_APPEND( &m->r_hd, &r->l );
00350
00351 if (rt_g.NMG_debug & DEBUG_BASIC) {
00352 bu_log("nmg_mrsv(m=x%x) returns r=x%x\n" , m , r );
00353 }
00354
00355 return(r);
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 struct shell *
00373 nmg_msv(struct nmgregion *r)
00374 {
00375 struct shell *s;
00376 struct vertexuse *vu;
00377
00378 NMG_CK_REGION(r);
00379
00380
00381 GET_SHELL(s, r->m_p);
00382
00383 s->r_p = r;
00384 BU_LIST_APPEND( &r->s_hd, &s->l );
00385
00386 s->sa_p = (struct shell_a *)NULL;
00387 BU_LIST_INIT( &s->fu_hd );
00388 BU_LIST_INIT( &s->lu_hd );
00389 BU_LIST_INIT( &s->eu_hd );
00390 s->vu_p = (struct vertexuse *) NULL;
00391 s->l.magic = NMG_SHELL_MAGIC;
00392
00393 vu = nmg_mvvu(&s->l.magic, r->m_p);
00394 s->vu_p = vu;
00395
00396 if (rt_g.NMG_debug & DEBUG_BASIC) {
00397 bu_log("nmg_msv(r=x%x) returns s=x%x, vu=x%x\n" , r , s , s->vu_p );
00398 }
00399
00400 return(s);
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418 struct faceuse *
00419 nmg_mf(struct loopuse *lu1)
00420 {
00421 struct face *f;
00422 struct faceuse *fu1, *fu2;
00423 struct loopuse *lu2;
00424 struct shell *s;
00425 struct model *m;
00426
00427 NMG_CK_LOOPUSE(lu1);
00428 if (*lu1->up.magic_p != NMG_SHELL_MAGIC) {
00429 rt_bomb("nmg_mf() loop must be child of shell for making face\n");
00430 }
00431 lu2 = lu1->lumate_p;
00432 NMG_CK_LOOPUSE(lu2);
00433 if (lu2->up.magic_p != lu1->up.magic_p) {
00434 rt_bomb("nmg_mf() loopuse mate does not have same parent\n");
00435 }
00436
00437 s = lu1->up.s_p;
00438 NMG_CK_SHELL(s);
00439
00440 m = nmg_find_model( &s->l.magic );
00441 GET_FACE(f, m);
00442 GET_FACEUSE(fu1, m);
00443 GET_FACEUSE(fu2, m);
00444
00445 f->fu_p = fu1;
00446 f->g.plane_p = (struct face_g_plane *)NULL;
00447 f->flip = 0;
00448 BU_LIST_INIT(&f->l);
00449 f->l.magic = NMG_FACE_MAGIC;
00450
00451 BU_LIST_INIT(&fu1->lu_hd);
00452 BU_LIST_INIT(&fu2->lu_hd);
00453 fu1->s_p = fu2->s_p = s;
00454 fu1->fumate_p = fu2;
00455 fu2->fumate_p = fu1;
00456 fu1->orientation = fu2->orientation = OT_UNSPEC;
00457 fu1->f_p = fu2->f_p = f;
00458 fu1->l.magic =
00459 fu2->l.magic = NMG_FACEUSE_MAGIC;
00460
00461
00462 BU_LIST_DEQUEUE( &lu1->l );
00463 BU_LIST_DEQUEUE( &lu2->l );
00464 BU_LIST_APPEND( &fu1->lu_hd, &lu1->l );
00465 BU_LIST_APPEND( &fu2->lu_hd, &lu2->l );
00466
00467 lu1->up.fu_p = fu1;
00468 lu1->orientation = OT_SAME;
00469 lu2->up.fu_p = fu2;
00470 lu2->orientation = OT_SAME;
00471
00472
00473 BU_LIST_APPEND( &s->fu_hd, &fu1->l );
00474 BU_LIST_APPEND( &fu1->l, &fu2->l );
00475
00476 if (rt_g.NMG_debug & DEBUG_BASIC) {
00477 bu_log("nmg_mf(lu1=x%x) returns fu=x%x\n" , lu1 , fu1 );
00478 }
00479
00480 return(fu1);
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 struct loopuse *
00520 nmg_mlv(long int *magic, struct vertex *v, int orientation)
00521 {
00522 struct loop *l;
00523 struct loopuse *lu1, *lu2;
00524 struct vertexuse *vu1 = NULL;
00525 struct vertexuse *vu2;
00526 struct model *m;
00527
00528 union {
00529 struct shell *s;
00530 struct faceuse *fu;
00531 long *magic_p;
00532 } p;
00533
00534 p.magic_p = magic;
00535
00536 if (v) {
00537 NMG_CK_VERTEX(v);
00538 }
00539
00540 m = nmg_find_model( magic );
00541 GET_LOOP(l, m);
00542 GET_LOOPUSE(lu1, m);
00543 GET_LOOPUSE(lu2, m);
00544
00545 l->lg_p = (struct loop_g *)NULL;
00546 l->lu_p = lu1;
00547 l->magic = NMG_LOOP_MAGIC;
00548
00549 BU_LIST_INIT( &lu1->down_hd );
00550 BU_LIST_INIT( &lu2->down_hd );
00551 lu1->l_p = lu2->l_p = l;
00552 lu1->orientation = lu2->orientation = orientation;
00553
00554 lu1->lumate_p = lu2;
00555 lu2->lumate_p = lu1;
00556
00557
00558
00559 if (*p.magic_p == NMG_SHELL_MAGIC) {
00560 struct shell *s = p.s;
00561
00562
00563 lu1->up.s_p = lu2->up.s_p = s;
00564
00565 lu1->l.magic = lu2->l.magic =
00566 NMG_LOOPUSE_MAGIC;
00567
00568 BU_LIST_INSERT( &s->lu_hd, &lu1->l );
00569 BU_LIST_INSERT( &lu1->l, &lu2->l );
00570
00571
00572
00573 if ( (vu1 = s->vu_p) ) {
00574
00575 s->vu_p = (struct vertexuse *)NULL;
00576 vu1->up.lu_p = lu1;
00577 if (v) nmg_movevu(vu1, v);
00578 } else {
00579 if (v) vu1 = nmg_mvu(v, &lu1->l.magic, m);
00580 else vu1 = nmg_mvvu(&lu1->l.magic, m);
00581 }
00582 NMG_CK_VERTEXUSE(vu1);
00583 RT_LIST_SET_DOWN_TO_VERT(&lu1->down_hd, vu1);
00584
00585
00586 vu2 = nmg_mvu(vu1->v_p, &lu2->l.magic, m);
00587 NMG_CK_VERTEXUSE(vu2);
00588 RT_LIST_SET_DOWN_TO_VERT(&lu2->down_hd, vu2);
00589
00590 } else if (*p.magic_p == NMG_FACEUSE_MAGIC) {
00591
00592 lu1->up.fu_p = p.fu;
00593 lu2->up.fu_p = p.fu->fumate_p;
00594 lu1->l.magic = lu2->l.magic =
00595 NMG_LOOPUSE_MAGIC;
00596
00597 BU_LIST_INSERT( &p.fu->fumate_p->lu_hd, &lu2->l );
00598 BU_LIST_INSERT( &p.fu->lu_hd, &lu1->l );
00599
00600
00601 if (v) vu1 = nmg_mvu(v, &lu1->l.magic, m);
00602 else vu1 = nmg_mvvu(&lu1->l.magic, m);
00603 RT_LIST_SET_DOWN_TO_VERT(&lu1->down_hd, vu1);
00604
00605
00606 vu2 = nmg_mvu(vu1->v_p, &lu2->l.magic, m);
00607 RT_LIST_SET_DOWN_TO_VERT(&lu2->down_hd, vu2);
00608
00609 } else {
00610 rt_bomb("nmg_mlv() unknown parent for loopuse!\n");
00611 }
00612
00613 if (rt_g.NMG_debug & DEBUG_BASIC) {
00614 bu_log("nmg_mlv(up=x%x, v=x%x, %s) returns lu=x%x on vu=x%x\n",
00615 magic, v, nmg_orientation(orientation),
00616 lu1, vu1 );
00617 }
00618 return(lu1);
00619 }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 static struct vertexuse *
00633 nmg_mvu(struct vertex *v, long int *upptr, struct model *m)
00634
00635
00636
00637 {
00638 struct vertexuse *vu;
00639
00640 NMG_CK_VERTEX(v);
00641 NMG_CK_MODEL(m);
00642
00643 if (*upptr != NMG_SHELL_MAGIC &&
00644 *upptr != NMG_LOOPUSE_MAGIC &&
00645 *upptr != NMG_EDGEUSE_MAGIC) {
00646 bu_log("nmg_mvu() in %s at %d magic not shell, loop, or edge. Was x%x (%s)\n",
00647 __FILE__, __LINE__,
00648 *upptr, bu_identify_magic(*upptr) );
00649 rt_bomb("nmg_mvu() Cannot build vertexuse without parent\n");
00650 }
00651
00652 GET_VERTEXUSE(vu, m);
00653
00654 vu->v_p = v;
00655 vu->a.plane_p = (struct vertexuse_a_plane *)NULL;
00656 BU_LIST_APPEND( &v->vu_hd, &vu->l );
00657 vu->up.magic_p = upptr;
00658 vu->l.magic = NMG_VERTEXUSE_MAGIC;
00659
00660 if (rt_g.NMG_debug & DEBUG_BASIC) {
00661 bu_log("nmg_mvu(v=x%x, up=x%x) returns vu=x%x\n",
00662 v, upptr, vu);
00663 }
00664 return(vu);
00665 }
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 static struct vertexuse *
00679 nmg_mvvu(long int *upptr, struct model *m)
00680 {
00681 struct vertex *v;
00682 struct vertexuse *ret_vu;
00683
00684 NMG_CK_MODEL(m);
00685 GET_VERTEX(v, m);
00686 BU_LIST_INIT( &v->vu_hd );
00687 v->vg_p = (struct vertex_g *)NULL;
00688 v->magic = NMG_VERTEX_MAGIC;
00689 ret_vu = nmg_mvu(v, upptr, m);
00690
00691 if (rt_g.NMG_debug & DEBUG_BASIC) {
00692 bu_log("nmg_mvvu(upptr=x%x,m=x%x) returns vu=x%x\n" , upptr , m , ret_vu );
00693 }
00694
00695 return( ret_vu );
00696 }
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723 struct edgeuse *
00724 nmg_me(struct vertex *v1, struct vertex *v2, struct shell *s)
00725 {
00726 struct edge *e;
00727 struct edgeuse *eu1;
00728 struct edgeuse *eu2;
00729 struct vertexuse *vu;
00730 struct model *m;
00731
00732 if (v1) NMG_CK_VERTEX(v1);
00733 if (v2) NMG_CK_VERTEX(v2);
00734 NMG_CK_SHELL(s);
00735
00736 m = nmg_find_model( &s->l.magic );
00737 GET_EDGE(e, m);
00738 GET_EDGEUSE(eu1, m);
00739 GET_EDGEUSE(eu2, m);
00740
00741 BU_LIST_INIT( &eu1->l2 );
00742 BU_LIST_INIT( &eu2->l2 );
00743 eu1->l2.magic = eu2->l2.magic = NMG_EDGEUSE2_MAGIC;
00744
00745 e->eu_p = eu1;
00746
00747 e->magic = NMG_EDGE_MAGIC;
00748
00749 eu1->radial_p = eu1->eumate_p = eu2;
00750 eu2->radial_p = eu2->eumate_p = eu1;
00751
00752 eu1->e_p = eu2->e_p = e;
00753 eu1->orientation = eu2->orientation = OT_NONE;
00754
00755 eu1->vu_p = eu2->vu_p = (struct vertexuse *) NULL;
00756
00757 eu1->l.magic = eu2->l.magic =
00758 NMG_EDGEUSE_MAGIC;
00759
00760
00761
00762
00763
00764 eu1->up.s_p = eu2->up.s_p = s;
00765
00766 if (v1) {
00767 eu1->vu_p = nmg_mvu(v1, &eu1->l.magic, m);
00768 } else if (s->vu_p) {
00769
00770
00771 vu = s->vu_p;
00772 s->vu_p = (struct vertexuse *)NULL;
00773 eu1->vu_p = vu;
00774 vu->up.eu_p = eu1;
00775 } else {
00776 eu1->vu_p = nmg_mvvu(&eu1->l.magic, m);
00777 }
00778
00779 if (v2) {
00780 eu2->vu_p = nmg_mvu(v2, &eu2->l.magic, m);
00781 } else if (s->vu_p) {
00782
00783
00784 vu = s->vu_p;
00785 s->vu_p = (struct vertexuse *)NULL;
00786 eu2->vu_p = vu;
00787 vu->up.eu_p = eu2;
00788 } else {
00789 eu2->vu_p = nmg_mvvu(&eu2->l.magic, m);
00790 }
00791
00792
00793 if( s->vu_p ) {
00794
00795 (void)nmg_kvu( s->vu_p );
00796 s->vu_p = (struct vertexuse *)NULL;
00797 }
00798
00799
00800 BU_LIST_APPEND( &s->eu_hd, &eu1->l );
00801 BU_LIST_APPEND( &eu1->l, &eu2->l );
00802
00803 if (rt_g.NMG_debug & DEBUG_BASIC) {
00804 bu_log("nmg_me(v1=x%x, v2=x%x, s=x%x) returns eu=x%x\n" , v1 , v2 , s , eu1 );
00805 }
00806
00807 return(eu1);
00808 }
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 struct edgeuse *
00825 nmg_meonvu(struct vertexuse *vu)
00826 {
00827 struct edge *e;
00828 struct edgeuse *eu1, *eu2;
00829 struct model *m;
00830
00831 NMG_CK_VERTEXUSE(vu);
00832
00833 m = nmg_find_model( vu->up.magic_p );
00834 GET_EDGE(e, m);
00835 GET_EDGEUSE(eu1, m);
00836 GET_EDGEUSE(eu2, m);
00837
00838 BU_LIST_INIT( &eu1->l2 );
00839 BU_LIST_INIT( &eu2->l2 );
00840 eu1->l2.magic = eu2->l2.magic = NMG_EDGEUSE2_MAGIC;
00841
00842 e->eu_p = eu1;
00843 e->is_real = 0;
00844 e->magic = NMG_EDGE_MAGIC;
00845
00846 eu1->radial_p = eu1->eumate_p = eu2;
00847 eu2->radial_p = eu2->eumate_p = eu1;
00848 eu1->e_p = eu2->e_p = e;
00849 eu1->orientation = eu2->orientation = OT_NONE;
00850
00851 eu1->vu_p = vu;
00852
00853
00854
00855 eu2->vu_p = (struct vertexuse *) NULL;
00856
00857
00858 if (*vu->up.magic_p == NMG_SHELL_MAGIC) {
00859 struct shell *s;
00860
00861 s = eu2->up.s_p = eu1->up.s_p = vu->up.s_p;
00862 eu1->l.magic = eu2->l.magic =
00863 NMG_EDGEUSE_MAGIC;
00864
00865
00866 vu->up.eu_p = eu1;
00867
00868 if( s->vu_p != vu )
00869 rt_bomb("nmg_meonvu() vetexuse parent shell disowns vertexuse!\n");
00870 s->vu_p = (struct vertexuse *)NULL;
00871
00872 eu2->vu_p = nmg_mvu(vu->v_p, &eu2->l.magic, m);
00873 BU_LIST_APPEND( &s->eu_hd, &eu2->l );
00874 BU_LIST_APPEND( &s->eu_hd, &eu1->l );
00875 } else if (*vu->up.magic_p == NMG_LOOPUSE_MAGIC) {
00876 struct loopuse *lu;
00877 struct loopuse *lumate;
00878 struct vertexuse *vumate;
00879
00880 lu = vu->up.lu_p;
00881 NMG_CK_LOOPUSE(lu);
00882 lumate = lu->lumate_p;
00883 NMG_CK_LOOPUSE(lumate);
00884
00885
00886 if( lu == lumate ) rt_bomb("nmg_meonvu() lu mate is lu\n");
00887 if( BU_LIST_FIRST_MAGIC(&lumate->down_hd) != NMG_VERTEXUSE_MAGIC )
00888 rt_bomb("nmg_meonvu() mate of vertex-loop is not vertex-loop!\n");
00889 vumate = BU_LIST_FIRST(vertexuse, &lumate->down_hd);
00890 NMG_CK_VERTEXUSE(vumate);
00891 if( vu == vumate ) rt_bomb("nmg_meonvu() vu mate is vu\n");
00892 NMG_CK_VERTEX(vu->v_p);
00893 NMG_CK_VERTEX(vumate->v_p);
00894
00895
00896 eu2->vu_p = vumate;
00897
00898
00899 eu1->up.lu_p = lu;
00900 eu2->up.lu_p = lumate;
00901
00902 eu1->l.magic = eu2->l.magic =
00903 NMG_EDGEUSE_MAGIC;
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 BU_LIST_INIT( &lu->down_hd );
00914 BU_LIST_INIT( &lumate->down_hd );
00915
00916 BU_LIST_APPEND( &lumate->down_hd, &eu2->l );
00917 BU_LIST_APPEND( &lu->down_hd, &eu1->l );
00918
00919
00920 vu->up.eu_p = eu1;
00921 vumate->up.eu_p = eu2;
00922 } else {
00923 rt_bomb("nmg_meonvu() cannot make edge, vertexuse not sole element of object\n");
00924 }
00925
00926 if (rt_g.NMG_debug & DEBUG_BASIC) {
00927 bu_log("nmg_meonvu(vu=x%x) returns eu=x%x\n" , vu , eu1 );
00928 }
00929
00930 return(eu1);
00931 }
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 struct loopuse *
00953 nmg_ml(struct shell *s)
00954 {
00955 struct loop *l;
00956 struct loopuse *lu1, *lu2;
00957 struct edgeuse *p1;
00958 struct edgeuse *p2;
00959 struct edgeuse *feu;
00960 struct model *m;
00961
00962 NMG_CK_SHELL(s);
00963
00964 if( BU_LIST_IS_EMPTY( &s->eu_hd ) && s->vu_p ) {
00965 NMG_CK_VERTEXUSE(s->vu_p);
00966 NMG_CK_VERTEX(s->vu_p->v_p);
00967 lu1 = nmg_mlv(&s->l.magic, s->vu_p->v_p, OT_UNSPEC);
00968
00969
00970 if (rt_g.NMG_debug & DEBUG_BASIC) {
00971 bu_log("nmg_ml(s=x%x) returns lu of single vertex=x%x\n" , s , lu1 );
00972 }
00973
00974 return lu1;
00975 }
00976
00977 m = nmg_find_model( &s->l.magic );
00978 GET_LOOP(l, m);
00979 GET_LOOPUSE(lu1, m);
00980 GET_LOOPUSE(lu2, m);
00981
00982 l->lg_p = (struct loop_g *)NULL;
00983 l->lu_p = lu1;
00984 l->magic = NMG_LOOP_MAGIC;
00985
00986 BU_LIST_INIT( &lu1->down_hd );
00987 BU_LIST_INIT( &lu2->down_hd );
00988 lu1->l_p = lu2->l_p = l;
00989 lu1->orientation = lu2->orientation = OT_UNSPEC;
00990 lu1->lumate_p = lu2;
00991 lu2->lumate_p = lu1;
00992 lu1->up.s_p = lu2->up.s_p = s;
00993 lu1->l.magic = lu2->l.magic =
00994 NMG_LOOPUSE_MAGIC;
00995
00996
00997 feu = BU_LIST_FIRST( edgeuse, &s->eu_hd );
00998 if (feu){
00999 NMG_CK_EDGEUSE(feu);
01000 NMG_CK_VERTEXUSE(feu->vu_p);
01001 NMG_CK_VERTEX(feu->vu_p->v_p);
01002 }
01003
01004
01005 p2 = (struct edgeuse *)NULL;
01006 while( BU_LIST_NON_EMPTY( &s->eu_hd ) ) {
01007 p1 = BU_LIST_FIRST( edgeuse, &s->eu_hd );
01008 NMG_CK_EDGEUSE(p1);
01009 p2 = p1->eumate_p;
01010 NMG_CK_EDGEUSE(p2);
01011
01012
01013 if (p1->up.s_p != s || p2->up.s_p != s)
01014 rt_bomb("nmg_ml() edgeuse mates don't have proper parent!\n");
01015
01016
01017 BU_LIST_DEQUEUE( &p1->l );
01018 if( BU_LIST_IS_EMPTY( &s->eu_hd ) ) {
01019 bu_log("nmg_ml() in %s at %d edgeuse mate not in this shell\n",
01020 __FILE__, __LINE__);
01021 rt_bomb("nmg_ml\n");
01022 }
01023
01024
01025 BU_LIST_DEQUEUE( &p2->l );
01026
01027
01028
01029
01030
01031 BU_LIST_INSERT( &lu1->down_hd, &p1->l );
01032 BU_LIST_INSERT( &lu2->down_hd, &p2->l );
01033
01034 p1->up.lu_p = lu1;
01035 p2->up.lu_p = lu2;
01036
01037
01038 if( BU_LIST_IS_EMPTY( &s->eu_hd ) ) break;
01039 p1 = BU_LIST_FIRST( edgeuse, &s->eu_hd );
01040 NMG_CK_EDGEUSE(p1);
01041 NMG_CK_VERTEXUSE(p1->vu_p);
01042 NMG_CK_VERTEX(p1->vu_p->v_p);
01043 NMG_CK_VERTEXUSE(p2->vu_p);
01044 NMG_CK_VERTEX(p2->vu_p->v_p);
01045 if( p1->vu_p->v_p != p2->vu_p->v_p ) {
01046 break;
01047 }
01048 }
01049
01050 if (p2) {
01051 NMG_CK_EDGEUSE(p2);
01052 NMG_CK_VERTEXUSE(p2->vu_p);
01053 NMG_CK_VERTEX(p2->vu_p->v_p);
01054 }
01055 if( p2 && p2->vu_p->v_p != feu->vu_p->v_p) {
01056 bu_log("nmg_ml() Edge(use)s do not form proper loop!\n");
01057 nmg_pr_s(s, (char *)NULL);
01058 bu_log("nmg_ml() Edge(use)s do not form proper loop!\n");
01059 rt_bomb("nmg_ml\n");
01060 }
01061
01062
01063 BU_LIST_APPEND( &s->lu_hd, &lu2->l );
01064 BU_LIST_APPEND( &s->lu_hd, &lu1->l );
01065
01066 if (rt_g.NMG_debug & DEBUG_BASIC) {
01067 bu_log("nmg_ml(s=x%x) returns lu=x%x\n" , s , lu1 );
01068 }
01069
01070 return(lu1);
01071 }
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119 int
01120 nmg_kvu(register struct vertexuse *vu)
01121 {
01122 struct vertex *v;
01123 int ret = 0;
01124
01125 NMG_CK_VERTEXUSE(vu);
01126
01127 if (vu->a.magic_p) {
01128 NMG_CK_VERTEXUSE_A_EITHER(vu->a.magic_p);
01129 switch(*vu->a.magic_p) {
01130 case NMG_VERTEXUSE_A_PLANE_MAGIC:
01131 FREE_VERTEXUSE_A_PLANE(vu->a.plane_p);
01132 break;
01133 case NMG_VERTEXUSE_A_CNURB_MAGIC:
01134 FREE_VERTEXUSE_A_CNURB(vu->a.cnurb_p);
01135 break;
01136 }
01137 }
01138
01139 v = vu->v_p;
01140 NMG_CK_VERTEX(v);
01141
01142 BU_LIST_DEQUEUE( &vu->l );
01143 if( BU_LIST_IS_EMPTY( &v->vu_hd ) ) {
01144
01145 if (v->vg_p) FREE_VERTEX_G(v->vg_p);
01146 FREE_VERTEX(v);
01147 }
01148
01149
01150 if (vu->up.magic_p != (long *)NULL) {
01151 if (*vu->up.magic_p == NMG_SHELL_MAGIC) {
01152 if (vu->up.s_p) {
01153 vu->up.s_p->vu_p = (struct vertexuse *)NULL;
01154 ret = nmg_shell_is_empty(vu->up.s_p);
01155 }
01156 } else if (*vu->up.magic_p == NMG_LOOPUSE_MAGIC) {
01157 if (vu->up.lu_p) {
01158
01159 BU_LIST_INIT( &vu->up.lu_p->down_hd );
01160 ret = 1;
01161 }
01162 } else if (*vu->up.magic_p == NMG_EDGEUSE_MAGIC) {
01163 if (vu->up.eu_p) {
01164 vu->up.eu_p->vu_p = (struct vertexuse *)NULL;
01165 ret = 1;
01166 }
01167 } else
01168 rt_bomb("nmg_kvu() killing vertexuse of unknown parent?\n");
01169 }
01170
01171 FREE_VERTEXUSE(vu);
01172 if (rt_g.NMG_debug & DEBUG_BASIC) {
01173 bu_log("nmg_kvu(vu=x%x) ret=%d\n", vu, ret);
01174 }
01175 return ret;
01176 }
01177
01178
01179
01180
01181
01182
01183
01184 static void
01185 nmg_kfg(long int *magic_p)
01186 {
01187 switch( *magic_p ) {
01188 case NMG_FACE_G_PLANE_MAGIC:
01189
01190 {
01191 struct face_g_plane *pp;
01192 pp = (struct face_g_plane *)magic_p;
01193 if( BU_LIST_NON_EMPTY( &(pp->f_hd) ) ) return;
01194 FREE_FACE_G_PLANE(pp);
01195 }
01196 break;
01197 case NMG_FACE_G_SNURB_MAGIC:
01198
01199 {
01200 struct face_g_snurb *sp;
01201 sp = (struct face_g_snurb *)magic_p;
01202 if( BU_LIST_NON_EMPTY( &(sp->f_hd) ) ) return;
01203 bu_free( (char *)sp->u.knots, "nmg_kfg snurb u knots[]");
01204 bu_free( (char *)sp->v.knots, "nmg_kfg snurb v knots[]");
01205 bu_free( (char *)sp->ctl_points, "nmg_kfg snurb ctl_points[]");
01206 FREE_FACE_G_SNURB(sp);
01207 }
01208 break;
01209 default:
01210 rt_bomb("nmg_kfg() bad magic\n");
01211 }
01212 }
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226 int
01227 nmg_kfu(struct faceuse *fu1)
01228 {
01229 struct faceuse *fu2;
01230 struct face *f1;
01231 struct face *f2;
01232 struct shell *s;
01233 int ret;
01234
01235 NMG_CK_FACEUSE(fu1);
01236 fu2 = fu1->fumate_p;
01237 NMG_CK_FACEUSE(fu2);
01238 f1 = fu1->f_p;
01239 f2 = fu2->f_p;
01240 NMG_CK_FACE(f1);
01241 NMG_CK_FACE(f2);
01242 if( f1 != f2 )
01243 rt_bomb("nmg_kfu() faceuse mates do not share face!\n");
01244 s = fu1->s_p;
01245 NMG_CK_SHELL(s);
01246
01247
01248 while( BU_LIST_NON_EMPTY( &fu1->lu_hd ) ) {
01249 (void)nmg_klu( BU_LIST_FIRST( loopuse, &fu1->lu_hd ) );
01250 }
01251
01252
01253 if (f1->g.magic_p) {
01254
01255 BU_LIST_DEQUEUE( &f1->l );
01256 nmg_kfg( f1->g.magic_p );
01257 }
01258 FREE_FACE(f1);
01259 fu1->f_p = fu2->f_p = (struct face *)NULL;
01260
01261
01262 BU_LIST_DEQUEUE( &fu1->l );
01263 if( BU_LIST_IS_EMPTY( &s->fu_hd ) )
01264 rt_bomb("nmg_kfu() faceuse mate not in parent shell?\n");
01265 BU_LIST_DEQUEUE( &fu2->l );
01266
01267 FREE_FACEUSE(fu1);
01268 FREE_FACEUSE(fu2);
01269 ret = nmg_shell_is_empty(s);
01270 if (rt_g.NMG_debug & DEBUG_BASIC) {
01271 bu_log("nmg_kfu(fu1=x%x) fu2=x%x ret=%d\n", fu1, fu2, ret);
01272 }
01273 return ret;
01274 }
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290 int
01291 nmg_klu(struct loopuse *lu1)
01292 {
01293 struct loopuse *lu2;
01294 long magic1;
01295 int ret = 0;
01296
01297 NMG_CK_LOOPUSE(lu1);
01298 lu2 = lu1->lumate_p;
01299 NMG_CK_LOOPUSE(lu2);
01300
01301 if (lu1->l_p != lu2->l_p)
01302 rt_bomb("nmg_klu() loopmates do not share loop!\n");
01303
01304 if (*lu1->up.magic_p != *lu2->up.magic_p)
01305 rt_bomb("nmg_klu() loopuses do not have same type of parent!\n");
01306
01307
01308 magic1 = BU_LIST_FIRST_MAGIC( &lu1->down_hd );
01309 if( magic1 != BU_LIST_FIRST_MAGIC( &lu2->down_hd ) )
01310 rt_bomb("nmg_klu() loopuses do not have same type of child!\n");
01311
01312 if( magic1 == NMG_VERTEXUSE_MAGIC ) {
01313
01314
01315 (void)nmg_kvu( BU_LIST_FIRST(vertexuse, &lu1->down_hd) );
01316 (void)nmg_kvu( BU_LIST_FIRST(vertexuse, &lu2->down_hd) );
01317 } else if ( magic1 == NMG_EDGEUSE_MAGIC) {
01318
01319 while( BU_LIST_NON_EMPTY( &lu1->down_hd ) ) {
01320 (void)nmg_keu(BU_LIST_FIRST(edgeuse, &lu1->down_hd) );
01321 }
01322 } else if ( magic1 == BU_LIST_HEAD_MAGIC ) {
01323
01324 } else {
01325 bu_log("nmg_klu(x%x) magic=%s\n", lu1, bu_identify_magic(magic1) );
01326 rt_bomb("nmg_klu: unknown type for loopuse child\n");
01327 }
01328
01329
01330 if (*lu1->up.magic_p == NMG_SHELL_MAGIC) {
01331 BU_LIST_DEQUEUE( &lu1->l );
01332 BU_LIST_DEQUEUE( &lu2->l );
01333 ret = nmg_shell_is_empty( lu1->up.s_p );
01334 } else if (*lu1->up.magic_p == NMG_FACEUSE_MAGIC) {
01335 BU_LIST_DEQUEUE( &lu1->l );
01336 BU_LIST_DEQUEUE( &lu2->l );
01337 ret = BU_LIST_IS_EMPTY( &lu1->up.fu_p->lu_hd );
01338 } else {
01339 rt_bomb("nmg_klu() unknown parent for loopuse\n");
01340 }
01341
01342 NMG_CK_LOOP(lu1->l_p);
01343 if (lu1->l_p->lg_p) {
01344 NMG_CK_LOOP_G(lu1->l_p->lg_p);
01345 FREE_LOOP_G(lu1->l_p->lg_p);
01346 }
01347 FREE_LOOP(lu1->l_p);
01348 FREE_LOOPUSE(lu1);
01349 FREE_LOOPUSE(lu2);
01350 if (rt_g.NMG_debug & DEBUG_BASIC) {
01351 bu_log("nmg_klu(lu1=x%x) lu2=x%x ret=%d\n", lu1, lu2, ret);
01352 }
01353 return ret;
01354 }
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374 int
01375 nmg_keg(struct edgeuse *eu)
01376 {
01377 NMG_CK_EDGEUSE(eu);
01378
01379 if( !eu->g.magic_p ) return 0;
01380
01381 switch( *eu->g.magic_p ) {
01382 case NMG_EDGE_G_LSEG_MAGIC:
01383 {
01384 struct edge_g_lseg *lp;
01385 lp = eu->g.lseg_p;
01386 eu->g.magic_p = (long *)NULL;
01387 if( BU_LIST_NON_EMPTY( &lp->eu_hd2 ) ) return 0;
01388 FREE_EDGE_G_LSEG(lp);
01389 }
01390 break;
01391 case NMG_EDGE_G_CNURB_MAGIC:
01392 {
01393 struct edge_g_cnurb *eg;
01394 eg = eu->g.cnurb_p;
01395 eu->g.magic_p = (long *)NULL;
01396 if( BU_LIST_NON_EMPTY( &eg->eu_hd2 ) ) return 0;
01397 if( eg->order != 0 ) {
01398 bu_free( (char *)eg->k.knots, "nmg_keg cnurb knots[]");
01399 bu_free( (char *)eg->ctl_points, "nmg_keg cnurb ctl_points[]");
01400 }
01401 FREE_EDGE_G_CNURB(eg);
01402 }
01403 break;
01404 }
01405 return 1;
01406 }
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419 int
01420 nmg_keu(register struct edgeuse *eu1)
01421 {
01422 register struct edgeuse *eu2;
01423 struct edge *e;
01424 int ret = 0;
01425
01426 NMG_CK_EDGEUSE(eu1);
01427 e = eu1->e_p;
01428 NMG_CK_EDGE(e);
01429
01430 eu2 = eu1->eumate_p;
01431 NMG_CK_EDGEUSE(eu2);
01432 NMG_CK_EDGE(eu2->e_p);
01433
01434 if (e != eu2->e_p) {
01435 rt_bomb("nmg_keu() edgeuse pair does not share edge\n");
01436 }
01437
01438
01439 if (eu1->radial_p != eu2) {
01440 NMG_CK_EDGEUSE(eu1->radial_p);
01441 NMG_CK_EDGEUSE(eu2->radial_p);
01442
01443 eu1->radial_p->radial_p = eu2->radial_p;
01444 eu2->radial_p->radial_p = eu1->radial_p;
01445
01446 NMG_CK_EDGEUSE(eu1->radial_p);
01447 NMG_CK_EDGEUSE(eu2->radial_p);
01448
01449
01450
01451
01452 if (e->eu_p == eu1 || e->eu_p == eu2)
01453 e->eu_p = eu1->radial_p;
01454 NMG_CK_EDGEUSE( e->eu_p );
01455 } else {
01456
01457
01458
01459
01460 FREE_EDGE(e);
01461 e = (struct edge *)NULL;
01462 eu1->e_p = e;
01463 eu2->e_p = e;
01464 }
01465
01466
01467 if( eu1->g.magic_p )
01468 {
01469
01470 BU_LIST_DEQUEUE( &eu1->l2 );
01471
01472
01473 nmg_keg( eu1 );
01474 }
01475
01476 if( eu2->g.magic_p )
01477 {
01478
01479 BU_LIST_DEQUEUE( &eu2->l2 );
01480
01481
01482 nmg_keg( eu2 );
01483 }
01484
01485
01486 if (*eu1->up.magic_p == NMG_LOOPUSE_MAGIC) {
01487 struct loopuse *lu1, *lu2;
01488 lu1 = eu1->up.lu_p;
01489 lu2 = eu2->up.lu_p;
01490 NMG_CK_LOOPUSE(lu1);
01491 NMG_CK_LOOPUSE(lu2);
01492
01493 if( lu1 == lu2 ) rt_bomb("nmg_keu() edgeuses on same loopuse\n");
01494 if (lu1->lumate_p != lu2 || lu1 != lu2->lumate_p ) {
01495 bu_log("nmg_keu() lu1=x%x, mate=x%x\n", lu1, lu1->lumate_p);
01496 bu_log("nmg_keu() lu2=x%x, mate=x%x\n", lu2, lu2->lumate_p);
01497 rt_bomb("nmg_keu() edgeuse mates don't belong to loopuse mates\n");
01498 }
01499
01500
01501 BU_LIST_DEQUEUE( &eu1->l );
01502 BU_LIST_DEQUEUE( &eu2->l );
01503
01504
01505 if( BU_LIST_IS_EMPTY( &lu1->down_hd ) ) ret = 1;
01506 } else if (*eu1->up.magic_p == NMG_SHELL_MAGIC) {
01507 if (eu1->up.s_p != eu2->up.s_p) {
01508 rt_bomb("nmg_keu() edguses don't share parent shell\n");
01509 }
01510
01511
01512 BU_LIST_DEQUEUE( &eu1->l );
01513 BU_LIST_DEQUEUE( &eu2->l );
01514 ret = nmg_shell_is_empty( eu1->up.s_p );
01515 } else {
01516 rt_bomb("nmg_keu() bad up pointer\n");
01517 }
01518
01519
01520 if (eu1->vu_p) {
01521 (void)nmg_kvu(eu1->vu_p);
01522 }
01523 if (eu2->vu_p) {
01524 (void)nmg_kvu(eu2->vu_p);
01525 }
01526
01527 FREE_EDGEUSE(eu1);
01528 FREE_EDGEUSE(eu2);
01529
01530 if( e )
01531 {
01532 NMG_CK_EDGE( e );
01533 NMG_CK_EDGEUSE( e->eu_p );
01534 }
01535
01536 if (rt_g.NMG_debug & DEBUG_BASIC) {
01537 bu_log("nmg_keu(eu1=x%x) eu2=x%x ret=%d\n", eu1, eu2, ret);
01538 }
01539 return ret;
01540 }
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551 int
01552 nmg_ks(struct shell *s)
01553 {
01554 struct nmgregion *r;
01555
01556 NMG_CK_SHELL(s);
01557 r = s->r_p;
01558 NMG_CK_REGION(r);
01559
01560 while( BU_LIST_NON_EMPTY( &s->fu_hd ) )
01561 (void)nmg_kfu( BU_LIST_FIRST(faceuse, &s->fu_hd) );
01562 while( BU_LIST_NON_EMPTY( &s->lu_hd ) )
01563 (void)nmg_klu( BU_LIST_FIRST(loopuse, &s->lu_hd) );
01564 while( BU_LIST_NON_EMPTY( &s->eu_hd ) )
01565 (void)nmg_keu( BU_LIST_FIRST(edgeuse, &s->eu_hd) );
01566 if( s->vu_p )
01567 nmg_kvu( s->vu_p );
01568
01569 BU_LIST_DEQUEUE( &s->l );
01570
01571 if (s->sa_p) {
01572 FREE_SHELL_A(s->sa_p);
01573 }
01574
01575 FREE_SHELL(s);
01576 if (rt_g.NMG_debug & DEBUG_BASIC) {
01577 bu_log("nmg_ks(s=x%x)\n", s);
01578 }
01579 if( BU_LIST_IS_EMPTY( &r->s_hd ) ) return 1;
01580 return 0;
01581 }
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592 int
01593 nmg_kr(struct nmgregion *r)
01594 {
01595 struct model *m;
01596
01597 NMG_CK_REGION(r);
01598 m = r->m_p;
01599 NMG_CK_MODEL(m);
01600
01601 while( BU_LIST_NON_EMPTY( &r->s_hd ) )
01602 (void)nmg_ks( BU_LIST_FIRST( shell, &r->s_hd ) );
01603
01604 BU_LIST_DEQUEUE( &r->l );
01605
01606 if (r->ra_p) {
01607 FREE_REGION_A(r->ra_p);
01608 }
01609 FREE_REGION(r);
01610 if (rt_g.NMG_debug & DEBUG_BASIC) {
01611 bu_log("nmg_kr(r=x%x)\n", r);
01612 }
01613
01614 if( BU_LIST_IS_EMPTY( &m->r_hd ) ) {
01615 m->maxindex = 1;
01616 return 1;
01617 }
01618 return 0;
01619 }
01620
01621
01622
01623
01624
01625 void
01626 nmg_km(struct model *m)
01627 {
01628 NMG_CK_MODEL(m);
01629
01630 while( BU_LIST_NON_EMPTY( &m->r_hd ) )
01631 (void)nmg_kr( BU_LIST_FIRST( nmgregion, &m->r_hd ) );
01632
01633 FREE_MODEL(m);
01634 if (rt_g.NMG_debug & DEBUG_BASIC) {
01635 bu_log("nmg_km(m=x%x)\n", m);
01636 }
01637 }
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649 void
01650 nmg_vertex_gv(struct vertex *v, const fastf_t *pt)
01651 {
01652 struct vertex_g *vg;
01653 struct model *m;
01654
01655 NMG_CK_VERTEX(v);
01656
01657 if ( (vg = v->vg_p) ) {
01658 NMG_CK_VERTEX_G(v->vg_p);
01659 }
01660 else {
01661 m = nmg_find_model(
01662 &BU_LIST_NEXT(vertexuse, &v->vu_hd)->l.magic );
01663 GET_VERTEX_G(vg, m);
01664
01665 vg->magic = NMG_VERTEX_G_MAGIC;
01666 v->vg_p = vg;
01667 }
01668 VMOVE( vg->coord, pt );
01669
01670 if (rt_g.NMG_debug & DEBUG_BASIC) {
01671 bu_log("nmg_vertex_gv(v=x%x, pt=(%g %g %g))\n", v , V3ARGS( pt ));
01672 }
01673 }
01674
01675
01676
01677
01678
01679
01680
01681 void
01682 nmg_vertex_g(register struct vertex *v, fastf_t x, fastf_t y, fastf_t z)
01683 {
01684 point_t pt;
01685
01686 pt[0] = x;
01687 pt[1] = y;
01688 pt[2] = z;
01689
01690 if (rt_g.NMG_debug & DEBUG_BASIC) {
01691 bu_log("nmg_vertex_g(v=x%x, pt=(%g %g %g))\n", v , x , y , z );
01692 }
01693
01694 nmg_vertex_gv(v, pt);
01695 }
01696
01697
01698
01699
01700
01701 void
01702 nmg_vertexuse_nv(struct vertexuse *vu, const fastf_t *norm)
01703 {
01704 struct model *m;
01705
01706 NMG_CK_VERTEXUSE( vu );
01707
01708 if( !vu->a.magic_p ) {
01709 struct vertexuse_a_plane *vua;
01710 m = nmg_find_model( &vu->l.magic );
01711 GET_VERTEXUSE_A_PLANE( vua , m );
01712 vua->magic = NMG_VERTEXUSE_A_PLANE_MAGIC;
01713 vu->a.plane_p = vua;
01714 } else if( *vu->a.magic_p == NMG_VERTEXUSE_A_CNURB_MAGIC ) {
01715
01716 rt_bomb("nmg_vertexuse_nv() Illegal assignment of normal vector to edge_g_cnurb vertexuse\n");
01717 } else {
01718 NMG_CK_VERTEXUSE_A_PLANE( vu->a.plane_p );
01719 }
01720
01721 VMOVE( vu->a.plane_p->N , norm );
01722
01723 if (rt_g.NMG_debug & DEBUG_BASIC) {
01724 bu_log("nmg_vertexuse_nv(vu=x%x, norm=(%g %g %g))\n", vu , V3ARGS( norm ));
01725 }
01726 }
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740 void
01741 nmg_vertexuse_a_cnurb(struct vertexuse *vu, const fastf_t *uvw)
01742 {
01743 struct vertexuse_a_cnurb *vua;
01744 struct model *m;
01745
01746 NMG_CK_VERTEXUSE( vu );
01747
01748 if( vu->a.magic_p ) rt_bomb("nmg_vertexuse_a_cnurb() vu has attribute already\n");
01749 NMG_CK_EDGEUSE( vu->up.eu_p );
01750 if( vu->up.eu_p->g.magic_p) NMG_CK_EDGE_G_CNURB( vu->up.eu_p->g.cnurb_p );
01751
01752 m = nmg_find_model( &vu->l.magic );
01753 GET_VERTEXUSE_A_CNURB( vua , m );
01754 VMOVE( vua->param, uvw );
01755 vua->magic = NMG_VERTEXUSE_A_CNURB_MAGIC;
01756
01757 vu->a.cnurb_p = vua;
01758
01759 if (rt_g.NMG_debug & DEBUG_BASIC) {
01760 bu_log("nmg_vertexuse_a_cnurb(vu=x%x, param=(%g %g %g)) vua=x%x\n",
01761 vu , V3ARGS( uvw ), vua);
01762 }
01763 }
01764
01765
01766
01767
01768
01769
01770
01771
01772 void
01773 nmg_edge_g(struct edgeuse *eu)
01774 {
01775 struct model *m;
01776 struct edge_g_lseg *eg_p = (struct edge_g_lseg *)NULL;
01777 struct edge *e;
01778 struct edgeuse *eu2;
01779 pointp_t pt;
01780 int found_eg=0;
01781
01782 NMG_CK_EDGEUSE(eu);
01783 e = eu->e_p;
01784 NMG_CK_EDGE(e);
01785 NMG_CK_VERTEXUSE(eu->vu_p);
01786 NMG_CK_VERTEX(eu->vu_p->v_p);
01787 NMG_CK_VERTEX_G(eu->vu_p->v_p->vg_p);
01788
01789 NMG_CK_EDGEUSE(eu->eumate_p);
01790 NMG_CK_VERTEXUSE(eu->eumate_p->vu_p);
01791 NMG_CK_VERTEX(eu->eumate_p->vu_p->v_p);
01792 NMG_CK_VERTEX_G(eu->eumate_p->vu_p->v_p->vg_p);
01793
01794 if(eu->vu_p->v_p == eu->eumate_p->vu_p->v_p )
01795 rt_bomb("nmg_edge_g(): Warning - edge runs from+to same vertex, 0 len!\n");
01796
01797 if ( (eg_p = eu->g.lseg_p) ) {
01798 NMG_CK_EDGE_G_LSEG(eg_p);
01799 rt_bomb("nmg_edge_g() geometry already assigned\n");
01800 }
01801
01802
01803 eu2 = eu->eumate_p->radial_p;
01804 while( eu2 != eu ) {
01805 if( eu2->g.magic_p && *eu2->g.magic_p == NMG_EDGE_G_LSEG_MAGIC ) {
01806 eg_p = eu2->g.lseg_p;
01807 found_eg = 1;
01808 break;
01809 }
01810 eu2 = eu2->eumate_p->radial_p;
01811 }
01812
01813 if( !eg_p ) {
01814
01815 m = nmg_find_model(&eu->l.magic);
01816 GET_EDGE_G_LSEG(eg_p, m);
01817 BU_LIST_INIT( &eg_p->eu_hd2 );
01818 eg_p->l.magic = NMG_EDGE_G_LSEG_MAGIC;
01819
01820
01821 pt = eu->vu_p->v_p->vg_p->coord;
01822 VMOVE(eg_p->e_pt, pt);
01823
01824
01825 pt = eu->eumate_p->vu_p->v_p->vg_p->coord;
01826 VSUB2(eg_p->e_dir, eg_p->e_pt, pt);
01827
01828
01829
01830
01831 if (VNEAR_ZERO(eg_p->e_dir, SMALL_FASTF)) {
01832 pointp_t pt2 = eu->vu_p->v_p->vg_p->coord;
01833 VPRINT("nmg_edge_g(): e_dir too small", eg_p->e_dir);
01834 bu_log("nmg_edge_g(): (%g %g %g) -> (%g %g %g)",
01835 pt[X], pt[Y], pt[Z],
01836 pt2[X], pt2[Y], pt2[Z]);
01837
01838 VSET(eg_p->e_dir, 1.0, 0.0, 0.0);
01839 VPRINT("nmg_edge_g(): Forcing e_dir to", eg_p->e_dir);
01840 rt_bomb("nmg_edge_g(): 0 length edge\n");
01841 }
01842 }
01843
01844
01845 BU_LIST_DEQUEUE( &eu->l2 );
01846 BU_LIST_DEQUEUE( &eu->eumate_p->l2 );
01847
01848
01849 BU_LIST_INSERT( &eg_p->eu_hd2, &eu->l2 );
01850 BU_LIST_INSERT( &eg_p->eu_hd2, &eu->eumate_p->l2 );
01851 eu->g.lseg_p = eg_p;
01852 eu->eumate_p->g.lseg_p = eg_p;
01853
01854 if( !found_eg )
01855 {
01856
01857 eu2 = eu->eumate_p->radial_p;
01858 while( eu2 != eu )
01859 {
01860 eu2->g.lseg_p = eg_p;
01861 BU_LIST_INSERT( &eg_p->eu_hd2, &eu2->l2 );
01862 eu2->eumate_p->g.lseg_p = eg_p;
01863 BU_LIST_INSERT( &eg_p->eu_hd2, &eu2->eumate_p->l2 );
01864
01865 eu2 = eu2->eumate_p->radial_p;
01866 }
01867 }
01868
01869 if (rt_g.NMG_debug & DEBUG_BASIC) {
01870 bu_log("nmg_edge_g(eu=x%x) eg=x%x\n", eu, eg_p );
01871 }
01872 }
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884 void
01885 nmg_edge_g_cnurb(struct edgeuse *eu, int order, int n_knots, fastf_t *kv, int n_pts, int pt_type, fastf_t *points)
01886 {
01887 struct model *m;
01888 struct edge_g_cnurb *eg;
01889 struct edge *e;
01890 struct faceuse *fu;
01891
01892 NMG_CK_EDGEUSE(eu);
01893 e = eu->e_p;
01894 NMG_CK_EDGE(e);
01895 NMG_CK_VERTEXUSE(eu->vu_p);
01896 NMG_CK_VERTEX(eu->vu_p->v_p);
01897 NMG_CK_VERTEX_G(eu->vu_p->v_p->vg_p);
01898
01899 NMG_CK_EDGEUSE(eu->eumate_p);
01900 NMG_CK_VERTEXUSE(eu->eumate_p->vu_p);
01901 NMG_CK_VERTEX(eu->eumate_p->vu_p->v_p);
01902 NMG_CK_VERTEX_G(eu->eumate_p->vu_p->v_p->vg_p);
01903
01904 #if 0
01905 if(eu->vu_p->v_p == eu->eumate_p->vu_p->v_p )
01906 rt_bomb("nmg_edge_g_cnurb(): edge runs from+to same vertex, 0 len!\n");
01907 #endif
01908
01909 if (eu->g.cnurb_p) {
01910 rt_bomb("nmg_edge_g_cnurb() geometry already assigned\n");
01911 }
01912 fu = nmg_find_fu_of_eu(eu);
01913 NMG_CK_FACEUSE(fu);
01914 NMG_CK_FACE_G_SNURB( fu->f_p->g.snurb_p );
01915
01916
01917 m = nmg_find_model(&eu->l.magic);
01918 GET_EDGE_G_CNURB(eg, m);
01919 BU_LIST_INIT( &eg->eu_hd2 );
01920
01921 eg->order = order;
01922 if( n_knots > 0 && kv ) {
01923 eg->k.k_size = n_knots;
01924 eg->k.knots = kv;
01925 } else {
01926
01927 rt_nurb_kvknot( &eg->k, order, 0.0, 1.0, n_knots - (2 * order), (struct resource *)NULL );
01928 }
01929
01930 if( n_pts < 2 ) rt_bomb("nmg_edge_g_cnurb() n_pts < 2\n");
01931 eg->c_size = n_pts;
01932 eg->pt_type = pt_type;
01933 if( points ) {
01934 eg->ctl_points = points;
01935 } else {
01936 int ncoord = RT_NURB_EXTRACT_COORDS(pt_type);
01937
01938 eg->ctl_points = (fastf_t *)bu_calloc(
01939 ncoord * n_pts,
01940 sizeof(fastf_t),
01941 "cnurb ctl_points[]" );
01942
01943
01944
01945
01946
01947 NMG_CK_VERTEXUSE_A_CNURB( eu->vu_p->a.cnurb_p );
01948 NMG_CK_VERTEXUSE_A_CNURB( eu->eumate_p->vu_p->a.cnurb_p );
01949 switch( ncoord ) {
01950 case 4:
01951 eg->ctl_points[3] = 1;
01952 eg->ctl_points[ (n_pts-1)*ncoord + 3] = 1;
01953
01954 case 3:
01955 VMOVE( eg->ctl_points, eu->vu_p->a.cnurb_p->param );
01956 VMOVE( &eg->ctl_points[ (n_pts-1)*ncoord ],
01957 eu->eumate_p->vu_p->a.cnurb_p->param );
01958 break;
01959 case 2:
01960 V2MOVE( eg->ctl_points, eu->vu_p->a.cnurb_p->param );
01961 V2MOVE( &eg->ctl_points[ (n_pts-1)*ncoord ],
01962 eu->eumate_p->vu_p->a.cnurb_p->param );
01963 break;
01964 default:
01965 rt_bomb("nmg_edge_g_cnurb() bad ncoord?\n");
01966 }
01967 }
01968
01969
01970 BU_LIST_DEQUEUE( &eu->l2 );
01971 BU_LIST_DEQUEUE( &eu->eumate_p->l2 );
01972
01973
01974 BU_LIST_INSERT( &eg->eu_hd2, &eu->l2 );
01975 BU_LIST_INSERT( &eg->eu_hd2, &eu->eumate_p->l2 );
01976 eu->g.cnurb_p = eg;
01977 eu->eumate_p->g.cnurb_p = eg;
01978
01979 eg->l.magic = NMG_EDGE_G_CNURB_MAGIC;
01980
01981 if (rt_g.NMG_debug & DEBUG_BASIC) {
01982 bu_log("nmg_edge_g_cnurb(eu=x%x, order=%d, n_knots=%d, kv=x%x, n_pts=%d, pt_type=x%x, points=x%x) eg=x%x\n",
01983 eu, order, n_knots, eg->k.knots,
01984 n_pts, pt_type, eg->ctl_points, eg );
01985 }
01986 }
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007 void
02008 nmg_edge_g_cnurb_plinear(struct edgeuse *eu)
02009 {
02010 struct model *m;
02011 struct edge_g_cnurb *eg;
02012 struct edge *e;
02013 struct faceuse *fu;
02014
02015 NMG_CK_EDGEUSE(eu);
02016 e = eu->e_p;
02017 NMG_CK_EDGE(e);
02018 NMG_CK_VERTEXUSE(eu->vu_p);
02019 NMG_CK_VERTEX(eu->vu_p->v_p);
02020 NMG_CK_VERTEX_G(eu->vu_p->v_p->vg_p);
02021
02022 NMG_CK_EDGEUSE(eu->eumate_p);
02023 NMG_CK_VERTEXUSE(eu->eumate_p->vu_p);
02024 NMG_CK_VERTEX(eu->eumate_p->vu_p->v_p);
02025 NMG_CK_VERTEX_G(eu->eumate_p->vu_p->v_p->vg_p);
02026
02027 NMG_CK_VERTEXUSE_A_CNURB( eu->vu_p->a.cnurb_p );
02028 NMG_CK_VERTEXUSE_A_CNURB( eu->eumate_p->vu_p->a.cnurb_p );
02029
02030 #if 0
02031 if(eu->vu_p->v_p == eu->eumate_p->vu_p->v_p )
02032 rt_bomb("nmg_edge_g_cnurb_plinear(): edge runs from+to same vertex, 0 len!\n");
02033 #endif
02034
02035 if (eu->g.cnurb_p) {
02036 rt_bomb("nmg_edge_g_cnurb_plinear() geometry already assigned\n");
02037 }
02038 fu = nmg_find_fu_of_eu(eu);
02039 NMG_CK_FACEUSE(fu);
02040 NMG_CK_FACE_G_SNURB( fu->f_p->g.snurb_p );
02041
02042
02043 m = nmg_find_model(&eu->l.magic);
02044 GET_EDGE_G_CNURB(eg, m);
02045 BU_LIST_INIT( &eg->eu_hd2 );
02046
02047 eg->order = 0;
02048
02049
02050 BU_LIST_DEQUEUE( &eu->l2 );
02051 BU_LIST_DEQUEUE( &eu->eumate_p->l2 );
02052
02053
02054 BU_LIST_INSERT( &eg->eu_hd2, &eu->l2 );
02055 BU_LIST_INSERT( &eg->eu_hd2, &eu->eumate_p->l2 );
02056 eu->g.cnurb_p = eg;
02057 eu->eumate_p->g.cnurb_p = eg;
02058
02059 eg->l.magic = NMG_EDGE_G_CNURB_MAGIC;
02060
02061 if (rt_g.NMG_debug & DEBUG_BASIC) {
02062 bu_log("nmg_edge_g_cnurb_plinear(eu=x%x) order=0, eg=x%x\n",
02063 eu, eg );
02064 }
02065 }
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081 int
02082 nmg_use_edge_g(struct edgeuse *eu, long int *magic_p)
02083 {
02084 struct edge_g_lseg *old;
02085
02086 struct edge_g_lseg *eg = (struct edge_g_lseg *)magic_p;
02087 int ndead = 0;
02088
02089 if( !magic_p ) return 0;
02090
02091 NMG_CK_EDGEUSE(eu);
02092 NMG_CK_EDGE_G_LSEG(eg);
02093 if( eu == eu->eumate_p ) rt_bomb("nmg_use_edge_g() eu == eumate_p!\n");
02094
02095 old = eu->g.lseg_p;
02096
02097
02098 if( old && eg ) {
02099 #if 0
02100 vect_t dir_src;
02101 vect_t dir_dest;
02102 fastf_t deg;
02103 double cos_ang;
02104
02105 VMOVE( dir_src, old->e_dir );
02106 VUNITIZE( dir_src );
02107 VMOVE( dir_dest, eg->e_dir );
02108 VUNITIZE( dir_dest );
02109 cos_ang = fabs(VDOT( dir_src, dir_dest ));
02110 if( cos_ang > 1.0 )
02111 cos_ang = 1.0;
02112 deg = acos( cos_ang ) * bn_radtodeg;
02113 if( fabs(deg) > 2 ) {
02114 VPRINT( "dir_src ", dir_src );
02115 VPRINT( "dir_dest", dir_dest );
02116 bu_log("nmg_use_edge_g() NOTICE Angle between old=x%x & new=x%x lines was %g deg.\n",
02117 old, eg, deg );
02118 rt_bomb("nmg_use_edge_g() angle between old & new lines is excessive\n");
02119 }
02120 #endif
02121 }
02122
02123
02124 if( eu->g.lseg_p != eg && eu->g.lseg_p ) {
02125
02126 NMG_CK_EDGE_G_LSEG(eu->g.lseg_p);
02127
02128 BU_LIST_DEQUEUE( &eu->l2 );
02129 ndead += nmg_keg( eu );
02130 eu->g.magic_p = (long *)NULL;
02131 }
02132 if( eu->g.lseg_p != eg ) {
02133 BU_LIST_INSERT( &eg->eu_hd2, &(eu->l2) );
02134 eu->g.magic_p = magic_p;
02135 }
02136
02137
02138 if( eu->eumate_p->g.lseg_p != eg && eu->eumate_p->g.lseg_p ) {
02139 struct edgeuse *mate = eu->eumate_p;
02140
02141 NMG_CK_EDGEUSE(mate);
02142 NMG_CK_EDGE_G_LSEG(mate->g.lseg_p);
02143
02144 BU_LIST_DEQUEUE( &mate->l2 );
02145 ndead += nmg_keg( mate );
02146 mate->g.magic_p = (long *)NULL;
02147 }
02148
02149 if( eu->eumate_p->g.lseg_p != eg ) {
02150 BU_LIST_INSERT( &eg->eu_hd2, &(eu->eumate_p->l2) );
02151 eu->eumate_p->g.magic_p = magic_p;
02152 }
02153 if( eu->g.magic_p != eu->eumate_p->g.magic_p ) rt_bomb("nmg_use_edge_g() eu and mate not using same geometry?\n");
02154
02155 if (rt_g.NMG_debug & DEBUG_BASIC) {
02156 bu_log("nmg_use_edge_g(eu=x%x, magic_p=x%x) old_eg=x%x, ret=%d\n",
02157 eu, magic_p, old, ndead);
02158 }
02159 return ndead;
02160 }
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170 void
02171 nmg_loop_g(struct loop *l, const struct bn_tol *tol)
02172 {
02173 struct edgeuse *eu;
02174 struct vertex_g *vg;
02175 struct loop_g *lg;
02176 struct loopuse *lu;
02177 struct model *m;
02178 long magic1;
02179 FAST fastf_t thickening;
02180
02181 NMG_CK_LOOP(l);
02182 BN_CK_TOL(tol);
02183 lu = l->lu_p;
02184 NMG_CK_LOOPUSE(lu);
02185
02186 if ( (lg = l->lg_p) ) {
02187 NMG_CK_LOOP_G(lg);
02188 } else {
02189 m = nmg_find_model( lu->up.magic_p );
02190 GET_LOOP_G(l->lg_p, m);
02191 lg = l->lg_p;
02192 lg->magic = NMG_LOOP_G_MAGIC;
02193 }
02194 VSETALL( lg->max_pt, -INFINITY );
02195 VSETALL( lg->min_pt, INFINITY );
02196
02197 magic1 = BU_LIST_FIRST_MAGIC( &lu->down_hd );
02198 if (magic1 == NMG_EDGEUSE_MAGIC) {
02199 for( BU_LIST_FOR( eu, edgeuse, &lu->down_hd ) ) {
02200 vg = eu->vu_p->v_p->vg_p;
02201 NMG_CK_VERTEX_G(vg);
02202 VMINMAX(lg->min_pt, lg->max_pt, vg->coord);
02203 if( !eu->g.magic_p && eu->vu_p->v_p != eu->eumate_p->vu_p->v_p )
02204 nmg_edge_g(eu);
02205 }
02206 } else if (magic1 == NMG_VERTEXUSE_MAGIC) {
02207 struct vertexuse *vu;
02208 vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
02209 NMG_CK_VERTEXUSE(vu);
02210 NMG_CK_VERTEX(vu->v_p);
02211 vg = vu->v_p->vg_p;
02212 NMG_CK_VERTEX_G(vg);
02213 VMOVE(lg->min_pt, vg->coord);
02214 VMOVE(lg->max_pt, vg->coord);
02215 } else {
02216 bu_log("nmg_loop_g() loopuse down is %s (x%x)\n",
02217 bu_identify_magic(magic1), magic1 );
02218 rt_bomb("nmg_loop_g() loopuse has bad child\n");
02219 }
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229 thickening = 5 * tol->dist;
02230 lg->min_pt[X] -= thickening;
02231 lg->min_pt[Y] -= thickening;
02232 lg->min_pt[Z] -= thickening;
02233 lg->max_pt[X] += thickening;
02234 lg->max_pt[Y] += thickening;
02235 lg->max_pt[Z] += thickening;
02236
02237 if (rt_g.NMG_debug & DEBUG_BASIC) {
02238 bu_log("nmg_loop_g(l=x%x, tol=x%x)\n", l , tol);
02239 }
02240
02241 }
02242
02243
02244
02245
02246
02247
02248
02249
02250 void
02251 nmg_face_g(struct faceuse *fu, const fastf_t *p)
02252 {
02253 int i;
02254 struct face_g_plane *fg;
02255 struct face *f;
02256 struct model *m;
02257
02258 NMG_CK_FACEUSE(fu);
02259 f = fu->f_p;
02260 NMG_CK_FACE(f);
02261
02262 fu->orientation = OT_SAME;
02263 fu->fumate_p->orientation = OT_OPPOSITE;
02264
02265 fg = f->g.plane_p;
02266 if (fg) {
02267
02268 NMG_CK_FACE_G_PLANE(fg);
02269 } else {
02270 m = nmg_find_model( &fu->l.magic );
02271 GET_FACE_G_PLANE(f->g.plane_p, m);
02272 f->flip = 0;
02273 fg = f->g.plane_p;
02274 fg->magic = NMG_FACE_G_PLANE_MAGIC;
02275 BU_LIST_INIT(&fg->f_hd);
02276 BU_LIST_APPEND( &fg->f_hd, &f->l );
02277 }
02278
02279 if( f->flip ) {
02280 for (i=0 ; i < ELEMENTS_PER_PLANE ; i++)
02281 fg->N[i] = -p[i];
02282 } else {
02283 HMOVE( fg->N, p );
02284 }
02285
02286 if (rt_g.NMG_debug & DEBUG_BASIC) {
02287 bu_log("nmg_face_g(fu=x%x, p=(%g %g %g %g))\n", fu , V4ARGS( p ));
02288 }
02289 }
02290
02291
02292
02293
02294
02295
02296
02297 void
02298 nmg_face_new_g(struct faceuse *fu, const fastf_t *pl)
02299 {
02300 struct face *f;
02301 struct face *f_tmp;
02302 struct face_g_plane *fg;
02303 struct model *m;
02304 int use_count=0;
02305
02306 NMG_CK_FACEUSE( fu );
02307 f = fu->f_p;
02308 NMG_CK_FACE( f );
02309 fg = f->g.plane_p;
02310
02311
02312 if( !fg )
02313 {
02314 nmg_face_g( fu, pl );
02315 return;
02316 }
02317
02318
02319 for( BU_LIST_FOR( f_tmp, face, &fg->f_hd ) )
02320 use_count++;
02321
02322
02323 if( use_count < 2 )
02324 {
02325 nmg_face_g( fu, pl );
02326 return;
02327 }
02328
02329
02330
02331 fu->orientation = OT_SAME;
02332 fu->fumate_p->orientation = OT_OPPOSITE;
02333
02334
02335 BU_LIST_DEQUEUE( &f->l );
02336
02337
02338 m = nmg_find_model( &fu->l.magic );
02339 GET_FACE_G_PLANE(f->g.plane_p, m);
02340 f->flip = 0;
02341 fg = f->g.plane_p;
02342 fg->magic = NMG_FACE_G_PLANE_MAGIC;
02343 BU_LIST_INIT(&fg->f_hd);
02344 BU_LIST_APPEND( &fg->f_hd, &f->l );
02345
02346 HMOVE( fg->N, pl );
02347
02348 if (rt_g.NMG_debug & DEBUG_BASIC) {
02349 bu_log("nmg_face_new_g(fu=x%x, pl=(%g %g %g %g))\n", fu , V4ARGS( pl ));
02350 }
02351 }
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365 void
02366 nmg_face_g_snurb(struct faceuse *fu, int u_order, int v_order, int n_u_knots, int n_v_knots, fastf_t *ukv, fastf_t *vkv, int n_rows, int n_cols, int pt_type, fastf_t *mesh)
02367 {
02368 struct face_g_snurb *fg;
02369 struct face *f;
02370 struct model *m;
02371
02372 NMG_CK_FACEUSE(fu);
02373 f = fu->f_p;
02374 NMG_CK_FACE(f);
02375
02376 fu->orientation = OT_SAME;
02377 fu->fumate_p->orientation = OT_OPPOSITE;
02378
02379 fg = f->g.snurb_p;
02380 if (fg) {
02381
02382 rt_bomb("nmg_face_g_snurb() face already has geometry\n");
02383 }
02384
02385 m = nmg_find_model( &fu->l.magic );
02386 GET_FACE_G_SNURB(f->g.snurb_p, m);
02387 fg = f->g.snurb_p;
02388
02389 fg->order[0] = u_order;
02390 fg->order[1] = v_order;
02391 fg->u.magic = NMG_KNOT_VECTOR_MAGIC;
02392 fg->v.magic = NMG_KNOT_VECTOR_MAGIC;
02393 fg->u.k_size = n_u_knots;
02394 fg->v.k_size = n_v_knots;
02395
02396 if( ukv ) {
02397 fg->u.knots = ukv;
02398 } else {
02399 fg->u.knots = (fastf_t *)bu_calloc(
02400 n_u_knots, sizeof(fastf_t), "u.knots[]" );
02401 }
02402 if( vkv ) {
02403 fg->v.knots = vkv;
02404 } else {
02405 fg->v.knots = (fastf_t *)bu_calloc(
02406 n_v_knots, sizeof(fastf_t), "v.knots[]" );
02407 }
02408
02409 fg->s_size[0] = n_rows;
02410 fg->s_size[1] = n_cols;
02411 fg->pt_type = pt_type;
02412
02413 if( mesh ) {
02414 fg->ctl_points = mesh;
02415 } else {
02416 int nwords;
02417 nwords = n_rows * n_cols * RT_NURB_EXTRACT_COORDS(pt_type);
02418 fg->ctl_points = (fastf_t *)bu_calloc(
02419 nwords, sizeof(fastf_t), "snurb ctl_points[]" );
02420 }
02421
02422 f->flip = 0;
02423 BU_LIST_INIT(&fg->f_hd);
02424 BU_LIST_APPEND( &fg->f_hd, &f->l );
02425 fg->l.magic = NMG_FACE_G_SNURB_MAGIC;
02426
02427 if (rt_g.NMG_debug & DEBUG_BASIC) {
02428 bu_log("nmg_face_g_snurb(fu=x%x, u_order=%d, v_order=%d, n_u_knots=%d, n_v_knots=%d, ukv=x%x, vkv=x%x, n_rows=%d, n_cols=%d, pt_type=x%x, mesh=x%x) fg=x%x\n",
02429 fu, u_order, v_order, n_u_knots, n_v_knots,
02430 fg->u.knots, fg->v.knots,
02431 n_rows, n_cols, pt_type, fg->ctl_points, fg );
02432 }
02433 }
02434
02435
02436
02437
02438
02439
02440 void
02441 nmg_face_bb(struct face *f, const struct bn_tol *tol)
02442 {
02443 struct loopuse *lu;
02444 struct faceuse *fu;
02445
02446 BN_CK_TOL(tol);
02447 NMG_CK_FACE(f);
02448 fu = f->fu_p;
02449 NMG_CK_FACEUSE(fu);
02450
02451 f->max_pt[X] = f->max_pt[Y] = f->max_pt[Z] = -MAX_FASTF;
02452 f->min_pt[X] = f->min_pt[Y] = f->min_pt[Z] = MAX_FASTF;
02453
02454
02455
02456
02457 for( BU_LIST_FOR( lu, loopuse, &fu->lu_hd ) ) {
02458 nmg_loop_g(lu->l_p, tol);
02459
02460 if (lu->orientation != OT_BOOLPLACE) {
02461 VMIN(f->min_pt, lu->l_p->lg_p->min_pt);
02462 VMAX(f->max_pt, lu->l_p->lg_p->max_pt);
02463 }
02464 }
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475 if( *fu->f_p->g.magic_p == NMG_FACE_G_SNURB_MAGIC )
02476 {
02477 rt_nurb_s_bound( fu->f_p->g.snurb_p, fu->f_p->g.snurb_p->min_pt,
02478 fu->f_p->g.snurb_p->max_pt);
02479 VMIN(f->min_pt, fu->f_p->g.snurb_p->min_pt );
02480 VMAX(f->max_pt, fu->f_p->g.snurb_p->max_pt );
02481 }
02482
02483 if (rt_g.NMG_debug & DEBUG_BASIC) {
02484 bu_log("nmg_face_bb(f=x%x, tol=x%x)\n", f , tol);
02485 }
02486 }
02487
02488
02489
02490
02491
02492
02493 void
02494 nmg_shell_a(struct shell *s, const struct bn_tol *tol)
02495 {
02496 struct shell_a *sa;
02497 struct vertex_g *vg;
02498 struct faceuse *fu;
02499 struct loopuse *lu;
02500 struct edgeuse *eu;
02501 struct model *m;
02502
02503 NMG_CK_SHELL(s);
02504 BN_CK_TOL(tol);
02505
02506 if (s->sa_p) {
02507 NMG_CK_SHELL_A(s->sa_p);
02508 } else {
02509 m = nmg_find_model( &s->l.magic );
02510 GET_SHELL_A(s->sa_p, m);
02511 s->sa_p->magic = NMG_SHELL_A_MAGIC;
02512 }
02513 sa = s->sa_p;
02514
02515 VSETALL( sa->max_pt , -MAX_FASTF);
02516 VSETALL( sa->min_pt , MAX_FASTF);
02517
02518 for( BU_LIST_FOR( fu, faceuse, &s->fu_hd ) ) {
02519 struct face *f;
02520
02521 f = fu->f_p;
02522 NMG_CK_FACE(f);
02523 nmg_face_bb(f, tol);
02524
02525 VMIN(sa->min_pt, f->min_pt);
02526 VMAX(sa->max_pt, f->max_pt);
02527
02528
02529 if( BU_LIST_NOT_HEAD(fu, &fu->l) &&
02530 ( BU_LIST_NEXT(faceuse, &fu->l)->f_p == f ) ) {
02531 fu = BU_LIST_PNEXT(faceuse,fu);
02532 }
02533 }
02534 for( BU_LIST_FOR( lu, loopuse, &s->lu_hd ) ) {
02535 nmg_loop_g(lu->l_p, tol);
02536
02537 VMIN(sa->min_pt, lu->l_p->lg_p->min_pt);
02538 VMAX(sa->max_pt, lu->l_p->lg_p->max_pt);
02539 }
02540 for( BU_LIST_FOR( eu, edgeuse, &s->eu_hd ) ) {
02541 NMG_CK_EDGEUSE(eu);
02542 NMG_CK_EDGE(eu->e_p);
02543 vg = eu->vu_p->v_p->vg_p;
02544 NMG_CK_VERTEX_G(vg);
02545 VMINMAX(sa->min_pt, sa->max_pt, vg->coord);
02546 }
02547 if (s->vu_p) {
02548 NMG_CK_VERTEXUSE(s->vu_p);
02549 NMG_CK_VERTEX(s->vu_p->v_p);
02550 if( s->vu_p->v_p->vg_p )
02551 {
02552 NMG_CK_VERTEX_G(s->vu_p->v_p->vg_p);
02553 vg = s->vu_p->v_p->vg_p;
02554 VMINMAX(sa->min_pt, sa->max_pt, vg->coord);
02555 }
02556 }
02557
02558
02559 if( BU_LIST_IS_EMPTY( &s->fu_hd ) &&
02560 BU_LIST_IS_EMPTY( &s->lu_hd ) &&
02561 BU_LIST_IS_EMPTY( &s->eu_hd ) && !s->vu_p ) {
02562 bu_log("nmg_shell_a() at %d in %s. Shell has no children\n",
02563 __LINE__, __FILE__);
02564 rt_bomb("nmg_shell_a\n");
02565 }
02566
02567 if (rt_g.NMG_debug & DEBUG_BASIC) {
02568 bu_log("nmg_shell_a(s=x%x, tol=x%x)\n", s , tol);
02569 }
02570 }
02571
02572
02573
02574
02575
02576
02577 void
02578 nmg_region_a(struct nmgregion *r, const struct bn_tol *tol)
02579 {
02580 register struct shell *s;
02581 struct nmgregion_a *ra;
02582
02583 NMG_CK_REGION(r);
02584 BN_CK_TOL(tol);
02585 if( r->ra_p ) {
02586 ra = r->ra_p;
02587 NMG_CK_REGION_A(ra);
02588 } else {
02589 GET_REGION_A(ra, r->m_p);
02590 r->ra_p = ra;
02591 }
02592
02593 ra->magic = NMG_REGION_A_MAGIC;
02594
02595 VSETALL(ra->max_pt, -MAX_FASTF);
02596 VSETALL(ra->min_pt, MAX_FASTF);
02597
02598 for( BU_LIST_FOR( s, shell, &r->s_hd ) ) {
02599 nmg_shell_a(s, tol);
02600 NMG_CK_SHELL_A(s->sa_p);
02601 VMIN(ra->min_pt, s->sa_p->min_pt);
02602 VMAX(ra->max_pt, s->sa_p->max_pt);
02603 }
02604
02605 if (rt_g.NMG_debug & DEBUG_BASIC) {
02606 bu_log("nmg_region_a(r=x%x, tol=x%x)\n", r , tol);
02607 }
02608 }
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631 int
02632 nmg_demote_lu(struct loopuse *lu1)
02633 {
02634 struct edgeuse *eu1;
02635 struct shell *s;
02636 int ret_val;
02637
02638 NMG_CK_LOOPUSE(lu1);
02639
02640 if (rt_g.NMG_debug & DEBUG_CLASSIFY)
02641 bu_log("nmg_demote_lu(x%x)\n", lu1);
02642
02643 if (BU_LIST_FIRST_MAGIC(&lu1->down_hd) == NMG_VERTEXUSE_MAGIC) {
02644 rt_bomb("nmg_demote_lu() demoting loopuse of a single vertex\n");
02645 }
02646
02647 if (BU_LIST_FIRST_MAGIC(&lu1->down_hd) != NMG_EDGEUSE_MAGIC)
02648 rt_bomb("nmg_demote_lu: bad loopuse child\n");
02649
02650
02651 s = nmg_find_s_of_lu(lu1);
02652 NMG_CK_SHELL(s);
02653
02654
02655
02656 while ( BU_LIST_NON_EMPTY(&lu1->down_hd) ) {
02657
02658 eu1 = BU_LIST_FIRST(edgeuse, &lu1->down_hd);
02659 NMG_CK_EDGEUSE(eu1);
02660 NMG_CK_EDGE(eu1->e_p);
02661 NMG_CK_EDGEUSE(eu1->eumate_p);
02662 NMG_CK_EDGE(eu1->eumate_p->e_p);
02663
02664 BU_LIST_DEQUEUE(&eu1->eumate_p->l);
02665 BU_LIST_APPEND(&s->eu_hd, &eu1->eumate_p->l);
02666
02667 BU_LIST_DEQUEUE(&eu1->l);
02668 BU_LIST_APPEND(&s->eu_hd, &eu1->l);
02669
02670 eu1->up.s_p = eu1->eumate_p->up.s_p = s;
02671 }
02672
02673
02674 if (BU_LIST_NON_EMPTY(&lu1->lumate_p->down_hd))
02675 rt_bomb("nmg_demote_lu: loopuse mates don't have same # of edges\n");
02676
02677 ret_val = nmg_klu(lu1);
02678
02679 if (rt_g.NMG_debug & DEBUG_BASIC) {
02680 bu_log("nmg_demote_lu(lu=x%x) returns %d\n", lu1 , ret_val);
02681 }
02682
02683 return( ret_val );
02684 }
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695 int
02696 nmg_demote_eu(struct edgeuse *eu)
02697 {
02698 struct shell *s;
02699 struct vertex *v;
02700 int ret_val;
02701
02702 if (*eu->up.magic_p != NMG_SHELL_MAGIC)
02703 rt_bomb("nmg_demote_eu() up is not shell\n");
02704 s = eu->up.s_p;
02705 NMG_CK_SHELL(s);
02706
02707 NMG_CK_EDGEUSE(eu);
02708 v = eu->vu_p->v_p;
02709 if( !nmg_is_vertex_a_selfloop_in_shell(v, s) )
02710 (void)nmg_mlv(&s->l.magic, v, OT_SAME);
02711
02712 NMG_CK_EDGEUSE(eu->eumate_p);
02713 v = eu->eumate_p->vu_p->v_p;
02714 if( !nmg_is_vertex_a_selfloop_in_shell(v, s) )
02715 (void)nmg_mlv(&s->l.magic, v, OT_SAME);
02716
02717 (void)nmg_keu(eu);
02718
02719 ret_val = nmg_shell_is_empty(s);
02720
02721 if (rt_g.NMG_debug & DEBUG_BASIC) {
02722 bu_log("nmg_demote_eu(eu=x%x) returns %d\n", eu , ret_val);
02723 }
02724
02725 return( ret_val );
02726 }
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745 void
02746 nmg_movevu(struct vertexuse *vu, struct vertex *v)
02747 {
02748 struct vertex *oldv;
02749
02750 NMG_CK_VERTEXUSE(vu);
02751 NMG_CK_VERTEX(v);
02752
02753 oldv = vu->v_p;
02754 NMG_CK_VERTEX(oldv);
02755
02756 BU_LIST_DEQUEUE( &vu->l );
02757 if( BU_LIST_IS_EMPTY( &oldv->vu_hd ) ) {
02758
02759 if (oldv->vg_p) FREE_VERTEX_G(oldv->vg_p);
02760 FREE_VERTEX(oldv);
02761 }
02762 BU_LIST_APPEND( &v->vu_hd, &vu->l );
02763 vu->v_p = v;
02764
02765 if (rt_g.NMG_debug & DEBUG_BASIC) {
02766 bu_log("nmg_movevu(vu=x%x, v=x%x)\n", vu , v);
02767 }
02768 }
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782 void
02783 nmg_je(struct edgeuse *eudst, struct edgeuse *eusrc)
02784 {
02785 struct edgeuse *eudst_mate;
02786 struct edgeuse *eusrc_mate;
02787 struct edge *e;
02788
02789 NMG_CK_EDGEUSE(eudst);
02790 NMG_CK_EDGEUSE(eusrc);
02791 eudst_mate = eudst->eumate_p;
02792 eusrc_mate = eusrc->eumate_p;
02793 NMG_CK_EDGEUSE(eudst_mate);
02794 NMG_CK_EDGEUSE(eusrc_mate);
02795
02796
02797
02798
02799 if (eusrc == eudst || eusrc_mate == eudst) {
02800 bu_log("nmg_je() moving edgeuse to itself\n");
02801 return;
02802 }
02803
02804 if (eusrc->e_p == eudst->e_p &&
02805 (eusrc->radial_p == eudst || eudst->radial_p == eusrc)) {
02806 bu_log("nmg_je() edgeuses already share edge\n");
02807 return;
02808 }
02809
02810
02811 if ( ! ( (eudst_mate->vu_p->v_p == eusrc->vu_p->v_p &&
02812 eudst->vu_p->v_p == eusrc_mate->vu_p->v_p) ||
02813 (eudst->vu_p->v_p == eusrc->vu_p->v_p &&
02814 eudst_mate->vu_p->v_p == eusrc_mate->vu_p->v_p) ) ) {
02815
02816 bu_log( "eusrc (v=x%x) (%g %g %g)\n", eusrc->vu_p->v_p, V3ARGS( eusrc->vu_p->v_p->vg_p->coord ) );
02817 bu_log( "eusrc_mate (v=x%x) (%g %g %g)\n", eusrc_mate->vu_p->v_p, V3ARGS( eusrc_mate->vu_p->v_p->vg_p->coord ) );
02818 bu_log( "eudst (v=x%x) (%g %g %g)\n", eudst->vu_p->v_p, V3ARGS( eudst->vu_p->v_p->vg_p->coord ) );
02819 bu_log( "eudst_mate (v=x%x) (%g %g %g)\n", eudst_mate->vu_p->v_p, V3ARGS( eudst_mate->vu_p->v_p->vg_p->coord ) );
02820 rt_bomb("nmg_je() edgeuses do not share vertices, cannot share edge\n");
02821 }
02822
02823 e = eusrc->e_p;
02824 eusrc_mate->e_p = eusrc->e_p = eudst->e_p;
02825
02826
02827
02828
02829
02830 if (eusrc->radial_p != eusrc_mate) {
02831
02832 if (e->eu_p == eusrc || e->eu_p == eusrc_mate)
02833 e->eu_p = eusrc->radial_p;
02834
02835
02836 eusrc->radial_p->radial_p = eusrc_mate->radial_p;
02837 eusrc_mate->radial_p->radial_p = eusrc->radial_p;
02838 } else {
02839
02840 FREE_EDGE(e);
02841 }
02842
02843 eusrc->radial_p = eudst;
02844 eusrc_mate->radial_p = eudst->radial_p;
02845
02846 eudst->radial_p->radial_p = eusrc_mate;
02847 eudst->radial_p = eusrc;
02848
02849 if (rt_g.NMG_debug & DEBUG_BASIC) {
02850 bu_log("nmg_je(eudst=x%x, eusrc=x%x)\n", eudst , eusrc);
02851 }
02852 }
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869 void
02870 nmg_unglueedge(struct edgeuse *eu)
02871 {
02872 struct edge *old_e;
02873 struct edge *new_e;
02874 struct model *m;
02875
02876 NMG_CK_EDGEUSE(eu);
02877 old_e = eu->e_p;
02878 NMG_CK_EDGE(old_e);
02879
02880
02881 if (eu->radial_p == eu->eumate_p)
02882 {
02883 if (rt_g.NMG_debug & DEBUG_BASIC) {
02884 bu_log("nmg_unglueedge(eu=x%x) (nothing unglued)\n", eu);
02885 }
02886 return;
02887 }
02888
02889 m = nmg_find_model( &eu->l.magic );
02890 GET_EDGE(new_e, m);
02891
02892 new_e->magic = NMG_EDGE_MAGIC;
02893 new_e->eu_p = eu;
02894
02895
02896 if (old_e->eu_p == eu || old_e->eu_p == eu->eumate_p ) {
02897 old_e->eu_p = old_e->eu_p->radial_p;
02898 }
02899
02900
02901 eu->radial_p->radial_p = eu->eumate_p->radial_p;
02902 eu->eumate_p->radial_p->radial_p = eu->radial_p;
02903 eu->eumate_p->radial_p = eu;
02904 eu->radial_p = eu->eumate_p;
02905
02906
02907 eu->eumate_p->e_p = eu->e_p = new_e;
02908
02909 if (rt_g.NMG_debug & DEBUG_BASIC) {
02910 bu_log("nmg_unglueedge(eu=x%x)\n", eu);
02911 }
02912 }
02913
02914
02915
02916
02917
02918
02919
02920
02921 void
02922 nmg_jv(register struct vertex *v1, register struct vertex *v2)
02923 {
02924 register struct vertexuse *vu;
02925
02926 NMG_CK_VERTEX(v1);
02927 NMG_CK_VERTEX(v2);
02928
02929 if (v1 == v2) return;
02930
02931
02932
02933
02934
02935
02936 vu = BU_LIST_FIRST(vertexuse, &v2->vu_hd );
02937 while( BU_LIST_NOT_HEAD( vu, &v2->vu_hd ) ) {
02938 register struct vertexuse *vunext;
02939
02940 NMG_CK_VERTEXUSE(vu);
02941 vunext = BU_LIST_PNEXT(vertexuse, vu);
02942 BU_LIST_DEQUEUE( &vu->l );
02943 BU_LIST_INSERT( &v1->vu_hd, &vu->l );
02944 vu->v_p = v1;
02945 vu = vunext;
02946 }
02947
02948
02949 if (v2->vg_p) {
02950 if( !v1->vg_p ) {
02951 v1->vg_p = v2->vg_p;
02952 } else {
02953 FREE_VERTEX_G(v2->vg_p);
02954 }
02955 }
02956 FREE_VERTEX(v2);
02957
02958 if (rt_g.NMG_debug & DEBUG_BASIC) {
02959 bu_log("nmg_jv(v1=x%x, v2=x%x)\n", v1 , v2);
02960 }
02961 }
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972 void
02973 nmg_jfg(struct face *f1, struct face *f2)
02974 {
02975 struct face_g_plane *fg1;
02976 struct face_g_plane *fg2;
02977 struct face *f;
02978
02979 NMG_CK_FACE(f1);
02980 NMG_CK_FACE(f2);
02981 fg1 = f1->g.plane_p;
02982 fg2 = f2->g.plane_p;
02983 if( fg2 && !fg1 ) {
02984
02985 NMG_CK_FACE_G_PLANE(fg1);
02986 f1->g.plane_p = fg2;
02987 f1->flip = f2->flip;
02988 BU_LIST_INSERT( &fg2->f_hd, &f1->l );
02989
02990 if (rt_g.NMG_debug & DEBUG_BASIC) {
02991 bu_log("nmg_jfg(f1=x%x, f2=x%x)\n", f1 , f2);
02992 }
02993 return;
02994 }
02995 if( fg1 && !fg2 ) {
02996
02997 NMG_CK_FACE_G_PLANE(fg1);
02998 f2->g.plane_p = fg1;
02999 f2->flip = f1->flip;
03000 BU_LIST_INSERT( &fg1->f_hd, &f2->l );
03001
03002 if (rt_g.NMG_debug & DEBUG_BASIC) {
03003 bu_log("nmg_jfg(f1=x%x, f2=x%x)\n", f1 , f2);
03004 }
03005 return;
03006 }
03007
03008 NMG_CK_FACE_G_PLANE(fg1);
03009 NMG_CK_FACE_G_PLANE(fg2);
03010
03011 if( fg1 == fg2 )
03012 {
03013 if (rt_g.NMG_debug & DEBUG_BASIC) {
03014 bu_log("nmg_jfg(f1=x%x, f2=x%x)\n", f1 , f2);
03015 }
03016 return;
03017 }
03018
03019
03020 while( BU_LIST_NON_EMPTY( &fg2->f_hd ) ) {
03021 f = BU_LIST_FIRST( face, &fg2->f_hd );
03022 BU_LIST_DEQUEUE( &f->l );
03023 NMG_CK_FACE(f);
03024 f->g.plane_p = fg1;
03025
03026 BU_LIST_INSERT( &fg1->f_hd, &f->l );
03027 }
03028
03029
03030 FREE_FACE_G_PLANE(fg2);
03031
03032 if (rt_g.NMG_debug & DEBUG_BASIC) {
03033 bu_log("nmg_jfg(f1=x%x, f2=x%x)\n", f1 , f2);
03034 }
03035 }
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051 void
03052 nmg_jeg(struct edge_g_lseg *dest_eg, struct edge_g_lseg *src_eg)
03053 {
03054 register struct edgeuse *eu;
03055
03056 NMG_CK_EDGE_G_LSEG(src_eg);
03057 NMG_CK_EDGE_G_LSEG(dest_eg);
03058 if (rt_g.NMG_debug & DEBUG_BASIC) {
03059 bu_log("nmg_jeg( src_eg=x%x, dest_eg=x%x )\n",
03060 src_eg, dest_eg );
03061 }
03062
03063 #if 0
03064
03065 VMOVE( dir_src, src_eg->e_dir );
03066 VUNITIZE( dir_src );
03067 VMOVE( dir_dest, dest_eg->e_dir );
03068 VUNITIZE( dir_dest );
03069 cos_ang = fabs(VDOT( dir_src, dir_dest ));
03070 if( cos_ang > 1.0 )
03071 cos_ang = 1.0;
03072 deg = acos( cos_ang ) * bn_radtodeg;
03073 if( fabs(deg) > 2 ) {
03074 VPRINT( "dir_src ", dir_src );
03075 VPRINT( "dir_dest", dir_dest );
03076 bu_log("Angle between lines is %g degrees\n", deg );
03077
03078 }
03079 #endif
03080 while( BU_LIST_NON_EMPTY( &src_eg->eu_hd2 ) ) {
03081 struct bu_list *midway;
03082
03083 NMG_CK_EDGE_G_LSEG(src_eg);
03084
03085
03086 midway = BU_LIST_FIRST(bu_list, &src_eg->eu_hd2 );
03087 NMG_CKMAG(midway, NMG_EDGEUSE2_MAGIC, "edgeuse2 [l2]");
03088 eu = BU_LIST_MAIN_PTR( edgeuse, midway, l2 );
03089 NMG_CK_EDGEUSE(eu);
03090
03091 if( eu->g.lseg_p != src_eg ) {
03092 bu_log("nmg_jeg() eu=x%x, eu->g=x%x != src_eg=x%x?? dest_eg=x%x\n",
03093 eu, eu->g.lseg_p, src_eg, dest_eg );
03094 rt_bomb("nmg_jeg() edge geometry fumble\n");
03095 }
03096
03097
03098 if( nmg_use_edge_g( eu, &dest_eg->l.magic ) )
03099 break;
03100 }
03101 }
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111