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 #ifndef lint
00039 static const char RCScline[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/g_cline.c,v 14.13 2006/09/16 02:04:24 lbutler Exp $ (BRL)";
00040 #endif
00041
00042 #include "common.h"
00043
00044 #include <stdlib.h>
00045 #include <stddef.h>
00046 #include <stdio.h>
00047 #include <math.h>
00048
00049 #include "tcl.h"
00050 #include "machine.h"
00051 #include "vmath.h"
00052 #include "db.h"
00053 #include "nmg.h"
00054 #include "raytrace.h"
00055 #include "rtgeom.h"
00056 #include "./debug.h"
00057
00058
00059 struct cline_specific {
00060 point_t V;
00061 vect_t height;
00062 fastf_t radius;
00063 fastf_t thickness;
00064 vect_t h;
00065 };
00066
00067 #define RT_CLINE_O(m) bu_offsetof( struct rt_cline_internal, m )
00068
00069 const struct bu_structparse rt_cline_parse[] = {
00070 { "%f", 3, "V", RT_CLINE_O( v ), BU_STRUCTPARSE_FUNC_NULL },
00071 { "%f", 3, "H", RT_CLINE_O( h ), BU_STRUCTPARSE_FUNC_NULL },
00072 { "%f", 1, "r", RT_CLINE_O( radius ), BU_STRUCTPARSE_FUNC_NULL },
00073 { "%f", 1, "t", RT_CLINE_O( thickness ), BU_STRUCTPARSE_FUNC_NULL },
00074 { {'\0','\0','\0','\0'}, 0, (char *)NULL, 0, BU_STRUCTPARSE_FUNC_NULL }
00075 };
00076
00077
00078 fastf_t rt_cline_radius=-1.0;
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 int
00096 rt_cline_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
00097 {
00098 struct rt_cline_internal *cline_ip;
00099 register struct cline_specific *cline;
00100 vect_t work;
00101 vect_t rad;
00102 point_t top;
00103 fastf_t tmp;
00104 fastf_t max_tr;
00105
00106 RT_CK_DB_INTERNAL(ip);
00107 cline_ip = (struct rt_cline_internal *)ip->idb_ptr;
00108 RT_CLINE_CK_MAGIC(cline_ip);
00109
00110 BU_GETSTRUCT( cline, cline_specific );
00111 cline->thickness = cline_ip->thickness;
00112 cline->radius = cline_ip->radius;
00113 VMOVE( cline->V, cline_ip->v );
00114 VMOVE( cline->height, cline_ip->h );
00115 VMOVE( cline->h, cline_ip->h );
00116 VUNITIZE( cline->h );
00117 stp->st_specific = (genptr_t)cline;
00118
00119 if( rt_cline_radius > 0.0 )
00120 max_tr = rt_cline_radius;
00121 else
00122 max_tr = 0.0;
00123 tmp = MAGNITUDE( cline_ip->h ) * 0.5;
00124 stp->st_aradius = sqrt( tmp*tmp + cline_ip->radius*cline_ip->radius );
00125 stp->st_bradius = stp->st_aradius + max_tr;
00126 VSETALL( stp->st_min, MAX_FASTF );
00127 VREVERSE( stp->st_max, stp->st_min );
00128
00129 VSETALL( rad, cline_ip->radius + max_tr );
00130 VADD2( work, cline_ip->v, rad );
00131 VMINMAX( stp->st_min,stp->st_max, work );
00132 VSUB2( work, cline_ip->v, rad );
00133 VMINMAX( stp->st_min,stp->st_max, work );
00134 VADD2( top, cline_ip->v, cline_ip->h );
00135 VADD2( work, top, rad );
00136 VMINMAX( stp->st_min,stp->st_max, work );
00137 VSUB2( work, top, rad );
00138 VMINMAX( stp->st_min,stp->st_max, work );
00139
00140 return( 0 );
00141 }
00142
00143
00144
00145
00146 void
00147 rt_cline_print(register const struct soltab *stp)
00148 {
00149 register const struct cline_specific *cline =
00150 (struct cline_specific *)stp->st_specific;
00151
00152 VPRINT( "V", cline->V );
00153 VPRINT( "Height", cline->height );
00154 VPRINT( "Unit Height", cline->h );
00155 bu_log( "Radius: %g\n", cline->radius );
00156 if( cline->thickness > 0.0 )
00157 bu_log( "Plate Mode Thickness: %g\n", cline->thickness );
00158 else
00159 bu_log( "Volume mode\n" );
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 int
00174 rt_cline_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
00175 {
00176 register struct cline_specific *cline =
00177 (struct cline_specific *)stp->st_specific;
00178 struct seg ref_seghead;
00179 register struct seg *segp;
00180 fastf_t reff;
00181 fastf_t dist[3];
00182 fastf_t cosa, sina;
00183 fastf_t half_los;
00184 point_t pt1, pt2;
00185 vect_t diff;
00186 fastf_t tmp;
00187 fastf_t distmin, distmax;
00188 fastf_t add_radius;
00189
00190 BU_LIST_INIT( &ref_seghead.l );
00191
00192
00193 if( rt_cline_radius > 0.0 )
00194 {
00195 add_radius = rt_cline_radius;
00196 reff = cline->radius + add_radius;
00197 }
00198 else
00199 {
00200 add_radius = 0.0;
00201 reff = cline->radius;
00202 }
00203
00204 cosa = VDOT( rp->r_dir, cline->h );
00205
00206 if( cosa > 0.0 )
00207 tmp = cosa - 1.0;
00208 else
00209 tmp = cosa + 1.0;
00210
00211 (void)bn_distsq_line3_line3( dist, cline->V, cline->height,
00212 rp->r_pt, rp->r_dir, pt1, pt2 );
00213
00214 if( NEAR_ZERO( tmp, RT_DOT_TOL ) )
00215 {
00216
00217 #if 1
00218
00219
00220
00221
00222
00223 return( 0 );
00224 #else
00225
00226 if( cline->thickness > 0.0 )
00227 return( 0 );
00228
00229 if( dist[2] > reff*reff )
00230 return( 0 );
00231
00232 VJOIN2( diff, cline->V, 1.0, cline->height, -1.0, rp->r_pt );
00233 dist[0] = VDOT( diff, rp->r_dir );
00234 if( dist[1] < dist[0] )
00235 {
00236 dist[2] = dist[0];
00237 dist[0] = dist[1];
00238 dist[1] = dist[2];
00239 }
00240
00241
00242
00243 RT_GET_SEG( segp, ap->a_resource);
00244 segp->seg_stp = stp;
00245 segp->seg_in.hit_dist = dist[0];
00246 segp->seg_in.hit_surfno = 1;
00247 if( cosa > 0.0 )
00248 VREVERSE( segp->seg_in.hit_normal, cline->h )
00249 else
00250 VMOVE( segp->seg_in.hit_normal, cline->h );
00251
00252 segp->seg_out.hit_dist = dist[1];
00253 segp->seg_out.hit_surfno = -1;
00254 if( cosa < 0.0 )
00255 VREVERSE( segp->seg_out.hit_normal, cline->h )
00256 else
00257 VMOVE( segp->seg_out.hit_normal, cline->h );
00258 BU_LIST_INSERT( &(seghead->l), &(segp->l) );
00259 return( 1 );
00260 #endif
00261 }
00262
00263 if( dist[2] > reff*reff )
00264 return( 0 );
00265
00266
00267
00268 if( dist[0] < 0.0 || dist[0] > 1.0 )
00269 return( 0 );
00270
00271 sina = sqrt( 1.0 - cosa*cosa);
00272 tmp = sqrt( dist[2] ) - add_radius;
00273 if( dist[2] > add_radius * add_radius )
00274 half_los = sqrt( cline->radius*cline->radius - tmp*tmp) / sina;
00275 else
00276 half_los = cline->radius / sina;
00277
00278 VSUB2( diff, cline->V, rp->r_pt );
00279 distmin = VDOT( rp->r_dir, diff );
00280 VADD2( diff, cline->V, cline->height );
00281 VSUB2( diff, diff, rp->r_pt );
00282 distmax = VDOT( rp->r_dir, diff );
00283
00284 if( distmin > distmax )
00285 {
00286 tmp = distmin;
00287 distmin = distmax;
00288 distmax = tmp;
00289 }
00290
00291 distmin -= cline->radius;
00292 distmax += cline->radius;
00293
00294 if( cline->thickness <= 0.0 )
00295 {
00296
00297
00298 RT_GET_SEG( segp, ap->a_resource);
00299 segp->seg_stp = stp;
00300 segp->seg_in.hit_surfno = 2;
00301 segp->seg_in.hit_dist = dist[1] - half_los;
00302 if( segp->seg_in.hit_dist < distmin )
00303 segp->seg_in.hit_dist = distmin;
00304 VMOVE( segp->seg_in.hit_vpriv, cline->h );
00305
00306 segp->seg_out.hit_surfno = -2;
00307 segp->seg_out.hit_dist = dist[1] + half_los;
00308 if( segp->seg_out.hit_dist > distmax )
00309 segp->seg_out.hit_dist = distmax;
00310 VMOVE( segp->seg_out.hit_vpriv, cline->h );
00311 BU_LIST_INSERT( &(seghead->l), &(segp->l) );
00312
00313 return( 1 );
00314 }
00315 else
00316 {
00317
00318
00319 RT_GET_SEG( segp, ap->a_resource);
00320 segp->seg_stp = stp;
00321 segp->seg_in.hit_surfno = 2;
00322 segp->seg_in.hit_dist = dist[1] - half_los;
00323 if( segp->seg_in.hit_dist < distmin )
00324 segp->seg_in.hit_dist = distmin;
00325 VMOVE( segp->seg_in.hit_vpriv, cline->h );
00326
00327 segp->seg_out.hit_surfno = -2;
00328 segp->seg_out.hit_dist = segp->seg_in.hit_dist + cline->thickness;
00329 VMOVE( segp->seg_out.hit_vpriv, cline->h );
00330 BU_LIST_INSERT( &(seghead->l), &(segp->l) );
00331
00332 RT_GET_SEG( segp, ap->a_resource);
00333 segp->seg_stp = stp;
00334 segp->seg_in.hit_surfno = 2;
00335 segp->seg_in.hit_dist = dist[1] + half_los;
00336 if( segp->seg_in.hit_dist > distmax )
00337 segp->seg_in.hit_dist = distmax;
00338 segp->seg_in.hit_dist -= cline->thickness;
00339 VMOVE( segp->seg_in.hit_vpriv, cline->h );
00340
00341 segp->seg_out.hit_surfno = -2;
00342 segp->seg_out.hit_dist = segp->seg_in.hit_dist + cline->thickness;
00343 VMOVE( segp->seg_out.hit_vpriv, cline->h );
00344 BU_LIST_INSERT( &(seghead->l), &(segp->l) );
00345
00346 return( 2 );
00347 }
00348 }
00349
00350 #define RT_CLINE_SEG_MISS(SEG) (SEG).seg_stp=RT_SOLTAB_NULL
00351
00352
00353
00354
00355
00356
00357 void
00358 rt_cline_vshot(struct soltab **stp, struct xray **rp, struct seg *segp, int n, struct application *ap)
00359
00360
00361
00362
00363
00364 {
00365 rt_vstub( stp, rp, segp, n, ap );
00366 }
00367
00368
00369
00370
00371
00372
00373 void
00374 rt_cline_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp)
00375 {
00376 vect_t tmp;
00377 fastf_t dot;
00378
00379 if( hitp->hit_surfno == 1 || hitp->hit_surfno == -1 )
00380 return;
00381
00382
00383
00384
00385 VCROSS( tmp, rp->r_dir, hitp->hit_vpriv );
00386 VCROSS( hitp->hit_normal, tmp, hitp->hit_vpriv );
00387 VUNITIZE( hitp->hit_normal );
00388 dot = VDOT( hitp->hit_normal, rp->r_dir );
00389 if( dot < 0.0 && hitp->hit_surfno < 0 )
00390 VREVERSE( hitp->hit_normal, hitp->hit_normal )
00391 else if( dot > 0.0 && hitp->hit_surfno > 0 )
00392 VREVERSE( hitp->hit_normal, hitp->hit_normal )
00393
00394 if( MAGNITUDE( hitp->hit_normal ) < 0.9 ) {
00395 bu_log( "BAD normal for solid %s for ray -p %g %g %g -d %g %g %g\n",
00396 stp->st_name, V3ARGS( rp->r_pt ), V3ARGS( rp->r_dir ) );
00397 bu_bomb( "BAD normal\n" );
00398 }
00399 VJOIN1( hitp->hit_point, rp->r_pt, hitp->hit_dist, rp->r_dir );
00400 }
00401
00402
00403
00404
00405
00406
00407 void
00408 rt_cline_curve(register struct curvature *cvp, register struct hit *hitp, struct soltab *stp)
00409 {
00410
00411
00412 cvp->crv_c1 = cvp->crv_c2 = 0;
00413
00414
00415 bn_vec_ortho( cvp->crv_pdir, hitp->hit_normal );
00416 }
00417
00418
00419
00420
00421
00422
00423
00424 void
00425 rt_cline_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
00426 {
00427 uvp->uv_u = 0.0;
00428 uvp->uv_v = 0.0;
00429 uvp->uv_du = 0.0;
00430 uvp->uv_dv = 0.0;
00431 }
00432
00433
00434
00435
00436 void
00437 rt_cline_free(register struct soltab *stp)
00438 {
00439 register struct cline_specific *cline =
00440 (struct cline_specific *)stp->st_specific;
00441
00442 bu_free( (char *)cline, "cline_specific" );
00443 }
00444
00445
00446
00447
00448 int
00449 rt_cline_class(const struct soltab *stp, const fastf_t *min, const fastf_t *max, const struct bn_tol *tol)
00450 {
00451
00452 return( 0 );
00453 }
00454
00455
00456
00457
00458 int
00459 rt_cline_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
00460 {
00461 LOCAL struct rt_cline_internal *cline_ip;
00462 LOCAL fastf_t top[16*3];
00463 LOCAL fastf_t bottom[16*3];
00464 point_t top_pt;
00465 vect_t unit_a, unit_b;
00466 vect_t a, b;
00467 fastf_t inner_radius;
00468 int i;
00469
00470 RT_CK_DB_INTERNAL(ip);
00471 cline_ip = (struct rt_cline_internal *)ip->idb_ptr;
00472 RT_CLINE_CK_MAGIC(cline_ip);
00473
00474 VADD2( top_pt, cline_ip->v, cline_ip->h );
00475 bn_vec_ortho( unit_a, cline_ip->h );
00476 VCROSS( unit_b, unit_a, cline_ip->h );
00477 VUNITIZE( unit_b );
00478 VSCALE( a, unit_a, cline_ip->radius );
00479 VSCALE( b, unit_b, cline_ip->radius );
00480
00481 rt_ell_16pts( bottom, cline_ip->v, a, b );
00482 rt_ell_16pts( top, top_pt, a, b );
00483
00484
00485 RT_ADD_VLIST( vhead, &top[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE );
00486 for( i=0; i<16; i++ ) {
00487 RT_ADD_VLIST( vhead, &top[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW );
00488 }
00489
00490
00491 RT_ADD_VLIST( vhead, &bottom[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE );
00492 for( i=0; i<16; i++ ) {
00493 RT_ADD_VLIST( vhead, &bottom[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW );
00494 }
00495
00496
00497 for( i=0; i<16; i += 4 ) {
00498 RT_ADD_VLIST( vhead, &top[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE );
00499 RT_ADD_VLIST( vhead, &bottom[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW );
00500 }
00501
00502 if( cline_ip->thickness > 0.0 && cline_ip->thickness < cline_ip->radius )
00503 {
00504
00505
00506 inner_radius = cline_ip->radius - cline_ip->thickness;
00507
00508 VSCALE( a, unit_a, inner_radius );
00509 VSCALE( b, unit_b, inner_radius );
00510
00511 rt_ell_16pts( bottom, cline_ip->v, a, b );
00512 rt_ell_16pts( top, top_pt, a, b );
00513
00514
00515 RT_ADD_VLIST( vhead, &top[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE );
00516 for( i=0; i<16; i++ ) {
00517 RT_ADD_VLIST( vhead, &top[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW );
00518 }
00519
00520
00521 RT_ADD_VLIST( vhead, &bottom[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE );
00522 for( i=0; i<16; i++ ) {
00523 RT_ADD_VLIST( vhead, &bottom[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW );
00524 }
00525
00526
00527 for( i=0; i<16; i += 4 ) {
00528 RT_ADD_VLIST( vhead, &top[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE );
00529 RT_ADD_VLIST( vhead, &bottom[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW );
00530 }
00531
00532 }
00533
00534 return(0);
00535 }
00536
00537 struct cline_vert {
00538 point_t pt;
00539 struct vertex *v;
00540 };
00541
00542
00543
00544
00545
00546
00547
00548
00549 int
00550 rt_cline_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
00551 {
00552 struct shell *s;
00553 struct rt_cline_internal *cline_ip;
00554 fastf_t ang_tol, abs_tol, norm_tol, rel_tol;
00555 int nsegs, seg_no, i;
00556 struct cline_vert *base_outer, *base_inner, *top_outer, *top_inner;
00557 struct cline_vert base_center, top_center;
00558 vect_t v1, v2;
00559 point_t top;
00560 struct bu_ptbl faces;
00561
00562 RT_CK_DB_INTERNAL(ip);
00563 cline_ip = (struct rt_cline_internal *)ip->idb_ptr;
00564 RT_CLINE_CK_MAGIC(cline_ip);
00565
00566 *r = nmg_mrsv( m );
00567 s = BU_LIST_FIRST(shell, &(*r)->s_hd);
00568
00569 ang_tol = bn_halfpi;
00570 abs_tol = bn_halfpi;
00571 rel_tol = bn_halfpi;
00572 norm_tol = bn_halfpi;
00573
00574 if( ttol->abs <= 0.0 && ttol->rel <= 0.0 && ttol->norm <= 0.0 )
00575 {
00576
00577 ang_tol = 2.0 * acos( 0.9 );
00578 }
00579 else
00580 {
00581 if( ttol->abs > 0.0 && ttol->abs < cline_ip->radius )
00582 abs_tol = 2.0 * acos( 1.0 - ttol->abs / cline_ip->radius );
00583 if( ttol->rel > 0.0 && ttol->rel < 1.0 )
00584 rel_tol = 2.0 * acos( 1.0 - ttol->rel );
00585 if( ttol->norm > 0.0 )
00586 norm_tol = 2.0 * ttol->norm;
00587 }
00588
00589 if( abs_tol < ang_tol )
00590 ang_tol = abs_tol;
00591 if( rel_tol < ang_tol )
00592 ang_tol = rel_tol;
00593 if( norm_tol < ang_tol )
00594 ang_tol = norm_tol;
00595
00596
00597 nsegs = (int)(bn_halfpi / ang_tol + 0.9999);
00598 if( nsegs < 2 )
00599 nsegs = 2;
00600
00601 ang_tol = bn_halfpi / nsegs;
00602
00603
00604 nsegs *= 4;
00605
00606
00607 base_outer = (struct cline_vert *)bu_calloc( nsegs, sizeof( struct cline_vert ), "base outer vertices" );
00608 top_outer = (struct cline_vert *)bu_calloc( nsegs, sizeof( struct cline_vert ), "top outer vertices" );
00609
00610 if( cline_ip->thickness > 0.0 && cline_ip->thickness < cline_ip->radius )
00611 {
00612 base_inner = (struct cline_vert *)bu_calloc( nsegs, sizeof( struct cline_vert ), "base inner vertices" );
00613 top_inner = (struct cline_vert *)bu_calloc( nsegs, sizeof( struct cline_vert ), "top inner vertices" );
00614 } else {
00615 base_inner = NULL;
00616 top_inner = NULL;
00617 }
00618
00619
00620 bn_vec_ortho( v1, cline_ip->h );
00621 VCROSS( v2, cline_ip->h, v1 );
00622 VUNITIZE( v2 );
00623 VADD2( top, cline_ip->v, cline_ip->h );
00624 for( seg_no = 0; seg_no < nsegs ; seg_no++ )
00625 {
00626 fastf_t a, b, c, d, angle;
00627
00628 angle = ang_tol * seg_no;
00629
00630 a = cos( angle );
00631 b = sin( angle );
00632
00633 if( cline_ip->thickness > 0.0 && cline_ip->thickness < cline_ip->radius )
00634 {
00635 c = a * (cline_ip->radius - cline_ip->thickness);
00636 d = b * (cline_ip->radius - cline_ip->thickness);
00637 } else {
00638 c = d = 0;
00639 }
00640
00641 a *= cline_ip->radius;
00642 b *= cline_ip->radius;
00643
00644 VJOIN2( base_outer[seg_no].pt, cline_ip->v, a, v1, b, v2 );
00645 VADD2( top_outer[seg_no].pt, base_outer[seg_no].pt, cline_ip->h );
00646
00647 if( cline_ip->thickness > 0.0 && cline_ip->thickness < cline_ip->radius )
00648 {
00649 VJOIN2( base_inner[seg_no].pt, cline_ip->v, c, v1, d, v2 );
00650 VADD2( top_inner[seg_no].pt, base_inner[seg_no].pt, cline_ip->h );
00651 }
00652 }
00653
00654 bu_ptbl_init( &faces , 64, "faces");
00655
00656 for( seg_no=0 ; seg_no<nsegs ; seg_no++ )
00657 {
00658 int next_seg;
00659 struct vertex **verts[3];
00660 struct faceuse *fu;
00661
00662 next_seg = seg_no + 1;
00663 if( next_seg == nsegs )
00664 next_seg = 0;
00665
00666 verts[2] = &top_outer[seg_no].v;
00667 verts[1] = &top_outer[next_seg].v;
00668 verts[0] = &base_outer[seg_no].v;
00669
00670 fu = nmg_cmface( s, verts, 3 );
00671 bu_ptbl_ins( &faces , (long *)fu );
00672
00673 verts[2] = &base_outer[seg_no].v;
00674 verts[1] = &top_outer[next_seg].v;
00675 verts[0] = &base_outer[next_seg].v;
00676
00677 fu = nmg_cmface( s, verts, 3 );
00678 bu_ptbl_ins( &faces , (long *)fu );
00679 }
00680
00681
00682 if( cline_ip->thickness > 0.0 && cline_ip->thickness < cline_ip->radius )
00683 {
00684 for( seg_no=0 ; seg_no<nsegs ; seg_no++ )
00685 {
00686 int next_seg;
00687 struct vertex **verts[3];
00688 struct faceuse *fu;
00689
00690 next_seg = seg_no + 1;
00691 if( next_seg == nsegs )
00692 next_seg = 0;
00693
00694 verts[0] = &top_inner[seg_no].v;
00695 verts[1] = &top_inner[next_seg].v;
00696 verts[2] = &base_inner[seg_no].v;
00697
00698 fu = nmg_cmface( s, verts, 3 );
00699 bu_ptbl_ins( &faces , (long *)fu );
00700
00701 verts[0] = &base_inner[seg_no].v;
00702 verts[1] = &top_inner[next_seg].v;
00703 verts[2] = &base_inner[next_seg].v;
00704
00705 fu = nmg_cmface( s, verts, 3 );
00706 bu_ptbl_ins( &faces , (long *)fu );
00707 }
00708 }
00709
00710
00711 top_center.v = (struct vertex *)NULL;
00712 VMOVE( top_center.pt, top );
00713 for( seg_no=0 ; seg_no<nsegs ; seg_no++ )
00714 {
00715 int next_seg;
00716 struct vertex **verts[3];
00717 struct faceuse *fu;
00718
00719 next_seg = seg_no + 1;
00720 if( next_seg == nsegs )
00721 next_seg = 0;
00722
00723 if( cline_ip->thickness > 0.0 && cline_ip->thickness < cline_ip->radius )
00724 {
00725 verts[2] = &top_outer[seg_no].v;
00726 verts[1] = &top_inner[seg_no].v;
00727 verts[0] = &top_inner[next_seg].v;
00728 fu = nmg_cmface( s, verts, 3 );
00729 bu_ptbl_ins( &faces , (long *)fu );
00730
00731 verts[2] = &top_inner[next_seg].v;
00732 verts[1] = &top_outer[next_seg].v;
00733 verts[0] = &top_outer[seg_no].v;
00734 fu = nmg_cmface( s, verts, 3 );
00735 bu_ptbl_ins( &faces , (long *)fu );
00736 }
00737 else
00738 {
00739 verts[2] = &top_outer[seg_no].v;
00740 verts[1] = &top_center.v;
00741 verts[0] = &top_outer[next_seg].v;
00742 fu = nmg_cmface( s, verts, 3 );
00743 bu_ptbl_ins( &faces , (long *)fu );
00744 }
00745 }
00746
00747
00748 base_center.v = (struct vertex *)NULL;
00749 VMOVE( base_center.pt, cline_ip->v );
00750 for( seg_no=0 ; seg_no<nsegs ; seg_no++ )
00751 {
00752 int next_seg;
00753 struct vertex **verts[3];
00754 struct faceuse *fu;
00755
00756 next_seg = seg_no + 1;
00757 if( next_seg == nsegs )
00758 next_seg = 0;
00759
00760 if( cline_ip->thickness > 0.0 && cline_ip->thickness < cline_ip->radius )
00761 {
00762 verts[0] = &base_outer[seg_no].v;
00763 verts[1] = &base_inner[seg_no].v;
00764 verts[2] = &base_inner[next_seg].v;
00765 fu = nmg_cmface( s, verts, 3 );
00766 bu_ptbl_ins( &faces , (long *)fu );
00767
00768 verts[0] = &base_inner[next_seg].v;
00769 verts[1] = &base_outer[next_seg].v;
00770 verts[2] = &base_outer[seg_no].v;
00771 fu = nmg_cmface( s, verts, 3 );
00772 bu_ptbl_ins( &faces , (long *)fu );
00773 }
00774 else
00775 {
00776 verts[0] = &base_outer[seg_no].v;
00777 verts[1] = &base_center.v;
00778 verts[2] = &base_outer[next_seg].v;
00779 fu = nmg_cmface( s, verts, 3 );
00780 bu_ptbl_ins( &faces , (long *)fu );
00781 }
00782 }
00783
00784
00785 if( top_center.v )
00786 nmg_vertex_gv( top_center.v, top_center.pt );
00787 if( base_center.v )
00788 nmg_vertex_gv( base_center.v, base_center.pt );
00789
00790 for( seg_no=0 ; seg_no<nsegs ; seg_no++ )
00791 {
00792 nmg_vertex_gv( top_outer[seg_no].v, top_outer[seg_no].pt );
00793 nmg_vertex_gv( base_outer[seg_no].v, base_outer[seg_no].pt );
00794 }
00795
00796 if( cline_ip->thickness > 0.0 && cline_ip->thickness < cline_ip->radius )
00797 {
00798 for( seg_no=0 ; seg_no<nsegs ; seg_no++ )
00799 {
00800 nmg_vertex_gv( top_inner[seg_no].v, top_inner[seg_no].pt );
00801 nmg_vertex_gv( base_inner[seg_no].v, base_inner[seg_no].pt );
00802 }
00803 }
00804
00805 bu_free( (char *)base_outer, "base outer vertices" );
00806 bu_free( (char *)top_outer, "top outer vertices" );
00807 if( cline_ip->thickness > 0.0 && cline_ip->thickness < cline_ip->radius )
00808 {
00809 bu_free( (char *)base_inner, "base inner vertices" );
00810 bu_free( (char *)top_inner, "top inner vertices" );
00811 }
00812
00813
00814 for( i=0 ; i<BU_PTBL_END( &faces ) ; i++ )
00815 {
00816 struct faceuse *fu;
00817
00818 fu = (struct faceuse *)BU_PTBL_GET( &faces , i );
00819 NMG_CK_FACEUSE( fu );
00820
00821 if( nmg_calc_face_g( fu ) )
00822 {
00823 bu_log( "rt_tess_cline: failed to calculate plane equation\n" );
00824 nmg_pr_fu_briefly( fu, "" );
00825 return( -1 );
00826 }
00827 }
00828
00829 nmg_region_a( *r , tol );
00830 bu_ptbl_free( &faces );
00831
00832 return(0);
00833 }
00834
00835
00836
00837
00838
00839
00840
00841 int
00842 rt_cline_import(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
00843 {
00844 LOCAL struct rt_cline_internal *cline_ip;
00845 union record *rp;
00846 point_t work;
00847
00848 BU_CK_EXTERNAL( ep );
00849 rp = (union record *)ep->ext_buf;
00850
00851
00852 if( rp->u_id != DBID_CLINE ) {
00853 bu_log("rt_cline_import: defective record\n");
00854 return(-1);
00855 }
00856
00857 RT_CK_DB_INTERNAL( ip );
00858 ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
00859 ip->idb_type = ID_CLINE;
00860 ip->idb_meth = &rt_functab[ID_CLINE];
00861 ip->idb_ptr = bu_malloc( sizeof(struct rt_cline_internal), "rt_cline_internal");
00862 cline_ip = (struct rt_cline_internal *)ip->idb_ptr;
00863 cline_ip->magic = RT_CLINE_INTERNAL_MAGIC;
00864 ntohd( (unsigned char *)(&cline_ip->thickness), rp->cli.cli_thick, 1 );
00865 cline_ip->thickness /= mat[15];
00866 ntohd( (unsigned char *)(&cline_ip->radius), rp->cli.cli_radius, 1 );
00867 cline_ip->radius /= mat[15];
00868 ntohd( (unsigned char *)(&work), rp->cli.cli_V, 3 );
00869 MAT4X3PNT( cline_ip->v, mat, work );
00870 ntohd( (unsigned char *)(&work), rp->cli.cli_h, 3 );
00871 MAT4X3VEC( cline_ip->h, mat, work );
00872
00873 return(0);
00874 }
00875
00876
00877
00878
00879
00880
00881 int
00882 rt_cline_export(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
00883 {
00884 struct rt_cline_internal *cline_ip;
00885 union record *rec;
00886 fastf_t tmp;
00887 point_t work;
00888
00889 RT_CK_DB_INTERNAL(ip);
00890 if( ip->idb_type != ID_CLINE ) return(-1);
00891 cline_ip = (struct rt_cline_internal *)ip->idb_ptr;
00892 RT_CLINE_CK_MAGIC(cline_ip);
00893
00894 BU_CK_EXTERNAL(ep);
00895 ep->ext_nbytes = sizeof(union record);
00896 ep->ext_buf = (genptr_t)bu_calloc( 1, ep->ext_nbytes, "cline external");
00897 rec = (union record *)ep->ext_buf;
00898
00899 rec->s.s_id = ID_SOLID;
00900 rec->cli.cli_id = DBID_CLINE;
00901
00902 tmp = cline_ip->thickness * local2mm;
00903 htond( rec->cli.cli_thick, (unsigned char *)(&tmp), 1 );
00904 tmp = cline_ip->radius * local2mm;
00905 htond( rec->cli.cli_radius, (unsigned char *)(&tmp), 1 );
00906 VSCALE( work, cline_ip->v, local2mm );
00907 htond( rec->cli.cli_V, (unsigned char *)work, 3 );
00908 VSCALE( work, cline_ip->h, local2mm );
00909 htond( rec->cli.cli_h, (unsigned char *)work, 3 );
00910
00911 return(0);
00912 }
00913
00914
00915
00916
00917
00918
00919
00920 int
00921 rt_cline_import5(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
00922 {
00923 struct rt_cline_internal *cline_ip;
00924 fastf_t vec[8];
00925
00926 BU_CK_EXTERNAL( ep );
00927
00928 BU_ASSERT_LONG( ep->ext_nbytes, ==, SIZEOF_NETWORK_DOUBLE * 8 );
00929
00930 RT_CK_DB_INTERNAL( ip );
00931 ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
00932 ip->idb_type = ID_CLINE;
00933 ip->idb_meth = &rt_functab[ID_CLINE];
00934 ip->idb_ptr = bu_malloc( sizeof(struct rt_cline_internal), "rt_cline_internal");
00935
00936 cline_ip = (struct rt_cline_internal *)ip->idb_ptr;
00937 cline_ip->magic = RT_CLINE_INTERNAL_MAGIC;
00938
00939
00940 ntohd( (unsigned char *)vec, ep->ext_buf, 8 );
00941
00942 cline_ip->thickness = vec[0] / mat[15];
00943 cline_ip->radius = vec[1] / mat[15];
00944 MAT4X3PNT(cline_ip->v, mat, &vec[2]);
00945 MAT4X3VEC(cline_ip->h, mat, &vec[5]);
00946
00947 return(0);
00948 }
00949
00950
00951
00952
00953
00954
00955 int
00956 rt_cline_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
00957 {
00958 struct rt_cline_internal *cline_ip;
00959 fastf_t vec[8];
00960
00961 RT_CK_DB_INTERNAL(ip);
00962 if (ip->idb_type != ID_CLINE) return(-1);
00963 cline_ip = (struct rt_cline_internal *)ip->idb_ptr;
00964 RT_CLINE_CK_MAGIC(cline_ip);
00965
00966 BU_CK_EXTERNAL(ep);
00967 ep->ext_nbytes = SIZEOF_NETWORK_DOUBLE * 8;
00968 ep->ext_buf = (genptr_t)bu_malloc(ep->ext_nbytes, "cline external");
00969
00970 vec[0] = cline_ip->thickness * local2mm;
00971 vec[1] = cline_ip->radius * local2mm;
00972 VSCALE(&vec[2], cline_ip->v, local2mm);
00973 VSCALE(&vec[5], cline_ip->h, local2mm);
00974
00975
00976 htond(ep->ext_buf, (unsigned char *)vec, 8);
00977
00978 return(0);
00979 }
00980
00981
00982
00983
00984
00985
00986
00987
00988 int
00989 rt_cline_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
00990 {
00991 register struct rt_cline_internal *cline_ip =
00992 (struct rt_cline_internal *)ip->idb_ptr;
00993 char buf[256];
00994 point_t local_v;
00995 vect_t local_h;
00996
00997 RT_CLINE_CK_MAGIC(cline_ip);
00998 bu_vls_strcat( str, "cline solid (CLINE)\n");
00999
01000 VSCALE( local_v, cline_ip->v, mm2local );
01001 VSCALE( local_h, cline_ip->h, mm2local );
01002
01003 if( cline_ip->thickness > 0.0 )
01004 {
01005 sprintf( buf, "\tV (%g %g %g)\n\tH (%g %g %g)\n\tradius %g\n\tplate mode thickness %g",
01006 V3INTCLAMPARGS( local_v ), V3INTCLAMPARGS( local_h ), INTCLAMP(cline_ip->radius*mm2local), INTCLAMP(cline_ip->thickness*mm2local) );
01007 }
01008 else
01009 {
01010 sprintf( buf, "\tV (%g %g %g)\n\tH (%g %g %g)\n\tradius %g\n\tVolume mode\n",
01011 V3INTCLAMPARGS( local_v ), V3INTCLAMPARGS( local_h ), INTCLAMP(cline_ip->radius*mm2local) );
01012 }
01013 bu_vls_strcat( str, buf );
01014
01015 return(0);
01016 }
01017
01018
01019
01020
01021
01022
01023 void
01024 rt_cline_ifree(struct rt_db_internal *ip)
01025 {
01026 register struct rt_cline_internal *cline_ip;
01027
01028 RT_CK_DB_INTERNAL(ip);
01029 cline_ip = (struct rt_cline_internal *)ip->idb_ptr;
01030 RT_CLINE_CK_MAGIC(cline_ip);
01031 cline_ip->magic = 0;
01032
01033 bu_free( (char *)cline_ip, "cline ifree" );
01034 ip->idb_ptr = GENPTR_NULL;
01035 }
01036
01037 int
01038 rt_cline_tnurb(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct bn_tol *tol)
01039 {
01040 return( 1 );
01041 }
01042
01043 int
01044 rt_cline_tclget(Tcl_Interp *interp, const struct rt_db_internal *intern, const char *attr)
01045 {
01046 register struct rt_cline_internal *cli =
01047 (struct rt_cline_internal *)intern->idb_ptr;
01048 Tcl_DString ds;
01049 struct bu_vls vls;
01050 int ret=TCL_OK;
01051
01052 RT_CLINE_CK_MAGIC( cli );
01053
01054 Tcl_DStringInit( &ds );
01055 bu_vls_init( &vls );
01056
01057 if( attr == (char *)NULL )
01058 {
01059 bu_vls_strcpy( &vls, "cline" );
01060 bu_vls_printf( &vls, " V {%.25G %.25G %.25G}", V3ARGS( cli->v ) );
01061 bu_vls_printf( &vls, " H {%.25G %.25G %.25G}", V3ARGS( cli->h ) );
01062 bu_vls_printf( &vls, " R %.25G T %.25G", cli->radius, cli->thickness );
01063 }
01064 else if( *attr == 'V')
01065 bu_vls_printf( &vls, "%.25G %.25G %.25G", V3ARGS( cli->v ) );
01066 else if( *attr == 'H' )
01067 bu_vls_printf( &vls, "%.25G %.25G %.25G", V3ARGS( cli->h ) );
01068 else if( *attr == 'R' )
01069 bu_vls_printf( &vls, "%.25G", cli->radius );
01070 else if( *attr == 'T' )
01071 bu_vls_printf( &vls, "%.25G", cli->thickness );
01072 else
01073 {
01074 bu_vls_strcat( &vls, "ERROR: unrecognized attribute, must be V, H, R, or T!!!" );
01075 ret = TCL_ERROR;
01076 }
01077
01078 Tcl_DStringAppend( &ds, bu_vls_addr( &vls ), -1 );
01079 Tcl_DStringResult( interp, &ds );
01080 Tcl_DStringFree( &ds );
01081 bu_vls_free( &vls );
01082 return( ret );
01083 }
01084
01085 int
01086 rt_cline_tcladjust(Tcl_Interp *interp, struct rt_db_internal *intern, int argc, char **argv)
01087 {
01088 struct rt_cline_internal *cli =
01089 (struct rt_cline_internal *)intern->idb_ptr;
01090 fastf_t *new;
01091
01092 RT_CK_DB_INTERNAL( intern );
01093 RT_CLINE_CK_MAGIC( cli );
01094
01095 while( argc >= 2 )
01096 {
01097 int array_len=3;
01098
01099 if( *argv[0] == 'V' )
01100 {
01101 new = cli->v;
01102 if( tcl_list_to_fastf_array( interp, argv[1], &new, &array_len ) !=
01103 array_len ) {
01104 Tcl_SetResult( interp,
01105 "ERROR: Incorrect number of coordinates for vector\n",
01106 TCL_STATIC );
01107 return( TCL_ERROR );
01108 }
01109 }
01110 else if( *argv[0] == 'H' )
01111 {
01112 new = cli->h;
01113 if( tcl_list_to_fastf_array( interp, argv[1], &new, &array_len ) !=
01114 array_len ) {
01115 Tcl_SetResult( interp,
01116 "ERROR: Incorrect number of coordinates for point\n",
01117 TCL_STATIC );
01118 return( TCL_ERROR );
01119 }
01120 }
01121 else if( *argv[0] == 'R' )
01122 cli->radius = atof( argv[1] );
01123 else if( *argv[0] == 'T' )
01124 cli->thickness = atof( argv[1] );
01125
01126 argc -= 2;
01127 argv += 2;
01128 }
01129
01130 return( TCL_OK );
01131 }
01132
01133 int
01134 rt_cline_tclform( const struct rt_functab *ftp, Tcl_Interp *interp )
01135 {
01136 RT_CK_FUNCTAB(ftp);
01137
01138 Tcl_AppendResult( interp,
01139 "V {%f %f %f} H {%f %f %f} R %f T %f", (char *)NULL );
01140
01141 return TCL_OK;
01142
01143 }
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154