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 #ifndef lint
00043 static const char RCSell[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/g_ell.c,v 14.13 2006/09/16 02:04:24 lbutler Exp $ (BRL)";
00044 #endif
00045
00046 #include "common.h"
00047
00048 #include <stddef.h>
00049 #include <stdio.h>
00050 #ifdef HAVE_STRING_H
00051 # include <string.h>
00052 #else
00053 # include <strings.h>
00054 #endif
00055 #include <math.h>
00056
00057 #include "machine.h"
00058 #include "vmath.h"
00059 #include "db.h"
00060 #include "nmg.h"
00061 #include "raytrace.h"
00062 #include "nurb.h"
00063 #include "rtgeom.h"
00064 #include "./debug.h"
00065
00066 BU_EXTERN(int rt_sph_prep, (struct soltab *stp, struct rt_db_internal *ip,
00067 struct rt_i *rtip));
00068
00069 const struct bu_structparse rt_ell_parse[] = {
00070 { "%f", 3, "V", bu_offsetof(struct rt_ell_internal, v[X]), BU_STRUCTPARSE_FUNC_NULL },
00071 { "%f", 3, "A", bu_offsetof(struct rt_ell_internal, a[X]), BU_STRUCTPARSE_FUNC_NULL },
00072 { "%f", 3, "B", bu_offsetof(struct rt_ell_internal, b[X]), BU_STRUCTPARSE_FUNC_NULL },
00073 { "%f", 3, "C", bu_offsetof(struct rt_ell_internal, c[X]), BU_STRUCTPARSE_FUNC_NULL },
00074 { {'\0','\0','\0','\0'}, 0, (char *)NULL, 0, BU_STRUCTPARSE_FUNC_NULL }
00075 };
00076
00077 static void nmg_sphere_face_snurb(struct faceuse *fu, const matp_t m);
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
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 struct ell_specific {
00173 vect_t ell_V;
00174 vect_t ell_Au;
00175 vect_t ell_Bu;
00176 vect_t ell_Cu;
00177 vect_t ell_invsq;
00178 mat_t ell_SoR;
00179 mat_t ell_invRSSR;
00180 };
00181 #define ELL_NULL ((struct ell_specific *)0)
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 int
00199 rt_ell_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
00200 {
00201 register struct ell_specific *ell;
00202 struct rt_ell_internal *eip;
00203 LOCAL fastf_t magsq_a, magsq_b, magsq_c;
00204 LOCAL mat_t R;
00205 LOCAL mat_t Rinv;
00206 LOCAL mat_t SS;
00207 LOCAL mat_t mtemp;
00208 LOCAL vect_t Au, Bu, Cu;
00209 LOCAL vect_t w1, w2, P;
00210 LOCAL fastf_t f;
00211
00212 eip = (struct rt_ell_internal *)ip->idb_ptr;
00213 RT_ELL_CK_MAGIC(eip);
00214
00215
00216
00217
00218
00219
00220 if( rt_sph_prep( stp, ip, rtip ) == 0 ) {
00221 return(0);
00222 }
00223
00224
00225 magsq_a = MAGSQ( eip->a );
00226 magsq_b = MAGSQ( eip->b );
00227 magsq_c = MAGSQ( eip->c );
00228
00229 if( magsq_a < rtip->rti_tol.dist || magsq_b < rtip->rti_tol.dist || magsq_c < rtip->rti_tol.dist ) {
00230 bu_log("sph(%s): zero length A(%g), B(%g), or C(%g) vector\n",
00231 stp->st_name, magsq_a, magsq_b, magsq_c );
00232 return(1);
00233 }
00234
00235
00236 f = 1.0/sqrt(magsq_a);
00237 VSCALE( Au, eip->a, f );
00238 f = 1.0/sqrt(magsq_b);
00239 VSCALE( Bu, eip->b, f );
00240 f = 1.0/sqrt(magsq_c);
00241 VSCALE( Cu, eip->c, f );
00242
00243
00244 f = VDOT( Au, Bu );
00245 if( ! NEAR_ZERO(f, rtip->rti_tol.dist) ) {
00246 bu_log("ell(%s): A not perpendicular to B, f=%f\n",stp->st_name, f);
00247 return(1);
00248 }
00249 f = VDOT( Bu, Cu );
00250 if( ! NEAR_ZERO(f, rtip->rti_tol.dist) ) {
00251 bu_log("ell(%s): B not perpendicular to C, f=%f\n",stp->st_name, f);
00252 return(1);
00253 }
00254 f = VDOT( Au, Cu );
00255 if( ! NEAR_ZERO(f, rtip->rti_tol.dist) ) {
00256 bu_log("ell(%s): A not perpendicular to C, f=%f\n",stp->st_name, f);
00257 return(1);
00258 }
00259
00260
00261 BU_GETSTRUCT( ell, ell_specific );
00262 stp->st_specific = (genptr_t)ell;
00263
00264 VMOVE( ell->ell_V, eip->v );
00265
00266 VSET( ell->ell_invsq, 1.0/magsq_a, 1.0/magsq_b, 1.0/magsq_c );
00267 VMOVE( ell->ell_Au, Au );
00268 VMOVE( ell->ell_Bu, Bu );
00269 VMOVE( ell->ell_Cu, Cu );
00270
00271 MAT_IDN( ell->ell_SoR );
00272 MAT_IDN( R );
00273
00274
00275 VMOVE( &R[0], Au );
00276 VMOVE( &R[4], Bu );
00277 VMOVE( &R[8], Cu );
00278 bn_mat_trn( Rinv, R );
00279
00280
00281 MAT_IDN( SS );
00282 SS[ 0] = ell->ell_invsq[0];
00283 SS[ 5] = ell->ell_invsq[1];
00284 SS[10] = ell->ell_invsq[2];
00285
00286
00287 bn_mat_mul( mtemp, SS, R );
00288 bn_mat_mul( ell->ell_invRSSR, Rinv, mtemp );
00289
00290
00291 VSCALE( &ell->ell_SoR[0], eip->a, ell->ell_invsq[0] );
00292 VSCALE( &ell->ell_SoR[4], eip->b, ell->ell_invsq[1] );
00293 VSCALE( &ell->ell_SoR[8], eip->c, ell->ell_invsq[2] );
00294
00295
00296 VMOVE( stp->st_center, eip->v );
00297 f = magsq_a;
00298 if( magsq_b > f )
00299 f = magsq_b;
00300 if( magsq_c > f )
00301 f = magsq_c;
00302 stp->st_aradius = stp->st_bradius = sqrt(f);
00303
00304
00305 VSET( w1, magsq_a, magsq_b, magsq_c );
00306
00307
00308 VSET( P, 1.0, 0, 0 );
00309 MAT3X3VEC( w2, R, P );
00310 VELMUL( w2, w2, w2 );
00311 f = VDOT( w1, w2 );
00312 f = sqrt(f);
00313 stp->st_min[X] = ell->ell_V[X] - f;
00314 stp->st_max[X] = ell->ell_V[X] + f;
00315
00316
00317 VSET( P, 0, 1.0, 0 );
00318 MAT3X3VEC( w2, R, P );
00319 VELMUL( w2, w2, w2 );
00320 f = VDOT( w1, w2 );
00321 f = sqrt(f);
00322 stp->st_min[Y] = ell->ell_V[Y] - f;
00323 stp->st_max[Y] = ell->ell_V[Y] + f;
00324
00325
00326 VSET( P, 0, 0, 1.0 );
00327 MAT3X3VEC( w2, R, P );
00328 VELMUL( w2, w2, w2 );
00329 f = VDOT( w1, w2 );
00330 f = sqrt(f);
00331 stp->st_min[Z] = ell->ell_V[Z] - f;
00332 stp->st_max[Z] = ell->ell_V[Z] + f;
00333
00334 return(0);
00335 }
00336
00337
00338
00339
00340 void
00341 rt_ell_print(register const struct soltab *stp)
00342 {
00343 register struct ell_specific *ell =
00344 (struct ell_specific *)stp->st_specific;
00345
00346 VPRINT("V", ell->ell_V);
00347 bn_mat_print("S o R", ell->ell_SoR );
00348 bn_mat_print("invRSSR", ell->ell_invRSSR );
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 int
00363 rt_ell_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
00364 {
00365 register struct ell_specific *ell =
00366 (struct ell_specific *)stp->st_specific;
00367 register struct seg *segp;
00368 LOCAL vect_t dprime;
00369 LOCAL vect_t pprime;
00370 LOCAL vect_t xlated;
00371 LOCAL fastf_t dp, dd;
00372 LOCAL fastf_t k1, k2;
00373 FAST fastf_t root;
00374
00375
00376 MAT4X3VEC( dprime, ell->ell_SoR, rp->r_dir );
00377 VSUB2( xlated, rp->r_pt, ell->ell_V );
00378 MAT4X3VEC( pprime, ell->ell_SoR, xlated );
00379
00380 dp = VDOT( dprime, pprime );
00381 dd = VDOT( dprime, dprime );
00382
00383 if( (root = dp*dp - dd * (VDOT(pprime,pprime)-1.0)) < 0 )
00384 return(0);
00385 root = sqrt(root);
00386
00387 RT_GET_SEG(segp, ap->a_resource);
00388 segp->seg_stp = stp;
00389 if( (k1=(-dp+root)/dd) <= (k2=(-dp-root)/dd) ) {
00390
00391 segp->seg_in.hit_dist = k1;
00392 segp->seg_out.hit_dist = k2;
00393 } else {
00394
00395 segp->seg_in.hit_dist = k2;
00396 segp->seg_out.hit_dist = k1;
00397 }
00398 BU_LIST_INSERT( &(seghead->l), &(segp->l) );
00399 return(2);
00400 }
00401
00402 #define RT_ELL_SEG_MISS(SEG) (SEG).seg_stp=RT_SOLTAB_NULL
00403
00404
00405
00406
00407
00408
00409 void
00410 rt_ell_vshot(struct soltab **stp, struct xray **rp, struct seg *segp, int n, struct application *ap)
00411
00412
00413
00414
00415
00416 {
00417 register int i;
00418 register struct ell_specific *ell;
00419 LOCAL vect_t dprime;
00420 LOCAL vect_t pprime;
00421 LOCAL vect_t xlated;
00422 LOCAL fastf_t dp, dd;
00423 LOCAL fastf_t k1, k2;
00424 FAST fastf_t root;
00425
00426
00427 # include "noalias.h"
00428 for(i = 0; i < n; i++){
00429 #if !CRAY
00430 if (stp[i] == 0) continue;
00431 #endif
00432 ell = (struct ell_specific *)stp[i]->st_specific;
00433
00434 MAT4X3VEC( dprime, ell->ell_SoR, rp[i]->r_dir );
00435 VSUB2( xlated, rp[i]->r_pt, ell->ell_V );
00436 MAT4X3VEC( pprime, ell->ell_SoR, xlated );
00437
00438 dp = VDOT( dprime, pprime );
00439 dd = VDOT( dprime, dprime );
00440
00441 if( (root = dp*dp - dd * (VDOT(pprime,pprime)-1.0)) < 0 ) {
00442 RT_ELL_SEG_MISS(segp[i]);
00443 }
00444 else {
00445 root = sqrt(root);
00446
00447 segp[i].seg_stp = stp[i];
00448
00449 if( (k1=(-dp+root)/dd) <= (k2=(-dp-root)/dd) ) {
00450
00451 segp[i].seg_in.hit_dist = k1;
00452 segp[i].seg_out.hit_dist = k2;
00453 } else {
00454
00455 segp[i].seg_in.hit_dist = k2;
00456 segp[i].seg_out.hit_dist = k1;
00457 }
00458 }
00459 }
00460 }
00461
00462
00463
00464
00465
00466
00467 void
00468 rt_ell_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp)
00469 {
00470 register struct ell_specific *ell =
00471 (struct ell_specific *)stp->st_specific;
00472 LOCAL vect_t xlated;
00473 LOCAL fastf_t scale;
00474
00475 VJOIN1( hitp->hit_point, rp->r_pt, hitp->hit_dist, rp->r_dir );
00476 VSUB2( xlated, hitp->hit_point, ell->ell_V );
00477 MAT4X3VEC( hitp->hit_normal, ell->ell_invRSSR, xlated );
00478 scale = 1.0 / MAGNITUDE( hitp->hit_normal );
00479 VSCALE( hitp->hit_normal, hitp->hit_normal, scale );
00480
00481
00482 hitp->hit_vpriv[X] = scale;
00483 }
00484
00485
00486
00487
00488
00489
00490 void
00491 rt_ell_curve(register struct curvature *cvp, register struct hit *hitp, struct soltab *stp)
00492 {
00493 register struct ell_specific *ell =
00494 (struct ell_specific *)stp->st_specific;
00495 vect_t u, v;
00496 vect_t vec1, vec2;
00497 vect_t tmp;
00498 fastf_t a, b, c, scale;
00499
00500
00501
00502
00503
00504 bn_vec_ortho( u, hitp->hit_normal );
00505 VCROSS( v, hitp->hit_normal, u );
00506
00507
00508 scale = - hitp->hit_vpriv[X];
00509
00510
00511 MAT4X3VEC( tmp, ell->ell_invRSSR, u );
00512 a = VDOT(u, tmp) * scale;
00513 b = VDOT(v, tmp) * scale;
00514 MAT4X3VEC( tmp, ell->ell_invRSSR, v );
00515 c = VDOT(v, tmp) * scale;
00516
00517 bn_eigen2x2( &cvp->crv_c1, &cvp->crv_c2, vec1, vec2, a, b, c );
00518 VCOMB2( cvp->crv_pdir, vec1[X], u, vec1[Y], v );
00519 VUNITIZE( cvp->crv_pdir );
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 void
00531 rt_ell_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
00532 {
00533 register struct ell_specific *ell =
00534 (struct ell_specific *)stp->st_specific;
00535 LOCAL vect_t work;
00536 LOCAL vect_t pprime;
00537 LOCAL fastf_t r;
00538
00539
00540
00541
00542
00543 VSUB2( work, hitp->hit_point, ell->ell_V );
00544 MAT4X3VEC( pprime, ell->ell_SoR, work );
00545
00546
00547
00548 uvp->uv_u = bn_atan2( pprime[Y], pprime[X] ) * bn_inv2pi;
00549 if( uvp->uv_u < 0 )
00550 uvp->uv_u += 1.0;
00551
00552
00553
00554
00555 uvp->uv_v = bn_atan2( pprime[Z],
00556 sqrt( pprime[X] * pprime[X] + pprime[Y] * pprime[Y]) ) *
00557 bn_invpi + 0.5;
00558
00559
00560 r = ap->a_rbeam + ap->a_diverge * hitp->hit_dist;
00561 uvp->uv_du = uvp->uv_dv =
00562 bn_inv2pi * r / stp->st_aradius;
00563 }
00564
00565
00566
00567
00568 void
00569 rt_ell_free(register struct soltab *stp)
00570 {
00571 register struct ell_specific *ell =
00572 (struct ell_specific *)stp->st_specific;
00573
00574 bu_free( (char *)ell, "ell_specific" );
00575 }
00576
00577 int
00578 rt_ell_class(void)
00579 {
00580 return(0);
00581 }
00582
00583
00584
00585
00586
00587
00588 #define ELLOUT(n) ov+(n-1)*3
00589 void
00590 rt_ell_16pts(register fastf_t *ov,
00591 register fastf_t *V,
00592 fastf_t *A,
00593 fastf_t *B)
00594 {
00595 static fastf_t c, d, e, f,g,h;
00596
00597 e = h = .92388;
00598 c = d = .707107;
00599 g = f = .382683;
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 VADD2( ELLOUT(1), V, A );
00610 VJOIN2( ELLOUT(2), V, e, A, f, B );
00611 VJOIN2( ELLOUT(3), V, c, A, d, B );
00612 VJOIN2( ELLOUT(4), V, g, A, h, B );
00613 VADD2( ELLOUT(5), V, B );
00614 VJOIN2( ELLOUT(6), V, -g, A, h, B );
00615 VJOIN2( ELLOUT(7), V, -c, A, d, B );
00616 VJOIN2( ELLOUT(8), V, -e, A, f, B );
00617 VSUB2( ELLOUT(9), V, A );
00618 VJOIN2( ELLOUT(10), V, -e, A, -f, B );
00619 VJOIN2( ELLOUT(11), V, -c, A, -d, B );
00620 VJOIN2( ELLOUT(12), V, -g, A, -h, B );
00621 VSUB2( ELLOUT(13), V, B );
00622 VJOIN2( ELLOUT(14), V, g, A, -h, B );
00623 VJOIN2( ELLOUT(15), V, c, A, -d, B );
00624 VJOIN2( ELLOUT(16), V, e, A, -f, B );
00625 }
00626
00627
00628
00629
00630 int
00631 rt_ell_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
00632 {
00633 register int i;
00634 struct rt_ell_internal *eip;
00635 fastf_t top[16*3];
00636 fastf_t middle[16*3];
00637 fastf_t bottom[16*3];
00638
00639 RT_CK_DB_INTERNAL(ip);
00640 eip = (struct rt_ell_internal *)ip->idb_ptr;
00641 RT_ELL_CK_MAGIC(eip);
00642
00643 rt_ell_16pts( top, eip->v, eip->a, eip->b );
00644 rt_ell_16pts( bottom, eip->v, eip->b, eip->c );
00645 rt_ell_16pts( middle, eip->v, eip->a, eip->c );
00646
00647 RT_ADD_VLIST( vhead, &top[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE );
00648 for( i=0; i<16; i++ ) {
00649 RT_ADD_VLIST( vhead, &top[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW );
00650 }
00651
00652 RT_ADD_VLIST( vhead, &bottom[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE );
00653 for( i=0; i<16; i++ ) {
00654 RT_ADD_VLIST( vhead, &bottom[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW );
00655 }
00656
00657 RT_ADD_VLIST( vhead, &middle[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE );
00658 for( i=0; i<16; i++ ) {
00659 RT_ADD_VLIST( vhead, &middle[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW );
00660 }
00661 return(0);
00662 }
00663
00664 #if 0
00665 static point_t octa_verts[6] = {
00666 { 1, 0, 0 },
00667 {-1, 0, 0 },
00668 { 0, 1, 0 },
00669 { 0,-1, 0 },
00670 { 0, 0, 1 },
00671 { 0, 0,-1 }
00672 };
00673
00674 #define XPLUS 0
00675 #define XMIN 1
00676 #define YPLUS 2
00677 #define YMIN 3
00678 #define ZPLUS 4
00679 #define ZMIN 5
00680 #endif
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 struct ell_state {
00700 struct shell *s;
00701 struct rt_ell_internal *eip;
00702 mat_t invRinvS;
00703 mat_t invRoS;
00704 fastf_t theta_tol;
00705 };
00706
00707 struct ell_vert_strip {
00708 int nverts_per_strip;
00709 int nverts;
00710 struct vertex **vp;
00711 vect_t *norms;
00712 int nfaces;
00713 struct faceuse **fu;
00714 };
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749 int
00750 rt_ell_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
00751 {
00752 LOCAL mat_t R;
00753 LOCAL mat_t S;
00754 LOCAL mat_t invR;
00755 LOCAL mat_t invS;
00756 LOCAL vect_t Au, Bu, Cu;
00757 LOCAL fastf_t Alen, Blen, Clen;
00758 LOCAL fastf_t invAlen, invBlen, invClen;
00759 LOCAL fastf_t magsq_a, magsq_b, magsq_c;
00760 LOCAL fastf_t f;
00761 struct ell_state state;
00762 register int i;
00763 fastf_t radius;
00764 int nsegs;
00765 int nstrips;
00766 struct ell_vert_strip *strips;
00767 int j;
00768 struct vertex **vertp[4];
00769 int faceno;
00770 int stripno;
00771 int boff;
00772 int toff;
00773 int blim;
00774 int tlim;
00775 fastf_t rel;
00776
00777 RT_CK_DB_INTERNAL(ip);
00778 state.eip = (struct rt_ell_internal *)ip->idb_ptr;
00779 RT_ELL_CK_MAGIC(state.eip);
00780
00781
00782 magsq_a = MAGSQ( state.eip->a );
00783 magsq_b = MAGSQ( state.eip->b );
00784 magsq_c = MAGSQ( state.eip->c );
00785 if( magsq_a < tol->dist || magsq_b < tol->dist || magsq_c < tol->dist ) {
00786 bu_log("rt_ell_tess(): zero length A, B, or C vector\n");
00787 return(-2);
00788 }
00789
00790
00791 invAlen = 1.0/(Alen = sqrt(magsq_a));
00792 VSCALE( Au, state.eip->a, invAlen );
00793 invBlen = 1.0/(Blen = sqrt(magsq_b));
00794 VSCALE( Bu, state.eip->b, invBlen );
00795 invClen = 1.0/(Clen = sqrt(magsq_c));
00796 VSCALE( Cu, state.eip->c, invClen );
00797
00798
00799 f = VDOT( Au, Bu );
00800 if( ! NEAR_ZERO(f, tol->dist) ) {
00801 bu_log("ell(): A not perpendicular to B, f=%f\n", f);
00802 return(-3);
00803 }
00804 f = VDOT( Bu, Cu );
00805 if( ! NEAR_ZERO(f, tol->dist) ) {
00806 bu_log("ell(): B not perpendicular to C, f=%f\n", f);
00807 return(-3);
00808 }
00809 f = VDOT( Au, Cu );
00810 if( ! NEAR_ZERO(f, tol->dist) ) {
00811 bu_log("ell(): A not perpendicular to C, f=%f\n", f);
00812 return(-3);
00813 }
00814
00815 {
00816 vect_t axb;
00817 VCROSS( axb, Au, Bu );
00818 f = VDOT( axb, Cu );
00819 if( f < 0 ) {
00820 VREVERSE( Cu, Cu );
00821 VREVERSE( state.eip->c, state.eip->c );
00822 }
00823 }
00824
00825
00826 MAT_IDN( R );
00827 VMOVE( &R[0], Au );
00828 VMOVE( &R[4], Bu );
00829 VMOVE( &R[8], Cu );
00830 bn_mat_trn( invR, R );
00831
00832
00833
00834 MAT_IDN( S );
00835 S[ 0] = invAlen;
00836 S[ 5] = invBlen;
00837 S[10] = invClen;
00838 bn_mat_inv( invS, S );
00839
00840
00841 bn_mat_mul( state.invRinvS, invR, invS );
00842
00843
00844 bn_mat_mul( state.invRoS, invR, S );
00845
00846
00847 radius = Alen;
00848 if( Blen > radius )
00849 radius = Blen;
00850 if( Clen > radius )
00851 radius = Clen;
00852
00853
00854
00855
00856 if( ttol->rel <= 0.0 || ttol->rel >= 1.0 ) {
00857 rel = 0.0;
00858 } else {
00859
00860 rel = ttol->rel * radius;
00861 }
00862 if( ttol->abs <= 0.0 ) {
00863 if( rel <= 0.0 ) {
00864
00865 rel = 0.10 * radius;
00866 } else {
00867
00868 }
00869 } else {
00870
00871 if( ttol->rel <= 0.0 || rel > ttol->abs )
00872 {
00873 rel = ttol->abs;
00874 if( rel > radius )
00875 rel = radius;
00876 }
00877 }
00878
00879
00880
00881
00882
00883 state.theta_tol = 2 * acos( 1.0 - rel / radius );
00884
00885
00886 if( ttol->norm > 0.0 && ttol->norm < state.theta_tol ) {
00887 state.theta_tol = ttol->norm;
00888 }
00889
00890 *r = nmg_mrsv( m );
00891 state.s = BU_LIST_FIRST(shell, &(*r)->s_hd);
00892
00893
00894 nsegs = (int)(bn_halfpi / state.theta_tol + 0.999);
00895 if( nsegs < 2 ) nsegs = 2;
00896
00897
00898
00899
00900
00901
00902 nstrips = 2 * nsegs + 1;
00903 strips = (struct ell_vert_strip *)bu_calloc( nstrips,
00904 sizeof(struct ell_vert_strip), "strips[]" );
00905
00906
00907 strips[0].nverts = 1;
00908 strips[0].nverts_per_strip = 0;
00909 strips[0].nfaces = 4;
00910
00911 strips[nstrips-1].nverts = 1;
00912 strips[nstrips-1].nverts_per_strip = 0;
00913 strips[nstrips-1].nfaces = 4;
00914
00915 strips[nsegs].nverts = nsegs * 4;
00916 strips[nsegs].nverts_per_strip = nsegs;
00917 strips[nsegs].nfaces = 0;
00918
00919 for( i=1; i<nsegs; i++ ) {
00920 strips[i].nverts_per_strip =
00921 strips[nstrips-1-i].nverts_per_strip = i;
00922 strips[i].nverts =
00923 strips[nstrips-1-i].nverts = i * 4;
00924 strips[i].nfaces =
00925 strips[nstrips-1-i].nfaces = (2 * i + 1)*4;
00926 }
00927
00928 for( i=0; i<nstrips; i++ ) {
00929 strips[i].vp = (struct vertex **)bu_calloc( strips[i].nverts,
00930 sizeof(struct vertex *), "strip vertex[]" );
00931 strips[i].norms = (vect_t *)bu_calloc( strips[i].nverts,
00932 sizeof( vect_t ), "strip normals[]" );
00933 }
00934
00935 for( i=0; i < nstrips; i++ ) {
00936 if( strips[i].nfaces <= 0 ) continue;
00937 strips[i].fu = (struct faceuse **)bu_calloc( strips[i].nfaces,
00938 sizeof(struct faceuse *), "strip faceuse[]" );
00939 }
00940
00941
00942
00943 for( i = 1; i <= nsegs; i++ ) {
00944 faceno = 0;
00945 tlim = strips[i-1].nverts;
00946 blim = strips[i].nverts;
00947 for( stripno=0; stripno<4; stripno++ ) {
00948 toff = stripno * strips[i-1].nverts_per_strip;
00949 boff = stripno * strips[i].nverts_per_strip;
00950
00951
00952 for( j = 0; j < strips[i].nverts_per_strip; j++ ) {
00953
00954
00955 vertp[0] = &(strips[i].vp[j+boff]);
00956 vertp[1] = &(strips[i-1].vp[(j+toff)%tlim]);
00957 vertp[2] = &(strips[i].vp[(j+1+boff)%blim]);
00958 if( (strips[i-1].fu[faceno++] = nmg_cmface(state.s, vertp, 3 )) == 0 ) {
00959 bu_log("rt_ell_tess() nmg_cmface failure\n");
00960 goto fail;
00961 }
00962 if( j+1 >= strips[i].nverts_per_strip ) break;
00963
00964
00965 vertp[0] = &(strips[i].vp[(j+1+boff)%blim]);
00966 vertp[1] = &(strips[i-1].vp[(j+toff)%tlim]);
00967 vertp[2] = &(strips[i-1].vp[(j+1+toff)%tlim]);
00968 if( (strips[i-1].fu[faceno++] = nmg_cmface(state.s, vertp, 3 )) == 0 ) {
00969 bu_log("rt_ell_tess() nmg_cmface failure\n");
00970 goto fail;
00971 }
00972 }
00973 }
00974 }
00975
00976 for( i = nsegs; i < nstrips; i++ ) {
00977 faceno = 0;
00978 tlim = strips[i+1].nverts;
00979 blim = strips[i].nverts;
00980 for( stripno=0; stripno<4; stripno++ ) {
00981 toff = stripno * strips[i+1].nverts_per_strip;
00982 boff = stripno * strips[i].nverts_per_strip;
00983
00984
00985 for( j = 0; j < strips[i].nverts_per_strip; j++ ) {
00986
00987
00988 vertp[0] = &(strips[i].vp[j+boff]);
00989 vertp[1] = &(strips[i].vp[(j+1+boff)%blim]);
00990 vertp[2] = &(strips[i+1].vp[(j+toff)%tlim]);
00991 if( (strips[i+1].fu[faceno++] = nmg_cmface(state.s, vertp, 3 )) == 0 ) {
00992 bu_log("rt_ell_tess() nmg_cmface failure\n");
00993 goto fail;
00994 }
00995 if( j+1 >= strips[i].nverts_per_strip ) break;
00996
00997
00998 vertp[0] = &(strips[i].vp[(j+1+boff)%blim]);
00999 vertp[1] = &(strips[i+1].vp[(j+1+toff)%tlim]);
01000 vertp[2] = &(strips[i+1].vp[(j+toff)%tlim]);
01001 if( (strips[i+1].fu[faceno++] = nmg_cmface(state.s, vertp, 3 )) == 0 ) {
01002 bu_log("rt_ell_tess() nmg_cmface failure\n");
01003 goto fail;
01004 }
01005 }
01006 }
01007 }
01008
01009
01010
01011
01012
01013 for( i=0; i < nstrips; i++ ) {
01014 double alpha;
01015 double beta;
01016 fastf_t cos_alpha, sin_alpha;
01017 fastf_t cos_beta, sin_beta;
01018 point_t sphere_pt;
01019 point_t model_pt;
01020
01021 alpha = (((double)i) / (nstrips-1));
01022 cos_alpha = cos(alpha*bn_pi);
01023 sin_alpha = sin(alpha*bn_pi);
01024 for( j=0; j < strips[i].nverts; j++ ) {
01025
01026 beta = ((double)j) / strips[i].nverts;
01027 cos_beta = cos(beta*bn_twopi);
01028 sin_beta = sin(beta*bn_twopi);
01029 VSET( sphere_pt,
01030 cos_beta * sin_alpha,
01031 cos_alpha,
01032 sin_beta * sin_alpha );
01033
01034 MAT4X3PNT( model_pt, state.invRinvS, sphere_pt );
01035 VADD2( model_pt, model_pt, state.eip->v );
01036
01037 nmg_vertex_gv( strips[i].vp[j], model_pt );
01038
01039
01040 MAT4X3VEC( strips[i].norms[j], state.invRoS, sphere_pt );
01041
01042 VUNITIZE( strips[i].norms[j] );
01043 }
01044 }
01045
01046
01047 for( i=0; i < nstrips; i++ ) {
01048 for( j=0; j < strips[i].nfaces; j++ ) {
01049 if( nmg_fu_planeeqn( strips[i].fu[j], tol ) < 0 )
01050 goto fail;
01051 }
01052 }
01053
01054
01055 for( i=0; i < nstrips; i++ )
01056 {
01057 for( j=0; j < strips[i].nverts; j++ )
01058 {
01059 struct faceuse *fu;
01060 struct vertexuse *vu;
01061 vect_t norm_opp;
01062
01063 NMG_CK_VERTEX( strips[i].vp[j] );
01064 VREVERSE( norm_opp , strips[i].norms[j] )
01065
01066 for( BU_LIST_FOR( vu , vertexuse , &strips[i].vp[j]->vu_hd ) )
01067 {
01068 fu = nmg_find_fu_of_vu( vu );
01069 NMG_CK_FACEUSE( fu );
01070
01071
01072
01073 if( fu->orientation == OT_SAME )
01074 nmg_vertexuse_nv( vu , strips[i].norms[j] );
01075 else if( fu->orientation == OT_OPPOSITE )
01076 nmg_vertexuse_nv( vu , norm_opp );
01077 }
01078 }
01079 }
01080
01081
01082 nmg_region_a( *r, tol );
01083
01084
01085
01086 for( i=0; i<nstrips; i++ ) {
01087 bu_free( (char *)strips[i].vp, "strip vertex[]" );
01088 bu_free( (char *)strips[i].norms, "strip norms[]" );
01089 }
01090
01091 for( i=0; i < nstrips; i++ ) {
01092 if( strips[i].fu == (struct faceuse **)0 ) continue;
01093 bu_free( (char *)strips[i].fu, "strip faceuse[]" );
01094 }
01095 bu_free( (char *)strips, "strips[]" );
01096 return(0);
01097 fail:
01098
01099
01100 for( i=0; i<nstrips; i++ ) {
01101 bu_free( (char *)strips[i].vp, "strip vertex[]" );
01102 bu_free( (char *)strips[i].norms, "strip norms[]" );
01103 }
01104
01105 for( i=0; i < nstrips; i++ ) {
01106 if( strips[i].fu == (struct faceuse **)0 ) continue;
01107 bu_free( (char *)strips[i].fu, "strip faceuse[]" );
01108 }
01109 bu_free( (char *)strips, "strips[]" );
01110 return(-1);
01111 }
01112
01113
01114
01115
01116
01117
01118
01119
01120 int
01121 rt_ell_import(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
01122 {
01123 struct rt_ell_internal *eip;
01124 union record *rp;
01125 LOCAL fastf_t vec[3*4];
01126
01127 BU_CK_EXTERNAL( ep );
01128 rp = (union record *)ep->ext_buf;
01129
01130 if( rp->u_id != ID_SOLID ) {
01131 bu_log("rt_ell_import: defective record\n");
01132 return(-1);
01133 }
01134
01135 RT_CK_DB_INTERNAL( ip );
01136 ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
01137 ip->idb_type = ID_ELL;
01138 ip->idb_meth = &rt_functab[ID_ELL];
01139 ip->idb_ptr = bu_malloc( sizeof(struct rt_ell_internal), "rt_ell_internal");
01140 eip = (struct rt_ell_internal *)ip->idb_ptr;
01141 eip->magic = RT_ELL_INTERNAL_MAGIC;
01142
01143
01144 rt_fastf_float( vec, rp->s.s_values, 4 );
01145
01146
01147 MAT4X3PNT( eip->v, mat, &vec[0*3] );
01148 MAT4X3VEC( eip->a, mat, &vec[1*3] );
01149 MAT4X3VEC( eip->b, mat, &vec[2*3] );
01150 MAT4X3VEC( eip->c, mat, &vec[3*3] );
01151
01152 return(0);
01153 }
01154
01155
01156
01157
01158 int
01159 rt_ell_export(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
01160 {
01161 struct rt_ell_internal *tip;
01162 union record *rec;
01163
01164 RT_CK_DB_INTERNAL(ip);
01165 if( ip->idb_type != ID_ELL && ip->idb_type != ID_SPH ) return(-1);
01166 tip = (struct rt_ell_internal *)ip->idb_ptr;
01167 RT_ELL_CK_MAGIC(tip);
01168
01169 BU_CK_EXTERNAL(ep);
01170 ep->ext_nbytes = sizeof(union record);
01171 ep->ext_buf = (genptr_t)bu_calloc( 1, ep->ext_nbytes, "ell external");
01172 rec = (union record *)ep->ext_buf;
01173
01174 rec->s.s_id = ID_SOLID;
01175 rec->s.s_type = GENELL;
01176
01177
01178 VSCALE( &rec->s.s_values[0], tip->v, local2mm );
01179 VSCALE( &rec->s.s_values[3], tip->a, local2mm );
01180 VSCALE( &rec->s.s_values[6], tip->b, local2mm );
01181 VSCALE( &rec->s.s_values[9], tip->c, local2mm );
01182
01183 return(0);
01184 }
01185
01186
01187
01188
01189
01190
01191
01192
01193 int
01194 rt_ell_import5(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
01195 {
01196 struct rt_ell_internal *eip;
01197 fastf_t vec[ELEMENTS_PER_VECT*4];
01198
01199 RT_CK_DB_INTERNAL( ip );
01200 BU_CK_EXTERNAL( ep );
01201
01202 BU_ASSERT_LONG( ep->ext_nbytes, ==, SIZEOF_NETWORK_DOUBLE * ELEMENTS_PER_VECT*4 );
01203
01204 ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
01205 ip->idb_type = ID_ELL;
01206 ip->idb_meth = &rt_functab[ID_ELL];
01207 ip->idb_ptr = bu_malloc( sizeof(struct rt_ell_internal), "rt_ell_internal");
01208
01209 eip = (struct rt_ell_internal *)ip->idb_ptr;
01210 eip->magic = RT_ELL_INTERNAL_MAGIC;
01211
01212
01213 ntohd( (unsigned char *)vec, ep->ext_buf, ELEMENTS_PER_VECT*4 );
01214
01215
01216 MAT4X3PNT( eip->v, mat, &vec[0*ELEMENTS_PER_VECT] );
01217 MAT4X3VEC( eip->a, mat, &vec[1*ELEMENTS_PER_VECT] );
01218 MAT4X3VEC( eip->b, mat, &vec[2*ELEMENTS_PER_VECT] );
01219 MAT4X3VEC( eip->c, mat, &vec[3*ELEMENTS_PER_VECT] );
01220
01221 return 0;
01222 }
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233 int
01234 rt_ell_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
01235 {
01236 struct rt_ell_internal *eip;
01237 fastf_t vec[ELEMENTS_PER_VECT*4];
01238
01239 RT_CK_DB_INTERNAL(ip);
01240 if( ip->idb_type != ID_ELL && ip->idb_type != ID_SPH ) return(-1);
01241 eip = (struct rt_ell_internal *)ip->idb_ptr;
01242 RT_ELL_CK_MAGIC(eip);
01243
01244 BU_CK_EXTERNAL(ep);
01245 ep->ext_nbytes = SIZEOF_NETWORK_DOUBLE * ELEMENTS_PER_VECT*4;
01246 ep->ext_buf = (genptr_t)bu_malloc( ep->ext_nbytes, "ell external");
01247
01248
01249 VSCALE( &vec[0*ELEMENTS_PER_VECT], eip->v, local2mm );
01250 VSCALE( &vec[1*ELEMENTS_PER_VECT], eip->a, local2mm );
01251 VSCALE( &vec[2*ELEMENTS_PER_VECT], eip->b, local2mm );
01252 VSCALE( &vec[3*ELEMENTS_PER_VECT], eip->c, local2mm );
01253
01254
01255 htond( ep->ext_buf, (unsigned char *)vec, ELEMENTS_PER_VECT*4 );
01256
01257 return 0;
01258 }
01259
01260
01261
01262
01263
01264
01265
01266
01267 int
01268 rt_ell_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
01269 {
01270 register struct rt_ell_internal *tip =
01271 (struct rt_ell_internal *)ip->idb_ptr;
01272 fastf_t mag_a, mag_b, mag_c;
01273 char buf[256];
01274 double angles[5];
01275 vect_t unitv;
01276
01277 RT_ELL_CK_MAGIC(tip);
01278 bu_vls_strcat( str, "ellipsoid (ELL)\n");
01279
01280 sprintf(buf, "\tV (%g, %g, %g)\n",
01281 INTCLAMP(tip->v[X] * mm2local),
01282 INTCLAMP(tip->v[Y] * mm2local),
01283 INTCLAMP(tip->v[Z] * mm2local) );
01284 bu_vls_strcat( str, buf );
01285
01286 mag_a = MAGNITUDE(tip->a);
01287 mag_b = MAGNITUDE(tip->b);
01288 mag_c = MAGNITUDE(tip->c);
01289
01290 sprintf(buf, "\tA (%g, %g, %g) mag=%g\n",
01291 INTCLAMP(tip->a[X] * mm2local),
01292 INTCLAMP(tip->a[Y] * mm2local),
01293 INTCLAMP(tip->a[Z] * mm2local),
01294 INTCLAMP(mag_a * mm2local) );
01295 bu_vls_strcat( str, buf );
01296
01297 sprintf(buf, "\tB (%g, %g, %g) mag=%g\n",
01298 INTCLAMP(tip->b[X] * mm2local),
01299 INTCLAMP(tip->b[Y] * mm2local),
01300 INTCLAMP(tip->b[Z] * mm2local),
01301 INTCLAMP(mag_b * mm2local) );
01302 bu_vls_strcat( str, buf );
01303
01304 sprintf(buf, "\tC (%g, %g, %g) mag=%g\n",
01305 INTCLAMP(tip->c[X] * mm2local),
01306 INTCLAMP(tip->c[Y] * mm2local),
01307 INTCLAMP(tip->c[Z] * mm2local),
01308 INTCLAMP(mag_c * mm2local) );
01309 bu_vls_strcat( str, buf );
01310
01311 if( !verbose ) return(0);
01312
01313 VSCALE( unitv, tip->a, 1/mag_a );
01314 rt_find_fallback_angle( angles, unitv );
01315 rt_pr_fallback_angle( str, "\tA", angles );
01316
01317 VSCALE( unitv, tip->b, 1/mag_b );
01318 rt_find_fallback_angle( angles, unitv );
01319 rt_pr_fallback_angle( str, "\tB", angles );
01320
01321 VSCALE( unitv, tip->c, 1/mag_c );
01322 rt_find_fallback_angle( angles, unitv );
01323 rt_pr_fallback_angle( str, "\tC", angles );
01324
01325 return(0);
01326 }
01327
01328
01329
01330
01331
01332
01333 void
01334 rt_ell_ifree(struct rt_db_internal *ip)
01335 {
01336 RT_CK_DB_INTERNAL(ip);
01337 bu_free( ip->idb_ptr, "ell ifree" );
01338 ip->idb_ptr = GENPTR_NULL;
01339 }
01340
01341
01342
01343
01344
01345 static const fastf_t rt_ell_uvw[5*ELEMENTS_PER_VECT] = {
01346 0, 1, 0,
01347 0, 0, 0,
01348 1, 0, 0,
01349 1, 1, 0,
01350 0, 1, 0
01351 };
01352
01353
01354
01355
01356 int
01357 rt_ell_tnurb(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct bn_tol *tol)
01358 {
01359 LOCAL mat_t R;
01360 LOCAL mat_t S;
01361 LOCAL mat_t invR;
01362 LOCAL mat_t invS;
01363 mat_t invRinvS;
01364 mat_t invRoS;
01365 LOCAL mat_t unit2model;
01366 LOCAL mat_t xlate;
01367 LOCAL vect_t Au, Bu, Cu;
01368 LOCAL fastf_t Alen, Blen, Clen;
01369 LOCAL fastf_t invAlen, invBlen, invClen;
01370 LOCAL fastf_t magsq_a, magsq_b, magsq_c;
01371 LOCAL fastf_t f;
01372 register int i;
01373 fastf_t radius;
01374 struct rt_ell_internal *eip;
01375 struct vertex *verts[8];
01376 struct vertex **vertp[4];
01377 struct faceuse *fu;
01378 struct shell *s;
01379 struct loopuse *lu;
01380 struct edgeuse *eu;
01381 point_t pole;
01382
01383 RT_CK_DB_INTERNAL(ip);
01384 eip = (struct rt_ell_internal *)ip->idb_ptr;
01385 RT_ELL_CK_MAGIC(eip);
01386
01387
01388 magsq_a = MAGSQ( eip->a );
01389 magsq_b = MAGSQ( eip->b );
01390 magsq_c = MAGSQ( eip->c );
01391 if( magsq_a < tol->dist || magsq_b < tol->dist || magsq_c < tol->dist ) {
01392 bu_log("rt_ell_tess(): zero length A, B, or C vector\n");
01393 return(-2);
01394 }
01395
01396
01397 invAlen = 1.0/(Alen = sqrt(magsq_a));
01398 VSCALE( Au, eip->a, invAlen );
01399 invBlen = 1.0/(Blen = sqrt(magsq_b));
01400 VSCALE( Bu, eip->b, invBlen );
01401 invClen = 1.0/(Clen = sqrt(magsq_c));
01402 VSCALE( Cu, eip->c, invClen );
01403
01404
01405 f = VDOT( Au, Bu );
01406 if( ! NEAR_ZERO(f, tol->dist) ) {
01407 bu_log("ell(): A not perpendicular to B, f=%f\n", f);
01408 return(-3);
01409 }
01410 f = VDOT( Bu, Cu );
01411 if( ! NEAR_ZERO(f, tol->dist) ) {
01412 bu_log("ell(): B not perpendicular to C, f=%f\n", f);
01413 return(-3);
01414 }
01415 f = VDOT( Au, Cu );
01416 if( ! NEAR_ZERO(f, tol->dist) ) {
01417 bu_log("ell(): A not perpendicular to C, f=%f\n", f);
01418 return(-3);
01419 }
01420
01421 {
01422 vect_t axb;
01423 VCROSS( axb, Au, Bu );
01424 f = VDOT( axb, Cu );
01425 if( f < 0 ) {
01426 VREVERSE( Cu, Cu );
01427 VREVERSE( eip->c, eip->c );
01428 }
01429 }
01430
01431
01432 MAT_IDN( R );
01433 VMOVE( &R[0], Au );
01434 VMOVE( &R[4], Bu );
01435 VMOVE( &R[8], Cu );
01436 bn_mat_trn( invR, R );
01437
01438
01439
01440 MAT_IDN( S );
01441 S[ 0] = invAlen;
01442 S[ 5] = invBlen;
01443 S[10] = invClen;
01444 bn_mat_inv( invS, S );
01445
01446
01447 bn_mat_mul( invRinvS, invR, invS );
01448
01449
01450 bn_mat_mul( invRoS, invR, S );
01451
01452
01453 radius = Alen;
01454 if( Blen > radius )
01455 radius = Blen;
01456 if( Clen > radius )
01457 radius = Clen;
01458
01459 MAT_IDN( xlate );
01460 MAT_DELTAS_VEC( xlate, eip->v );
01461 bn_mat_mul( unit2model, xlate, invRinvS );
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473 for( i=0; i<8; i++ ) verts[i] = (struct vertex *)0;
01474
01475 *r = nmg_mrsv( m );
01476 s = BU_LIST_FIRST(shell, &(*r)->s_hd);
01477
01478 vertp[0] = &verts[0];
01479 vertp[1] = &verts[0];
01480 vertp[2] = &verts[1];
01481 vertp[3] = &verts[1];
01482
01483 if( (fu = nmg_cmface( s, vertp, 4 )) == 0 ) {
01484 bu_log("rt_ell_tnurb(%s): nmg_cmface() fail on face\n");
01485 return -1;
01486 }
01487
01488
01489 lu = BU_LIST_FIRST( loopuse, &fu->lu_hd );
01490 NMG_CK_LOOPUSE(lu);
01491 eu = BU_LIST_FIRST( edgeuse, &lu->down_hd );
01492 NMG_CK_EDGEUSE(eu);
01493
01494
01495 for( i=0; i < 4; i++ ) {
01496 nmg_vertexuse_a_cnurb( eu->vu_p, &rt_ell_uvw[i*ELEMENTS_PER_VECT] );
01497 nmg_vertexuse_a_cnurb( eu->eumate_p->vu_p, &rt_ell_uvw[(i+1)*ELEMENTS_PER_VECT] );
01498 eu = BU_LIST_NEXT( edgeuse, &eu->l );
01499 }
01500
01501
01502 VSUB2( pole, eip->v, eip->c );
01503 nmg_vertex_gv( verts[0], pole );
01504 VADD2( pole, eip->v, eip->c );
01505 nmg_vertex_gv( verts[1], pole );
01506
01507
01508 nmg_sphere_face_snurb( fu, unit2model );
01509
01510
01511 eu = BU_LIST_FIRST( edgeuse, &lu->down_hd );
01512 NMG_CK_EDGEUSE(eu);
01513 for( i=0; i < 4; i++ ) {
01514 #if 0
01515 struct snurb sn;
01516 fastf_t param[4];
01517 bu_log("\neu=x%x, vu=x%x, v=x%x ", eu, eu->vu_p, eu->vu_p->v_p);
01518 VPRINT("xyz", eu->vu_p->v_p->vg_p->coord);
01519 nmg_hack_snurb( &sn, fu->f_p->g.snurb_p );
01520 VPRINT("uv", eu->vu_p->a.cnurb_p->param);
01521 rt_nurb_s_eval( &sn, V2ARGS(eu->vu_p->a.cnurb_p->param), param );
01522 VPRINT("surf(u,v)", param);
01523 #endif
01524
01525 nmg_edge_g_cnurb_plinear(eu);
01526 eu = BU_LIST_NEXT( edgeuse, &eu->l );
01527 }
01528
01529
01530 nmg_region_a( *r, tol );
01531
01532 return 0;
01533 }
01534
01535
01536
01537
01538
01539 static void
01540 nmg_sphere_face_snurb(struct faceuse *fu, const matp_t m)
01541 {
01542 struct face_g_snurb *fg;
01543 FAST fastf_t root2_2;
01544 register fastf_t *op;
01545
01546 NMG_CK_FACEUSE(fu);
01547 root2_2 = sqrt(2.0)*0.5;
01548
01549
01550
01551 nmg_face_g_snurb( fu,
01552 3, 3,
01553 8, 12,
01554 NULL, NULL,
01555 9, 5,
01556 RT_NURB_MAKE_PT_TYPE( 4, RT_NURB_PT_XYZ, RT_NURB_PT_RATIONAL ),
01557 NULL );
01558
01559 fg = fu->f_p->g.snurb_p;
01560 NMG_CK_FACE_G_SNURB(fg);
01561
01562 fg->v.knots[ 0] = 0;
01563 fg->v.knots[ 1] = 0;
01564 fg->v.knots[ 2] = 0;
01565 fg->v.knots[ 3] = 0.25;
01566 fg->v.knots[ 4] = 0.25;
01567 fg->v.knots[ 5] = 0.5;
01568 fg->v.knots[ 6] = 0.5;
01569 fg->v.knots[ 7] = 0.75;
01570 fg->v.knots[ 8] = 0.75;
01571 fg->v.knots[ 9] = 1;
01572 fg->v.knots[10] = 1;
01573 fg->v.knots[11] = 1;
01574
01575 fg->u.knots[0] = 0;
01576 fg->u.knots[1] = 0;
01577 fg->u.knots[2] = 0;
01578 fg->u.knots[3] = 0.5;
01579 fg->u.knots[4] = 0.5;
01580 fg->u.knots[5] = 1;
01581 fg->u.knots[6] = 1;
01582 fg->u.knots[7] = 1;
01583
01584 op = fg->ctl_points;
01585
01586
01587 #define M(x,y,z,w) { \
01588 *op++ = m[ 0]*(x) + m[ 1]*(y) + m[ 2]*(z) + m[ 3]*(w);\
01589 *op++ = m[ 4]*(x) + m[ 5]*(y) + m[ 6]*(z) + m[ 7]*(w);\
01590 *op++ = m[ 8]*(x) + m[ 9]*(y) + m[10]*(z) + m[11]*(w);\
01591 *op++ = m[12]*(x) + m[13]*(y) + m[14]*(z) + m[15]*(w); }
01592
01593
01594 M( 0 , 0 ,-1.0 , 1.0 );
01595 M( root2_2 , 0 ,-root2_2 , root2_2 );
01596 M( 1.0 , 0 , 0 , 1.0 );
01597 M( root2_2 , 0 , root2_2 , root2_2 );
01598 M( 0 , 0 , 1.0 , 1.0 );
01599
01600 M( 0 , 0 ,-root2_2 , root2_2 );
01601 M( 0.5 ,-0.5 ,-0.5 , 0.5 );
01602 M( root2_2 ,-root2_2 , 0 , root2_2 );
01603 M( 0.5 ,-0.5 , 0.5 , 0.5 );
01604 M( 0 , 0 , root2_2 , root2_2 );
01605
01606 M( 0 , 0 ,-1.0 , 1.0 );
01607 M( 0 ,-root2_2 ,-root2_2 , root2_2 );
01608 M( 0 ,-1.0 , 0 , 1.0 );
01609 M( 0 ,-root2_2 , root2_2 , root2_2 );
01610 M( 0 , 0 , 1.0 , 1.0 );
01611
01612 M( 0 , 0 ,-root2_2 , root2_2 );
01613 M(-0.5 ,-0.5 ,-0.5 , 0.5 );
01614 M(-root2_2 ,-root2_2 , 0 , root2_2 );
01615 M(-0.5 ,-0.5 , 0.5 , 0.5 );
01616 M( 0 , 0 , root2_2 , root2_2 );
01617
01618 M( 0 , 0 ,-1.0 , 1.0 );
01619 M(-root2_2 , 0 ,-root2_2 , root2_2 );
01620 M(-1.0 , 0 , 0 , 1.0 );
01621 M(-root2_2 , 0 , root2_2 , root2_2 );
01622 M( 0 , 0 , 1.0 , 1.0 );
01623
01624 M( 0 , 0 ,-root2_2 , root2_2 );
01625 M(-0.5 , 0.5 ,-0.5 , 0.5 );
01626 M(-root2_2 , root2_2 , 0 , root2_2 );
01627 M(-0.5 , 0.5 , 0.5 , 0.5 );
01628 M( 0 , 0 , root2_2 , root2_2 );
01629
01630 M( 0 , 0 ,-1.0 , 1.0 );
01631 M( 0 , root2_2 ,-root2_2 , root2_2 );
01632 M( 0 , 1.0 , 0 , 1.0 );
01633 M( 0 , root2_2 , root2_2 , root2_2 );
01634 M( 0 , 0 , 1.0 , 1.0 );
01635
01636 M( 0 , 0 ,-root2_2 , root2_2 );
01637 M( 0.5 , 0.5 ,-0.5 , 0.5 );
01638 M( root2_2 , root2_2 , 0 , root2_2 );
01639 M( 0.5 , 0.5 , 0.5 , 0.5 );
01640 M( 0 , 0 , root2_2 , root2_2 );
01641
01642 M( 0 , 0 ,-1.0 , 1.0 );
01643 M( root2_2 , 0 ,-root2_2 , root2_2 );
01644 M( 1.0 , 0 , 0 , 1.0 );
01645 M( root2_2 , 0 , root2_2 , root2_2 );
01646 M( 0 , 0 , 1.0 , 1.0 );
01647 }
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658