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 #ifndef lint
00056 static const char RCSarb[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/g_arb.c,v 14.15 2006/09/16 02:04:24 lbutler Exp $ (BRL)";
00057 #endif
00058
00059 #include "common.h"
00060
00061 #include <stddef.h>
00062 #include <stdio.h>
00063 #include <math.h>
00064 #ifdef HAVE_STRING_H
00065 # include <string.h>
00066 #else
00067 # include <strings.h>
00068 #endif
00069 #include "machine.h"
00070 #include "bu.h"
00071 #include "vmath.h"
00072 #include "bn.h"
00073 #include "nmg.h"
00074 #include "db.h"
00075 #include "rtgeom.h"
00076 #include "raytrace.h"
00077 #include "nurb.h"
00078 #include "./debug.h"
00079
00080
00081 #define RT_SLOPPY_DOT_TOL 0.0087
00082
00083
00084 struct oface {
00085 fastf_t arb_UVorig[3];
00086 fastf_t arb_U[3];
00087 fastf_t arb_V[3];
00088 fastf_t arb_Ulen;
00089 fastf_t arb_Vlen;
00090 };
00091
00092
00093 struct aface {
00094 fastf_t A[3];
00095 plane_t peqn;
00096 };
00097
00098
00099 struct arb_specific {
00100 int arb_nmfaces;
00101 struct oface *arb_opt;
00102 struct aface arb_face[4];
00103 };
00104
00105
00106 struct prep_arb {
00107 vect_t pa_center;
00108 int pa_faces;
00109 int pa_npts[6];
00110 int pa_pindex[4][6];
00111 int pa_clockwise[6];
00112 struct aface pa_face[6];
00113 struct oface pa_opt[6];
00114
00115 fastf_t pa_tol_sq;
00116 int pa_doopt;
00117 };
00118
00119
00120
00121
00122
00123
00124
00125 struct arb_info {
00126 char *ai_title;
00127 int ai_sub[4];
00128 };
00129 static const struct arb_info rt_arb_info[6] = {
00130 { "1234", {3, 2, 1, 0} },
00131 { "8765", {4, 5, 6, 7} },
00132 { "1485", {4, 7, 3, 0} },
00133 { "2673", {2, 6, 5, 1} },
00134 { "1562", {1, 5, 4, 0} },
00135 { "4378", {7, 6, 2, 3} }
00136 };
00137
00138 BU_EXTERN(void rt_arb_ifree, (struct rt_db_internal *) );
00139
00140 const struct bu_structparse rt_arb_parse[] = {
00141 { "%f", 3, "V1", bu_offsetof(struct rt_arb_internal, pt[0][X]), BU_STRUCTPARSE_FUNC_NULL },
00142 { "%f", 3, "V2", bu_offsetof(struct rt_arb_internal, pt[1][X]), BU_STRUCTPARSE_FUNC_NULL },
00143 { "%f", 3, "V3", bu_offsetof(struct rt_arb_internal, pt[2][X]), BU_STRUCTPARSE_FUNC_NULL },
00144 { "%f", 3, "V4", bu_offsetof(struct rt_arb_internal, pt[3][X]), BU_STRUCTPARSE_FUNC_NULL },
00145 { "%f", 3, "V5", bu_offsetof(struct rt_arb_internal, pt[4][X]), BU_STRUCTPARSE_FUNC_NULL },
00146 { "%f", 3, "V6", bu_offsetof(struct rt_arb_internal, pt[5][X]), BU_STRUCTPARSE_FUNC_NULL },
00147 { "%f", 3, "V7", bu_offsetof(struct rt_arb_internal, pt[6][X]), BU_STRUCTPARSE_FUNC_NULL },
00148 { "%f", 3, "V8", bu_offsetof(struct rt_arb_internal, pt[7][X]), BU_STRUCTPARSE_FUNC_NULL },
00149 { {'\0','\0','\0','\0'}, 0, (char *)NULL, 0, BU_STRUCTPARSE_FUNC_NULL }
00150 };
00151
00152
00153 const int rt_arb_faces[5][24] = {
00154 {0,1,2,3, 0,1,4,5, 1,2,4,5, 0,2,4,5, -1,-1,-1,-1, -1,-1,-1,-1},
00155 {0,1,2,3, 4,0,1,5, 4,1,2,5, 4,2,3,5, 4,3,0,5, -1,-1,-1,-1},
00156 {0,1,2,3, 1,2,4,6, 0,4,6,3, 4,1,0,5, 6,2,3,7, -1,-1,-1,-1},
00157 {0,1,2,3, 4,5,6,7, 0,3,4,7, 1,2,6,5, 0,1,5,4, 3,2,6,4},
00158 {0,1,2,3, 4,5,6,7, 0,4,7,3, 1,2,6,5, 0,1,5,4, 3,2,6,7},
00159 };
00160
00161
00162
00163 #define NO 0
00164 #define YES 1
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 int
00184 rt_arb_get_cgtype(
00185 int *cgtype,
00186 struct rt_arb_internal *arb,
00187 const struct bn_tol *tol,
00188 register int *uvec,
00189 register int *svec)
00190 {
00191 register int i,j;
00192 int numuvec, unique, done;
00193 int si;
00194
00195 RT_ARB_CK_MAGIC(arb);
00196 BN_CK_TOL(tol);
00197
00198 done = NO;
00199
00200 svec[0] = svec[1] = 0;
00201 si = 2;
00202
00203 for(i=0; i<7; i++) {
00204 unique = YES;
00205 if(done == NO) {
00206 svec[si] = i;
00207 }
00208 for(j=i+1; j<8; j++) {
00209 int tmp;
00210 vect_t vtmp;
00211
00212 VSUB2( vtmp, arb->pt[i], arb->pt[j] );
00213
00214 if( fabs(vtmp[0]) > tol->dist) tmp = 0;
00215 else if( fabs(vtmp[1]) > tol->dist) tmp = 0;
00216 else if( fabs(vtmp[2]) > tol->dist) tmp = 0;
00217 else tmp = 1;
00218
00219 if( tmp ) {
00220 if( done == NO )
00221 svec[++si] = j;
00222 unique = NO;
00223 }
00224 }
00225 if( unique == NO ) {
00226 if( si > 2 && si < 6 ) {
00227 svec[0] = si - 1;
00228 if(si == 5 && svec[5] >= 6)
00229 done = YES;
00230 si = 6;
00231 }
00232 if( si > 6 ) {
00233 svec[1] = si - 5;
00234 done = YES;
00235 }
00236 }
00237 }
00238
00239 if( si > 2 && si < 6 ) {
00240 svec[0] = si - 1;
00241 }
00242 if( si > 6 ) {
00243 svec[1] = si - 5;
00244 }
00245 for(i=1; i<=svec[1]; i++) {
00246 svec[svec[0]+1+i] = svec[5+i];
00247 }
00248 for(i=svec[0]+svec[1]+2; i<11; i++) {
00249 svec[i] = -1;
00250 }
00251
00252
00253 numuvec = 0;
00254 for(j=0; j<8; j++) {
00255 unique = YES;
00256 for(i=2; i<svec[0]+svec[1]+2; i++) {
00257 if( j == svec[i] ) {
00258 unique = NO;
00259 break;
00260 }
00261 }
00262 if( unique == YES ) {
00263 uvec[numuvec++] = j;
00264 }
00265 }
00266
00267
00268 switch( numuvec ) {
00269
00270 case 8:
00271 *cgtype = ARB8;
00272 break;
00273
00274 case 6:
00275 *cgtype = ARB7;
00276 break;
00277
00278 case 4:
00279 if(svec[0] == 2)
00280 *cgtype = ARB6;
00281 else
00282 *cgtype = ARB5;
00283 break;
00284
00285 case 2:
00286 *cgtype = ARB4;
00287 break;
00288
00289 default:
00290 bu_log( "rt_arb_get_cgtype: bad number of unique vectors (%d)\n",
00291 numuvec);
00292
00293 return(0);
00294 }
00295 #if 0
00296 bu_log("uvec: ");
00297 for(j=0; j<8; j++) bu_log("%d, ", uvec[j]);
00298 bu_log("\nsvec: ");
00299 for(j=0; j<11; j++ ) bu_log("%d, ", svec[j]);
00300 bu_log("\n");
00301 #endif
00302 return( numuvec );
00303 }
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 int
00324 rt_arb_std_type( const struct rt_db_internal *ip, const struct bn_tol *tol )
00325 {
00326 struct rt_arb_internal *arb;
00327 int uvec[8], svec[11];
00328 int cgtype = 0;
00329
00330 RT_CK_DB_INTERNAL(ip);
00331 BN_CK_TOL(tol);
00332
00333 if( ip->idb_type != ID_ARB8 ) bu_bomb("rt_arb_std_type: not ARB!\n");
00334
00335 arb = (struct rt_arb_internal *)ip->idb_ptr;
00336 RT_ARB_CK_MAGIC(arb);
00337
00338 if( rt_arb_get_cgtype( &cgtype, arb, tol, uvec, svec ) == 0 )
00339 return(0);
00340
00341 return( cgtype );
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351 void
00352 rt_arb_centroid( point_t center_pt, const struct rt_arb_internal *arb, int npoints )
00353 {
00354 register int j;
00355 fastf_t div;
00356 point_t sum;
00357
00358 RT_ARB_CK_MAGIC(arb);
00359
00360 VSETALL(sum, 0);
00361
00362 for( j=0; j < npoints; j++ ) {
00363 VADD2( sum, sum, arb->pt[j] );
00364 }
00365 div = 1.0 / npoints;
00366 VSCALE( center_pt, sum, div );
00367 }
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 HIDDEN int
00382 rt_arb_add_pt(register pointp_t point, const char *title, struct prep_arb *pap, int ptno, const char *name)
00383
00384
00385
00386
00387
00388 {
00389 LOCAL vect_t work;
00390 LOCAL vect_t P_A;
00391 FAST fastf_t f;
00392 register struct aface *afp;
00393 register struct oface *ofp;
00394
00395 afp = &pap->pa_face[pap->pa_faces];
00396 ofp = &pap->pa_opt[pap->pa_faces];
00397
00398
00399 switch( ptno ) {
00400 case 0:
00401 VMOVE( afp->A, point );
00402 if( pap->pa_doopt ) {
00403 VMOVE( ofp->arb_UVorig, point );
00404 }
00405 return(0);
00406 case 1:
00407 VSUB2( ofp->arb_U, point, afp->A );
00408 f = MAGNITUDE( ofp->arb_U );
00409 if( NEAR_ZERO( f, SQRT_SMALL_FASTF ) ) {
00410 return(-1);
00411 }
00412 ofp->arb_Ulen = f;
00413 f = 1/f;
00414 VSCALE( ofp->arb_U, ofp->arb_U, f );
00415
00416 return(0);
00417 case 2:
00418 VSUB2( P_A, point, afp->A );
00419
00420
00421 VCROSS( afp->peqn, P_A, ofp->arb_U );
00422
00423 f = MAGNITUDE( afp->peqn );
00424 if( NEAR_ZERO(f,RT_SLOPPY_DOT_TOL) ) {
00425 return(-1);
00426 }
00427 f = 1/f;
00428 VSCALE( afp->peqn, afp->peqn, f );
00429
00430 if( pap->pa_doopt ) {
00431
00432
00433
00434
00435 VCROSS( work, afp->peqn, ofp->arb_U );
00436 VUNITIZE( work );
00437 f = VDOT( work, P_A );
00438 VSCALE( ofp->arb_V, work, f );
00439 f = MAGNITUDE( ofp->arb_V );
00440 ofp->arb_Vlen = f;
00441 f = 1/f;
00442 VSCALE( ofp->arb_V, ofp->arb_V, f );
00443
00444
00445 VSUB2( P_A, point, ofp->arb_UVorig );
00446 f = VDOT( P_A, ofp->arb_U );
00447 if( f > ofp->arb_Ulen ) {
00448 ofp->arb_Ulen = f;
00449 } else if( f < 0.0 ) {
00450 VJOIN1( ofp->arb_UVorig, ofp->arb_UVorig, f,
00451 ofp->arb_U );
00452 ofp->arb_Ulen += (-f);
00453 }
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 VSUB2( work, afp->A, pap->pa_center );
00466 f = VDOT( work, afp->peqn );
00467 if( f < 0.0 ) {
00468 VREVERSE(afp->peqn, afp->peqn);
00469 pap->pa_clockwise[pap->pa_faces] = 1;
00470 } else {
00471 pap->pa_clockwise[pap->pa_faces] = 0;
00472 }
00473 afp->peqn[3] = VDOT( afp->peqn, afp->A );
00474 return(0);
00475 default:
00476
00477 if( pap->pa_doopt ) {
00478 VSUB2( P_A, point, ofp->arb_UVorig );
00479
00480 f = VDOT( P_A, ofp->arb_U );
00481 if( f > ofp->arb_Ulen ) {
00482 ofp->arb_Ulen = f;
00483 } else if( f < 0.0 ) {
00484 VJOIN1( ofp->arb_UVorig, ofp->arb_UVorig, f,
00485 ofp->arb_U );
00486 ofp->arb_Ulen += (-f);
00487 }
00488 f = VDOT( P_A, ofp->arb_V );
00489 if( f > ofp->arb_Vlen ) {
00490 ofp->arb_Vlen = f;
00491 } else if( f < 0.0 ) {
00492 VJOIN1( ofp->arb_UVorig, ofp->arb_UVorig, f,
00493 ofp->arb_V );
00494 ofp->arb_Vlen += (-f);
00495 }
00496 }
00497
00498 VSUB2( P_A, point, afp->A );
00499 VUNITIZE( P_A );
00500 f = VDOT( afp->peqn, P_A );
00501 if( ! NEAR_ZERO(f,RT_SLOPPY_DOT_TOL) ) {
00502
00503 bu_log("arb(%s): face %s[%d] non-planar, dot=%g\n",
00504 name, title, ptno, f );
00505 #ifdef CONSERVATIVE
00506 return(-1);
00507 #endif
00508 }
00509 return(0);
00510 }
00511
00512 }
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 HIDDEN int
00525 rt_arb_mk_planes(register struct prep_arb *pap, struct rt_arb_internal *aip, const char *name)
00526 {
00527 LOCAL vect_t sum;
00528 register int i;
00529 register int j;
00530 register int k;
00531 int equiv_pts[8];
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 VSETALL( sum, 0 );
00542 # include "noalias.h"
00543 for( i=0; i<8; i++ ) {
00544 VADD2( sum, sum, aip->pt[i] );
00545 }
00546 VSCALE( pap->pa_center, sum, 0.125 );
00547
00548
00549
00550
00551
00552
00553
00554 equiv_pts[0] = 0;
00555 for( i=1; i<8; i++ ) {
00556 for( j = i-1; j >= 0; j-- ) {
00557
00558 LOCAL vect_t work;
00559
00560 VSUB2( work, aip->pt[i], aip->pt[j] );
00561 if( MAGSQ( work ) < pap->pa_tol_sq ) {
00562
00563 equiv_pts[i] = equiv_pts[j];
00564 goto next_point;
00565 }
00566 }
00567 equiv_pts[i] = i;
00568 next_point: ;
00569 }
00570 if( RT_G_DEBUG & DEBUG_ARB8 ) {
00571 bu_log("arb(%s) equiv_pts[] = %d %d %d %d %d %d %d %d\n",
00572 name,
00573 equiv_pts[0], equiv_pts[1], equiv_pts[2], equiv_pts[3],
00574 equiv_pts[4], equiv_pts[5], equiv_pts[6], equiv_pts[7]);
00575 }
00576
00577 pap->pa_faces = 0;
00578 for( i=0; i<6; i++ ) {
00579 int npts;
00580
00581 npts = 0;
00582 for( j=0; j<4; j++ ) {
00583 int pt_index;
00584
00585 pt_index = rt_arb_info[i].ai_sub[j];
00586 if( RT_G_DEBUG & DEBUG_ARB8 ) {
00587 bu_log("face %d, j=%d, npts=%d, orig_vert=%d, vert=%d\n",
00588 i, j, npts,
00589 pt_index, equiv_pts[pt_index] );
00590 }
00591 pt_index = equiv_pts[pt_index];
00592
00593
00594
00595
00596 # include "noalias.h"
00597 for( k = npts-1; k >= 0; k-- ) {
00598 if( pap->pa_pindex[k][pap->pa_faces] == pt_index ) {
00599
00600 goto skip_pt;
00601 }
00602 }
00603 if( rt_arb_add_pt( aip->pt[pt_index],
00604 rt_arb_info[i].ai_title, pap, npts, name ) == 0 ) {
00605
00606 pap->pa_pindex[npts][pap->pa_faces] = pt_index;
00607 npts++;
00608 }
00609
00610 skip_pt: ;
00611 }
00612
00613 if( npts < 3 ) {
00614
00615 continue;
00616 }
00617
00618 if( pap->pa_doopt ) {
00619 register struct oface *ofp;
00620
00621 ofp = &pap->pa_opt[pap->pa_faces];
00622
00623
00624
00625 ofp->arb_Ulen = 1.0 / ofp->arb_Ulen;
00626 ofp->arb_Vlen = 1.0 / ofp->arb_Vlen;
00627 VSCALE( ofp->arb_U, ofp->arb_U, ofp->arb_Ulen );
00628 VSCALE( ofp->arb_V, ofp->arb_V, ofp->arb_Vlen );
00629 }
00630
00631 pap->pa_npts[pap->pa_faces] = npts;
00632 pap->pa_faces++;
00633 }
00634 if( pap->pa_faces < 4 || pap->pa_faces > 6 ) {
00635 bu_log("arb(%s): only %d faces present\n",
00636 name, pap->pa_faces);
00637 return(-1);
00638 }
00639 return(0);
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 HIDDEN int
00653 rt_arb_setup(struct soltab *stp, struct rt_arb_internal *aip, struct rt_i *rtip, int uv_wanted)
00654 {
00655 register int i;
00656 struct prep_arb pa;
00657
00658 RT_ARB_CK_MAGIC(aip);
00659
00660 pa.pa_doopt = uv_wanted;
00661 pa.pa_tol_sq = rtip->rti_tol.dist_sq;
00662
00663 if( rt_arb_mk_planes( &pa, aip, stp->st_dp->d_namep ) < 0 ) {
00664 return(-2);
00665 }
00666
00667
00668
00669
00670
00671
00672
00673 {
00674 register struct arb_specific *arbp;
00675 if( (arbp = (struct arb_specific *)stp->st_specific) == 0 ) {
00676 arbp = (struct arb_specific *)bu_malloc(
00677 sizeof(struct arb_specific) +
00678 sizeof(struct aface) * (pa.pa_faces - 4),
00679 "arb_specific" );
00680 stp->st_specific = (genptr_t)arbp;
00681 }
00682 arbp->arb_nmfaces = pa.pa_faces;
00683 bcopy( (char *)pa.pa_face, (char *)arbp->arb_face,
00684 pa.pa_faces * sizeof(struct aface) );
00685
00686 if( uv_wanted ) {
00687 register struct oface *ofp;
00688
00689
00690
00691
00692
00693
00694 ofp = (struct oface *)bu_malloc(
00695 pa.pa_faces * sizeof(struct oface), "arb_opt");
00696 bcopy( (char *)pa.pa_opt, (char *)ofp,
00697 pa.pa_faces * sizeof(struct oface) );
00698 arbp->arb_opt = ofp;
00699 } else {
00700 arbp->arb_opt = (struct oface *)0;
00701 }
00702 }
00703
00704
00705
00706
00707
00708
00709
00710 {
00711 LOCAL vect_t work;
00712 register fastf_t f;
00713
00714 # include "noalias.h"
00715 for( i=0; i< 8; i++ ) {
00716 VMINMAX( stp->st_min, stp->st_max, aip->pt[i] );
00717 }
00718 VADD2SCALE( stp->st_center, stp->st_min, stp->st_max, 0.5 );
00719 VSUB2SCALE( work, stp->st_max, stp->st_min, 0.5 );
00720
00721 f = work[X];
00722 if( work[Y] > f ) f = work[Y];
00723 if( work[Z] > f ) f = work[Z];
00724 stp->st_aradius = f;
00725 stp->st_bradius = MAGNITUDE(work);
00726 }
00727 return(0);
00728 }
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739 int
00740 rt_arb_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
00741 {
00742 struct rt_arb_internal *aip;
00743
00744 aip = (struct rt_arb_internal *)ip->idb_ptr;
00745 RT_ARB_CK_MAGIC(aip);
00746
00747 return( rt_arb_setup( stp, aip, rtip, 0 ) );
00748 }
00749
00750
00751
00752
00753 void
00754 rt_arb_print(register const struct soltab *stp)
00755 {
00756 register struct arb_specific *arbp =
00757 (struct arb_specific *)stp->st_specific;
00758 register struct aface *afp;
00759 register int i;
00760
00761 if( arbp == (struct arb_specific *)0 ) {
00762 bu_log("arb(%s): no faces\n", stp->st_name);
00763 return;
00764 }
00765 bu_log("%d faces:\n", arbp->arb_nmfaces);
00766 for( i=0; i < arbp->arb_nmfaces; i++ ) {
00767 afp = &(arbp->arb_face[i]);
00768 VPRINT( "A", afp->A );
00769 HPRINT( "Peqn", afp->peqn );
00770 if( arbp->arb_opt ) {
00771 register struct oface *op;
00772 op = &(arbp->arb_opt[i]);
00773 VPRINT( "UVorig", op->arb_UVorig );
00774 VPRINT( "U", op->arb_U );
00775 VPRINT( "V", op->arb_V );
00776 bu_log( "Ulen = %g, Vlen = %g\n",
00777 op->arb_Ulen, op->arb_Vlen);
00778 }
00779 }
00780 }
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 int
00798 rt_arb_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
00799 {
00800 struct arb_specific *arbp = (struct arb_specific *)stp->st_specific;
00801 LOCAL int iplane, oplane;
00802 LOCAL fastf_t in, out;
00803 register struct aface *afp;
00804 register int j;
00805
00806 in = -INFINITY;
00807 out = INFINITY;
00808 iplane = oplane = -1;
00809
00810 if (RT_G_DEBUG & DEBUG_ARB8) {
00811 bu_log("\n\n------------\n arb: ray point %g %g %g -> %g %g %g\n",
00812 V3ARGS(rp->r_pt),
00813 V3ARGS(rp->r_dir));
00814 }
00815
00816
00817 for( afp = &arbp->arb_face[j=arbp->arb_nmfaces-1]; j >= 0; j--, afp-- ) {
00818 FAST fastf_t dn;
00819 FAST fastf_t dxbdn;
00820 FAST fastf_t s;
00821
00822
00823
00824 dxbdn = VDOT( afp->peqn, rp->r_pt ) - afp->peqn[3];
00825 dn = -VDOT( afp->peqn, rp->r_dir );
00826
00827 if (RT_G_DEBUG & DEBUG_ARB8) {
00828 HPRINT("arb: Plane Equation", afp->peqn);
00829 bu_log("arb: dn=%g dxbdn=%g s=%g\n", dn, dxbdn, dxbdn/dn);
00830 }
00831
00832 if( dn < -SQRT_SMALL_FASTF ) {
00833
00834 if( out > (s = dxbdn/dn) ) {
00835 out = s;
00836 oplane = j;
00837 }
00838 } else if ( dn > SQRT_SMALL_FASTF ) {
00839
00840 if( in < (s = dxbdn/dn) ) {
00841 in = s;
00842 iplane = j;
00843 }
00844 } else {
00845
00846
00847
00848
00849
00850 if( dxbdn > SQRT_SMALL_FASTF )
00851 return( 0 );
00852 }
00853 if( in > out )
00854 return( 0 );
00855 }
00856
00857 if( iplane == -1 || oplane == -1 ) {
00858 bu_log("rt_arb_shoot(%s): 1 hit => MISS\n",
00859 stp->st_name);
00860 return( 0 );
00861 }
00862 if( in >= out || out >= INFINITY )
00863 return( 0 );
00864
00865 {
00866 register struct seg *segp;
00867
00868 RT_GET_SEG( segp, ap->a_resource );
00869 segp->seg_stp = stp;
00870 segp->seg_in.hit_dist = in;
00871 segp->seg_in.hit_surfno = iplane;
00872
00873 segp->seg_out.hit_dist = out;
00874 segp->seg_out.hit_surfno = oplane;
00875 BU_LIST_INSERT( &(seghead->l), &(segp->l) );
00876 }
00877 return(2);
00878 }
00879
00880 #define SEG_MISS(SEG) (SEG).seg_stp=(struct soltab *) 0;
00881
00882
00883
00884
00885
00886 void
00887 rt_arb_vshot(struct soltab **stp, struct xray **rp, struct seg *segp, int n, struct application *ap)
00888
00889
00890
00891
00892
00893 {
00894 register int j, i;
00895 register struct arb_specific *arbp;
00896 FAST fastf_t dn;
00897 FAST fastf_t dxbdn;
00898 FAST fastf_t s;
00899
00900
00901 # include "noalias.h"
00902 for(i = 0; i < n; i++){
00903 segp[i].seg_stp = stp[i];
00904 segp[i].seg_in.hit_dist = -INFINITY;
00905 segp[i].seg_in.hit_surfno = -1;
00906 segp[i].seg_out.hit_dist = INFINITY;
00907 segp[i].seg_out.hit_surfno = -1;
00908
00909 }
00910
00911
00912 for(j = 0; j < 6; j++) {
00913
00914 # include "noalias.h"
00915 for(i = 0; i < n; i++) {
00916 if (stp[i] == 0) continue;
00917 if ( segp[i].seg_stp == 0 ) continue;
00918
00919 arbp= (struct arb_specific *) stp[i]->st_specific;
00920 if ( arbp->arb_nmfaces <= j )
00921 continue;
00922
00923 dxbdn = VDOT( arbp->arb_face[j].peqn, rp[i]->r_pt ) -
00924 arbp->arb_face[j].peqn[3];
00925 if( (dn = -VDOT( arbp->arb_face[j].peqn, rp[i]->r_dir )) <
00926 -SQRT_SMALL_FASTF ) {
00927
00928 if( segp[i].seg_out.hit_dist > (s = dxbdn/dn) ) {
00929 segp[i].seg_out.hit_dist = s;
00930 segp[i].seg_out.hit_surfno = j;
00931 }
00932 } else if ( dn > SQRT_SMALL_FASTF ) {
00933
00934 if( segp[i].seg_in.hit_dist < (s = dxbdn/dn) ) {
00935 segp[i].seg_in.hit_dist = s;
00936 segp[i].seg_in.hit_surfno = j;
00937 }
00938 } else {
00939
00940
00941 if( dxbdn > SQRT_SMALL_FASTF ) {
00942 SEG_MISS(segp[i]);
00943 }
00944 }
00945 if(segp[i].seg_in.hit_dist > segp[i].seg_out.hit_dist) {
00946 SEG_MISS(segp[i]);
00947 }
00948 }
00949 }
00950
00951
00952
00953
00954
00955
00956 # include "noalias.h"
00957 for(i = 0; i < n; i++){
00958 if (stp[i] == 0) continue;
00959 if ( segp[i].seg_stp == 0 ) continue;
00960
00961 if( segp[i].seg_in.hit_surfno == -1 ||
00962 segp[i].seg_out.hit_surfno == -1 ) {
00963 SEG_MISS(segp[i]);
00964 }
00965 else if(segp[i].seg_in.hit_dist >= segp[i].seg_out.hit_dist ||
00966 segp[i].seg_out.hit_dist >= INFINITY ) {
00967 SEG_MISS(segp[i]);
00968 }
00969 }
00970 }
00971
00972
00973
00974
00975
00976
00977 void
00978 rt_arb_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp)
00979 {
00980 register struct arb_specific *arbp =
00981 (struct arb_specific *)stp->st_specific;
00982 register int h;
00983
00984 VJOIN1( hitp->hit_point, rp->r_pt, hitp->hit_dist, rp->r_dir );
00985 h = hitp->hit_surfno;
00986 VMOVE( hitp->hit_normal, arbp->arb_face[h].peqn );
00987 }
00988
00989
00990
00991
00992
00993
00994
00995
00996 void
00997 rt_arb_curve(register struct curvature *cvp, register struct hit *hitp, struct soltab *stp)
00998 {
00999
01000 bn_vec_ortho( cvp->crv_pdir, hitp->hit_normal );
01001 cvp->crv_c1 = cvp->crv_c2 = 0;
01002 }
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012 void
01013 rt_arb_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
01014 {
01015 register struct arb_specific *arbp =
01016 (struct arb_specific *)stp->st_specific;
01017 struct oface *ofp;
01018 LOCAL vect_t P_A;
01019 LOCAL fastf_t r;
01020 LOCAL vect_t rev_dir;
01021 LOCAL fastf_t dot_N;
01022 LOCAL vect_t UV_dir;
01023 LOCAL fastf_t *norm;
01024 LOCAL fastf_t min_r_U, min_r_V;
01025
01026 if( arbp->arb_opt == (struct oface *)0 ) {
01027 register int ret = 0;
01028 struct rt_db_internal intern;
01029 struct rt_arb_internal *aip;
01030
01031 if( rt_db_get_internal( &intern, stp->st_dp, ap->a_rt_i->rti_dbip, stp->st_matp, ap->a_resource ) < 0 ) {
01032 bu_log("rt_arb_uv(%s) rt_db_get_internal failure\n",
01033 stp->st_name);
01034 return;
01035 }
01036 RT_CK_DB_INTERNAL( &intern );
01037 aip = (struct rt_arb_internal *)intern.idb_ptr;
01038 RT_ARB_CK_MAGIC(aip);
01039
01040
01041
01042
01043
01044
01045 bu_semaphore_acquire( RT_SEM_MODEL );
01046 if( arbp->arb_opt == (struct oface *)0 ) {
01047 ret = rt_arb_setup(stp, aip, ap->a_rt_i, 1 );
01048 }
01049 bu_semaphore_release( RT_SEM_MODEL );
01050
01051 rt_db_free_internal( &intern, ap->a_resource );
01052
01053 if( ret != 0 || arbp->arb_opt == (struct oface *)0 ) {
01054 bu_log("rt_arb_uv(%s) dyanmic setup failure st_specific=x%x, optp=x%x\n",
01055 stp->st_name,
01056 stp->st_specific, arbp->arb_opt );
01057 return;
01058 }
01059 if(RT_G_DEBUG&DEBUG_SOLIDS) rt_pr_soltab( stp );
01060 }
01061
01062 ofp = &arbp->arb_opt[hitp->hit_surfno];
01063
01064 VSUB2( P_A, hitp->hit_point, ofp->arb_UVorig );
01065
01066 uvp->uv_u = VDOT( P_A, ofp->arb_U );
01067 uvp->uv_v = 1.0 - VDOT( P_A, ofp->arb_V );
01068 if( uvp->uv_u < 0 || uvp->uv_v < 0 || uvp->uv_u > 1 || uvp->uv_v > 1 ) {
01069 bu_log("arb_uv: bad uv=%g,%g\n", uvp->uv_u, uvp->uv_v);
01070
01071 if( uvp->uv_u < 0 ) uvp->uv_u = (-uvp->uv_u);
01072 if( uvp->uv_v < 0 ) uvp->uv_v = (-uvp->uv_v);
01073 }
01074 r = ap->a_rbeam + ap->a_diverge * hitp->hit_dist;
01075 min_r_U = r * ofp->arb_Ulen;
01076 min_r_V = r * ofp->arb_Vlen;
01077 VREVERSE( rev_dir, ap->a_ray.r_dir )
01078 norm = &arbp->arb_face[hitp->hit_surfno].peqn[0];
01079 dot_N = VDOT( rev_dir, norm );
01080 VJOIN1( UV_dir, rev_dir, -dot_N, norm )
01081 VUNITIZE( UV_dir )
01082 uvp->uv_du = r * VDOT( UV_dir, ofp->arb_U ) / dot_N;
01083 uvp->uv_dv = r * VDOT( UV_dir, ofp->arb_V ) / dot_N;
01084 if( uvp->uv_du < 0.0 )
01085 uvp->uv_du = -uvp->uv_du;
01086 if( uvp->uv_du < min_r_U )
01087 uvp->uv_du = min_r_U;
01088 if( uvp->uv_dv < 0.0 )
01089 uvp->uv_dv = -uvp->uv_dv;
01090 if( uvp->uv_dv < min_r_V )
01091 uvp->uv_dv = min_r_V;
01092 }
01093
01094
01095
01096
01097 void
01098 rt_arb_free(register struct soltab *stp)
01099 {
01100 register struct arb_specific *arbp =
01101 (struct arb_specific *)stp->st_specific;
01102
01103 if( arbp->arb_opt )
01104 bu_free( (char *)arbp->arb_opt, "arb_opt" );
01105 bu_free( (char *)arbp, "arb_specific" );
01106 }
01107
01108 #define ARB_FACE( valp, a, b, c, d ) \
01109 RT_ADD_VLIST( vhead, valp[a], BN_VLIST_LINE_MOVE ); \
01110 RT_ADD_VLIST( vhead, valp[b], BN_VLIST_LINE_DRAW ); \
01111 RT_ADD_VLIST( vhead, valp[c], BN_VLIST_LINE_DRAW ); \
01112 RT_ADD_VLIST( vhead, valp[d], BN_VLIST_LINE_DRAW );
01113
01114
01115
01116
01117
01118
01119
01120
01121 int
01122 rt_arb_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
01123 {
01124 struct rt_arb_internal *aip;
01125
01126 RT_CK_DB_INTERNAL(ip);
01127 aip = (struct rt_arb_internal *)ip->idb_ptr;
01128 RT_ARB_CK_MAGIC(aip);
01129
01130 ARB_FACE( aip->pt, 0, 1, 2, 3 );
01131 ARB_FACE( aip->pt, 4, 0, 3, 7 );
01132 ARB_FACE( aip->pt, 5, 4, 7, 6 );
01133 ARB_FACE( aip->pt, 1, 5, 6, 2 );
01134 return(0);
01135 }
01136
01137
01138
01139
01140 int
01141 rt_arb_class(const struct soltab *stp, const fastf_t *min, const fastf_t *max, const struct bn_tol *tol)
01142 {
01143 register struct arb_specific *arbp =
01144 (struct arb_specific *)stp->st_specific;
01145 register int i;
01146
01147 if( arbp == (struct arb_specific *)0 ) {
01148 bu_log("arb(%s): no faces\n", stp->st_name);
01149 return RT_CLASSIFY_UNIMPLEMENTED;
01150 }
01151
01152 for( i=0; i<arbp->arb_nmfaces; i++ ) {
01153 if( bn_hlf_class( arbp->arb_face[i].peqn, min, max, tol ) ==
01154 BN_CLASSIFY_OUTSIDE )
01155 return RT_CLASSIFY_OUTSIDE;
01156 }
01157
01158
01159
01160 return RT_CLASSIFY_UNIMPLEMENTED;
01161 }
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177 int
01178 rt_arb_import(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
01179 {
01180 struct rt_arb_internal *aip;
01181 union record *rp;
01182 register int i;
01183 LOCAL vect_t work;
01184 LOCAL fastf_t vec[3*8];
01185
01186 BU_CK_EXTERNAL( ep );
01187 rp = (union record *)ep->ext_buf;
01188
01189 if( rp->u_id != ID_SOLID ) {
01190 bu_log("rt_arb_import: defective record, id=x%x\n", rp->u_id);
01191 return(-1);
01192 }
01193
01194 RT_CK_DB_INTERNAL( ip );
01195 ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
01196 ip->idb_type = ID_ARB8;
01197 ip->idb_meth = &rt_functab[ID_ARB8];
01198 ip->idb_ptr = bu_malloc( sizeof(struct rt_arb_internal), "rt_arb_internal");
01199 aip = (struct rt_arb_internal *)ip->idb_ptr;
01200 aip->magic = RT_ARB_INTERNAL_MAGIC;
01201
01202
01203 rt_fastf_float( vec, rp->s.s_values, 8 );
01204
01205
01206
01207
01208 MAT4X3PNT( aip->pt[0], mat, &vec[0] );
01209
01210 # include "noalias.h"
01211 for( i=1; i<8; i++ ) {
01212 VADD2( work, &vec[0*3], &vec[i*3] );
01213 MAT4X3PNT( aip->pt[i], mat, work );
01214 }
01215 return(0);
01216 }
01217
01218
01219
01220
01221 int
01222 rt_arb_export(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
01223 {
01224 struct rt_arb_internal *aip;
01225 union record *rec;
01226 register int i;
01227
01228 RT_CK_DB_INTERNAL(ip);
01229 if( ip->idb_type != ID_ARB8 ) return(-1);
01230 aip = (struct rt_arb_internal *)ip->idb_ptr;
01231 RT_ARB_CK_MAGIC(aip);
01232
01233 BU_CK_EXTERNAL(ep);
01234 ep->ext_nbytes = sizeof(union record);
01235 ep->ext_buf = (genptr_t)bu_calloc( 1, ep->ext_nbytes, "arb external");
01236 rec = (union record *)ep->ext_buf;
01237
01238 rec->s.s_id = ID_SOLID;
01239 rec->s.s_type = GENARB8;
01240
01241
01242 VSCALE( &rec->s.s_values[3*0], aip->pt[0], local2mm );
01243 for( i=1; i < 8; i++ ) {
01244 VSUB2SCALE( &rec->s.s_values[3*i],
01245 aip->pt[i], aip->pt[0], local2mm );
01246 }
01247 return(0);
01248 }
01249
01250
01251
01252
01253
01254
01255
01256 int
01257 rt_arb_import5(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
01258 {
01259 struct rt_arb_internal *aip;
01260 register int i;
01261 fastf_t vec[3*8];
01262
01263 BU_CK_EXTERNAL( ep );
01264 BU_ASSERT_LONG( ep->ext_nbytes, ==, SIZEOF_NETWORK_DOUBLE * 3*8);
01265 RT_CK_DB_INTERNAL( ip );
01266 ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
01267 ip->idb_type = ID_ARB8;
01268 ip->idb_meth = &rt_functab[ID_ARB8];
01269 ip->idb_ptr = bu_malloc( sizeof(struct rt_arb_internal), "rt_arb_internal");
01270
01271 aip = (struct rt_arb_internal *)ip->idb_ptr;
01272 aip->magic = RT_ARB_INTERNAL_MAGIC;
01273
01274
01275 ntohd( (unsigned char *)vec, ep->ext_buf, 8*3);
01276 for (i=0; i<8; i++) {
01277 MAT4X3PNT( aip->pt[i], mat, &vec[i*3]);
01278 }
01279 return 0;
01280 }
01281
01282
01283
01284 int
01285 rt_arb_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
01286 {
01287 struct rt_arb_internal *aip;
01288 fastf_t vec[3*8];
01289 register int i;
01290
01291 RT_CK_DB_INTERNAL(ip);
01292 if (ip->idb_type != ID_ARB8) return -1;
01293 aip = (struct rt_arb_internal *)ip->idb_ptr;
01294 RT_ARB_CK_MAGIC(aip);
01295
01296 BU_CK_EXTERNAL(ep);
01297 ep->ext_nbytes = SIZEOF_NETWORK_DOUBLE * 8 * 3;
01298 ep->ext_buf = (genptr_t)bu_malloc( ep->ext_nbytes, "arb external");
01299 for (i=0; i<8; i++) {
01300 VSCALE( &vec[i*3], aip->pt[i], local2mm );
01301 }
01302 htond( ep->ext_buf, (unsigned char *)vec, 8*3);
01303 return 0;
01304 }
01305
01306
01307
01308
01309
01310
01311
01312 int
01313 rt_arb_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
01314 {
01315 register struct rt_arb_internal *aip = (struct rt_arb_internal *)ip->idb_ptr;
01316 char buf[256];
01317 int i;
01318 int arb_type;
01319 struct bn_tol tmp_tol;
01320
01321 RT_ARB_CK_MAGIC(aip);
01322
01323 tmp_tol.magic = BN_TOL_MAGIC;
01324 tmp_tol.dist = 0.0001;
01325 tmp_tol.dist_sq = tmp_tol.dist * tmp_tol.dist;
01326 tmp_tol.perp = 1e-5;
01327 tmp_tol.para = 1 - tmp_tol.perp;
01328
01329 arb_type = rt_arb_std_type( ip, &tmp_tol );
01330
01331 if( !arb_type ) {
01332
01333 bu_vls_strcat( str, "ARB8\n");
01334
01335
01336 sprintf( buf, "\t1 (%g, %g, %g)\n",
01337 INTCLAMP(aip->pt[0][X] * mm2local),
01338 INTCLAMP(aip->pt[0][Y] * mm2local),
01339 INTCLAMP(aip->pt[0][Z] * mm2local) );
01340 bu_vls_strcat( str, buf );
01341
01342 if( !verbose ) return(0);
01343
01344 for( i=1; i < 8; i++ ) {
01345 sprintf( buf, "\t%d (%g, %g, %g)\n", i+1,
01346 INTCLAMP(aip->pt[i][X] * mm2local),
01347 INTCLAMP(aip->pt[i][Y] * mm2local),
01348 INTCLAMP(aip->pt[i][Z] * mm2local) );
01349 bu_vls_strcat( str, buf );
01350 }
01351 } else {
01352 sprintf( buf, "ARB%d\n", arb_type );
01353 bu_vls_strcat( str, buf );
01354 switch( arb_type ) {
01355 case ARB8:
01356 for( i=0 ; i<8 ; i++ ) {
01357 sprintf( buf, "\t%d (%g, %g, %g)\n", i+1,
01358 INTCLAMP(aip->pt[i][X] * mm2local),
01359 INTCLAMP(aip->pt[i][Y] * mm2local),
01360 INTCLAMP(aip->pt[i][Z] * mm2local) );
01361 bu_vls_strcat( str, buf );
01362 }
01363 break;
01364 case ARB7:
01365 for( i=0 ; i<7 ; i++ ) {
01366 sprintf( buf, "\t%d (%g, %g, %g)\n", i+1,
01367 INTCLAMP(aip->pt[i][X] * mm2local),
01368 INTCLAMP(aip->pt[i][Y] * mm2local),
01369 INTCLAMP(aip->pt[i][Z] * mm2local) );
01370 bu_vls_strcat( str, buf );
01371 }
01372 break;
01373 case ARB6:
01374 for( i=0 ; i<5 ; i++ ) {
01375 sprintf( buf, "\t%d (%g, %g, %g)\n", i+1,
01376 INTCLAMP(aip->pt[i][X] * mm2local),
01377 INTCLAMP(aip->pt[i][Y] * mm2local),
01378 INTCLAMP(aip->pt[i][Z] * mm2local) );
01379 bu_vls_strcat( str, buf );
01380 }
01381 sprintf( buf, "\t6 (%g, %g, %g)\n",
01382 INTCLAMP(aip->pt[6][X] * mm2local),
01383 INTCLAMP(aip->pt[6][Y] * mm2local),
01384 INTCLAMP(aip->pt[6][Z] * mm2local) );
01385 bu_vls_strcat( str, buf );
01386 break;
01387 case ARB5:
01388 for( i=0 ; i<5 ; i++ ) {
01389 sprintf( buf, "\t%d (%g, %g, %g)\n", i+1,
01390 INTCLAMP(aip->pt[i][X] * mm2local),
01391 INTCLAMP(aip->pt[i][Y] * mm2local),
01392 INTCLAMP(aip->pt[i][Z] * mm2local) );
01393 bu_vls_strcat( str, buf );
01394 }
01395 break;
01396 case ARB4:
01397 for( i=0 ; i<3 ; i++ ) {
01398 sprintf( buf, "\t%d (%g, %g, %g)\n", i+1,
01399 INTCLAMP(aip->pt[i][X] * mm2local),
01400 INTCLAMP(aip->pt[i][Y] * mm2local),
01401 INTCLAMP(aip->pt[i][Z] * mm2local) );
01402 bu_vls_strcat( str, buf );
01403 }
01404 sprintf( buf, "\t4 (%g, %g, %g)\n",
01405 INTCLAMP(aip->pt[4][X] * mm2local),
01406 INTCLAMP(aip->pt[4][Y] * mm2local),
01407 INTCLAMP(aip->pt[4][Z] * mm2local) );
01408 bu_vls_strcat( str, buf );
01409 break;
01410 }
01411 }
01412 return(0);
01413 }
01414
01415
01416
01417
01418
01419
01420 void
01421 rt_arb_ifree(struct rt_db_internal *ip)
01422 {
01423 RT_CK_DB_INTERNAL(ip);
01424 bu_free( ip->idb_ptr, "arb ifree" );
01425 ip->idb_ptr = (genptr_t)NULL;
01426 }
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439 int
01440 rt_arb_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
01441 {
01442 LOCAL struct rt_arb_internal *aip;
01443 struct shell *s;
01444 struct prep_arb pa;
01445 register int i;
01446 struct faceuse *fu[6];
01447 struct vertex *verts[8];
01448 struct vertex **vertp[4];
01449
01450 RT_CK_DB_INTERNAL(ip);
01451 aip = (struct rt_arb_internal *)ip->idb_ptr;
01452 RT_ARB_CK_MAGIC(aip);
01453
01454 bzero( (char *)&pa, sizeof(pa) );
01455 pa.pa_doopt = 0;
01456 pa.pa_tol_sq = tol->dist_sq;
01457 if( rt_arb_mk_planes( &pa, aip, "(tess)" ) < 0 ) return(-2);
01458
01459 for( i=0; i<8; i++ ) verts[i] = (struct vertex *)0;
01460
01461 *r = nmg_mrsv( m );
01462 s = BU_LIST_FIRST(shell, &(*r)->s_hd);
01463
01464
01465 for( i=0; i < pa.pa_faces; i++ ) {
01466 if( pa.pa_clockwise[i] != 0 ) {
01467
01468 vertp[0] = &verts[pa.pa_pindex[0][i]];
01469 vertp[1] = &verts[pa.pa_pindex[1][i]];
01470 vertp[2] = &verts[pa.pa_pindex[2][i]];
01471 if( pa.pa_npts[i] > 3 ) {
01472 vertp[3] = &verts[pa.pa_pindex[3][i]];
01473 }
01474 } else {
01475 register struct vertex ***vertpp = vertp;
01476
01477 if( pa.pa_npts[i] > 3 ) {
01478 *vertpp++ = &verts[pa.pa_pindex[3][i]];
01479 }
01480 *vertpp++ = &verts[pa.pa_pindex[2][i]];
01481 *vertpp++ = &verts[pa.pa_pindex[1][i]];
01482 *vertpp++ = &verts[pa.pa_pindex[0][i]];
01483 }
01484 if( RT_G_DEBUG & DEBUG_ARB8 ) {
01485 bu_log("face %d, npts=%d, verts %d %d %d %d\n",
01486 i, pa.pa_npts[i],
01487 pa.pa_pindex[0][i], pa.pa_pindex[1][i],
01488 pa.pa_pindex[2][i], pa.pa_pindex[3][i] );
01489 }
01490 if( (fu[i] = nmg_cmface( s, vertp, pa.pa_npts[i] )) == 0 ) {
01491 bu_log("rt_arb_tess(%s): nmg_cmface() fail on face %d\n", i);
01492 continue;
01493 }
01494 }
01495
01496
01497 for( i=0; i<8; i++ )
01498 if(verts[i]) nmg_vertex_gv(verts[i], aip->pt[i]);
01499
01500
01501 for( i=0; i < pa.pa_faces; i++ ) {
01502 #if 1
01503
01504 nmg_face_g( fu[i], pa.pa_face[i].peqn );
01505 #else
01506
01507 if( nmg_fu_planeeqn( fu[i], tol ) < 0 )
01508 return -1;
01509 #endif
01510 }
01511
01512
01513 (void)nmg_mark_edges_real( &s->l.magic );
01514
01515
01516 nmg_region_a( *r, tol );
01517
01518
01519 nmg_make_faces_within_tol( s, tol );
01520
01521 return(0);
01522 }
01523
01524 static const fastf_t rt_arb_uvw[5*3] = {
01525 0, 0, 0,
01526 1, 0, 0,
01527 1, 1, 0,
01528 0, 1, 0,
01529 0, 0, 0
01530 };
01531 static const int rt_arb_vert_index_scramble[4] = { 0, 1, 3, 2 };
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548 int
01549 rt_arb_tnurb(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct bn_tol *tol)
01550 {
01551 LOCAL struct rt_arb_internal *aip;
01552 struct shell *s;
01553 struct prep_arb pa;
01554 register int i;
01555 struct faceuse *fu[6];
01556 struct vertex *verts[8];
01557 struct vertex **vertp[4];
01558 struct edgeuse *eu;
01559 struct loopuse *lu;
01560
01561 RT_CK_DB_INTERNAL(ip);
01562 aip = (struct rt_arb_internal *)ip->idb_ptr;
01563 RT_ARB_CK_MAGIC(aip);
01564
01565 bzero( (char *)&pa, sizeof(pa) );
01566 pa.pa_doopt = 0;
01567 pa.pa_tol_sq = tol->dist_sq;
01568 if( rt_arb_mk_planes( &pa, aip, "(tnurb)" ) < 0 ) return(-2);
01569
01570 for( i=0; i<8; i++ ) verts[i] = (struct vertex *)0;
01571
01572 *r = nmg_mrsv( m );
01573 s = BU_LIST_FIRST(shell, &(*r)->s_hd);
01574
01575
01576 for( i=0; i < pa.pa_faces; i++ ) {
01577 if( pa.pa_clockwise[i] != 0 ) {
01578
01579 vertp[0] = &verts[pa.pa_pindex[0][i]];
01580 vertp[1] = &verts[pa.pa_pindex[1][i]];
01581 vertp[2] = &verts[pa.pa_pindex[2][i]];
01582 if( pa.pa_npts[i] > 3 ) {
01583 vertp[3] = &verts[pa.pa_pindex[3][i]];
01584 }
01585 } else {
01586 register struct vertex ***vertpp = vertp;
01587
01588 if( pa.pa_npts[i] > 3 ) {
01589 *vertpp++ = &verts[pa.pa_pindex[3][i]];
01590 }
01591 *vertpp++ = &verts[pa.pa_pindex[2][i]];
01592 *vertpp++ = &verts[pa.pa_pindex[1][i]];
01593 *vertpp++ = &verts[pa.pa_pindex[0][i]];
01594 }
01595 if( RT_G_DEBUG & DEBUG_ARB8 ) {
01596 bu_log("face %d, npts=%d, verts %d %d %d %d\n",
01597 i, pa.pa_npts[i],
01598 pa.pa_pindex[0][i], pa.pa_pindex[1][i],
01599 pa.pa_pindex[2][i], pa.pa_pindex[3][i] );
01600 }
01601
01602
01603 if( (fu[i] = nmg_cmface( s, vertp, pa.pa_npts[i] )) == 0 ) {
01604 bu_log("rt_arb_tnurb(%s): nmg_cmface() fail on face %d\n", i);
01605 continue;
01606 }
01607
01608 lu = BU_LIST_FIRST( loopuse, &fu[i]->lu_hd );
01609 NMG_CK_LOOPUSE(lu);
01610 eu = BU_LIST_FIRST( edgeuse, &lu->down_hd );
01611 NMG_CK_EDGEUSE(eu);
01612
01613
01614 nmg_vertexuse_a_cnurb( eu->vu_p, &rt_arb_uvw[0*3] );
01615 nmg_vertexuse_a_cnurb( eu->eumate_p->vu_p, &rt_arb_uvw[1*3] );
01616 eu = BU_LIST_NEXT( edgeuse, &eu->l );
01617
01618 nmg_vertexuse_a_cnurb( eu->vu_p, &rt_arb_uvw[1*3] );
01619 nmg_vertexuse_a_cnurb( eu->eumate_p->vu_p, &rt_arb_uvw[2*3] );
01620 eu = BU_LIST_NEXT( edgeuse, &eu->l );
01621
01622 nmg_vertexuse_a_cnurb( eu->vu_p, &rt_arb_uvw[2*3] );
01623 if( pa.pa_npts[i] > 3 ) {
01624 nmg_vertexuse_a_cnurb( eu->eumate_p->vu_p, &rt_arb_uvw[3*3] );
01625
01626 eu = BU_LIST_NEXT( edgeuse, &eu->l );
01627 nmg_vertexuse_a_cnurb( eu->vu_p, &rt_arb_uvw[3*3] );
01628 }
01629
01630 nmg_vertexuse_a_cnurb( eu->eumate_p->vu_p, &rt_arb_uvw[0*3] );
01631 }
01632
01633
01634 for( i=0; i<8; i++ )
01635 if(verts[i]) nmg_vertex_gv(verts[i], aip->pt[i]);
01636
01637
01638 for( i=0; i < pa.pa_faces; i++ ) {
01639 struct face_g_snurb *fg;
01640 int j;
01641
01642
01643 nmg_face_g_snurb( fu[i],
01644 2, 2,
01645 4, 4,
01646 NULL, NULL,
01647 2, 2,
01648 RT_NURB_MAKE_PT_TYPE( 3, RT_NURB_PT_XYZ, RT_NURB_PT_NONRAT ),
01649 NULL );
01650
01651 fg = fu[i]->f_p->g.snurb_p;
01652 NMG_CK_FACE_G_SNURB(fg);
01653
01654
01655 fg->u.knots[0] = fg->u.knots[1] = 0;
01656 fg->u.knots[2] = fg->u.knots[3] = 1;
01657 fg->v.knots[0] = fg->v.knots[1] = 0;
01658 fg->v.knots[2] = fg->v.knots[3] = 1;
01659
01660
01661 lu = BU_LIST_FIRST( loopuse, &fu[i]->lu_hd );
01662 NMG_CK_LOOPUSE(lu);
01663 eu = BU_LIST_FIRST( edgeuse, &lu->down_hd );
01664 NMG_CK_EDGEUSE(eu);
01665
01666
01667 for( j=0; j < pa.pa_npts[i]; j++ ) {
01668 VMOVE( &fg->ctl_points[rt_arb_vert_index_scramble[j]*3],
01669 eu->vu_p->v_p->vg_p->coord );
01670
01671
01672 nmg_edge_g_cnurb_plinear(eu);
01673 eu = BU_LIST_NEXT( edgeuse, &eu->l );
01674 }
01675 if( pa.pa_npts[i] == 3 ) {
01676 vect_t c_b;
01677
01678
01679
01680
01681 VSUB2( c_b,
01682 &fg->ctl_points[rt_arb_vert_index_scramble[2]*3],
01683 &fg->ctl_points[rt_arb_vert_index_scramble[1]*3] );
01684 VADD2( &fg->ctl_points[rt_arb_vert_index_scramble[3]*3],
01685 &fg->ctl_points[rt_arb_vert_index_scramble[0]*3],
01686 c_b );
01687 }
01688 }
01689
01690
01691
01692 (void)nmg_mark_edges_real( &s->l.magic );
01693
01694
01695 nmg_region_a( *r, tol );
01696 return(0);
01697 }
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708 int
01709 rt_arb_calc_points(
01710 struct rt_arb_internal *arb,
01711 int cgtype,
01712 const plane_t planes[6],
01713 const struct bn_tol *tol)
01714 {
01715 int i;
01716 point_t pt[8];
01717
01718 RT_ARB_CK_MAGIC(arb);
01719
01720
01721 for(i=0; i<8; i++){
01722 if( rt_arb_3face_intersect( pt[i], planes, cgtype, i*3 ) < 0 ) {
01723 bu_log("rt_arb_calc_points: Intersection of planes fails %d\n", i);
01724 return -1;
01725 }
01726 }
01727
01728
01729 for( i=0; i<8; i++ ) {
01730 VMOVE( arb->pt[i], pt[i] );
01731 }
01732 return 0;
01733 }
01734
01735
01736 const int rt_arb_planes[5][24] = {
01737 {0,1,3, 0,1,2, 0,2,3, 0,1,3, 1,2,3, 1,2,3, 1,2,3, 1,2,3},
01738 {0,1,4, 0,1,2, 0,2,3, 0,3,4, 1,2,4, 1,2,4, 1,2,4, 1,2,4},
01739 {0,2,3, 0,1,3, 0,1,4, 0,2,4, 1,2,3, 1,2,3, 1,2,4, 1,2,4},
01740 {0,2,4, 0,3,4, 0,3,5, 0,2,5, 1,4,5, 1,3,4, 1,3,5, 1,2,4},
01741 {0,2,4, 0,3,4, 0,3,5, 0,2,5, 1,2,4, 1,3,4, 1,3,5, 1,2,5},
01742 };
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753 int
01754 rt_arb_3face_intersect(
01755 point_t point,
01756 const plane_t planes[6],
01757 int type,
01758 int loc)
01759 {
01760 int j;
01761 int i1, i2, i3;
01762
01763 j = type - 4;
01764
01765 i1 = rt_arb_planes[j][loc];
01766 i2 = rt_arb_planes[j][loc+1];
01767 i3 = rt_arb_planes[j][loc+2];
01768
01769 return bn_mkpoint_3planes( point, planes[i1], planes[i2], planes[i3] );
01770 }
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786 int
01787 rt_arb_calc_planes(Tcl_Interp *interp,
01788 struct rt_arb_internal *arb,
01789 int type,
01790 plane_t planes[6],
01791 const struct bn_tol *tol)
01792 {
01793 register int i, p1, p2, p3;
01794
01795 RT_ARB_CK_MAGIC(arb);
01796 BN_CK_TOL(tol);
01797
01798 type -= 4;
01799
01800 for (i=0; i<6; i++) {
01801 if(rt_arb_faces[type][i*4] == -1)
01802 break;
01803
01804 p1 = rt_arb_faces[type][i*4];
01805 p2 = rt_arb_faces[type][i*4+1];
01806 p3 = rt_arb_faces[type][i*4+2];
01807
01808 if (bn_mk_plane_3pts(planes[i],
01809 arb->pt[p1],
01810 arb->pt[p2],
01811 arb->pt[p3],
01812 tol) < 0) {
01813 struct bu_vls tmp_vls;
01814
01815 bu_vls_init(&tmp_vls);
01816 bu_vls_printf(&tmp_vls, "%d %d%d%d%d (bad face)\n",
01817 i+1, p1+1, p2+1, p3+1, rt_arb_faces[type][i*4+3]+1);
01818 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
01819 return -1;
01820 }
01821 }
01822
01823 return 0;
01824 }
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836 int
01837 rt_arb_move_edge(Tcl_Interp *interp,
01838 struct rt_arb_internal *arb,
01839 vect_t thru,
01840 int bp1,
01841 int bp2,
01842 int end1,
01843 int end2,
01844 const vect_t dir,
01845 plane_t planes[6],
01846 const struct bn_tol *tol)
01847 {
01848 fastf_t t1, t2;
01849
01850 if (bn_isect_line3_plane(&t1, thru, dir, planes[bp1], tol) < 0 ||
01851 bn_isect_line3_plane(&t2, thru, dir, planes[bp2], tol) < 0) {
01852 Tcl_AppendResult(interp, "edge (direction) parallel to face normal\n", (char *)NULL);
01853 return (1);
01854 }
01855
01856 RT_ARB_CK_MAGIC(arb);
01857
01858 VJOIN1(arb->pt[end1], thru, t1, dir);
01859 VJOIN1(arb->pt[end2], thru, t2, dir);
01860
01861 return(0);
01862 }
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921 short earb8[12][18] = {
01922 {0,1, 2,3, 0,0,1,2, 4,0,1,4, -1,0,0,0, 3,5},
01923 {1,2, 4,5, 0,0,1,2, 3,1,2,5, -1,0,0,0, 3,6},
01924 {2,3, 3,2, 0,0,2,3, 5,2,3,6, -1,0,0,0, 1,7},
01925 {0,3, 4,5, 0,0,1,3, 2,0,3,4, -1,0,0,0, 2,7},
01926 {0,4, 0,1, 2,0,4,3, 4,0,1,4, -1,0,0,0, 7,5},
01927 {1,5, 0,1, 4,0,1,5, 3,1,2,5, -1,0,0,0, 4,6},
01928 {4,5, 2,3, 4,0,5,4, 1,4,5,6, -1,0,0,0, 1,7},
01929 {5,6, 4,5, 3,1,5,6, 1,4,5,6, -1,0,0,0, 2,7},
01930 {6,7, 3,2, 5,2,7,6, 1,4,6,7, -1,0,0,0, 3,4},
01931 {4,7, 4,5, 2,0,7,4, 1,4,5,7, -1,0,0,0, 3,6},
01932 {2,6, 0,1, 3,1,2,6, 5,2,3,6, -1,0,0,0, 5,7},
01933 {3,7, 0,1, 2,0,3,7, 5,2,3,7, -1,0,0,0, 4,6},
01934 };
01935
01936
01937 short earb7[12][18] = {
01938 {0,1, 2,3, 0,0,1,2, 4,0,1,4, -1,0,0,0, 3,5},
01939 {1,2, 4,5, 0,0,1,2, 3,1,2,5, -1,0,0,0, 3,6},
01940 {2,3, 3,2, 0,0,2,3, 5,2,3,6, -1,0,0,0, 1,4},
01941 {0,3, 4,5, 0,0,1,3, 2,0,3,4, -1,0,0,0, 2,-1},
01942 {0,4, 0,5, 4,0,5,4, 2,0,3,4, 1,4,5,6, 1,-1},
01943 {1,5, 0,1, 4,0,1,5, 3,1,2,5, -1,0,0,0, 4,6},
01944 {4,5, 5,3, 2,0,3,4, 4,0,5,4, 1,4,5,6, 1,-1},
01945 {5,6, 4,5, 3,1,6,5, 1,4,5,6, -1,0,0,0, 2, -1},
01946 {2,6, 0,1, 5,2,3,6, 3,1,2,6, -1,0,0,0, 4,5},
01947 {4,6, 4,3, 2,0,3,4, 5,3,4,6, 1,4,5,6, 2,-1},
01948 {3,4, 0,1, 4,0,1,4, 2,0,3,4, 5,2,3,4, 5,6},
01949 {-1,-1, -1,-1, 5,2,3,4, 4,0,1,4, 8,2,1,-1, 6,5},
01950 };
01951
01952
01953 short earb6[10][18] = {
01954 {0,1, 2,1, 3,0,1,4, 0,0,1,2, -1,0,0,0, 3,-1},
01955 {1,2, 3,4, 1,1,2,5, 0,0,1,2, -1,0,0,0, 3,4},
01956 {2,3, 1,2, 4,2,3,5, 0,0,2,3, -1,0,0,0, 1,-1},
01957 {0,3, 3,4, 2,0,3,5, 0,0,1,3, -1,0,0,0, 4,2},
01958 {0,4, 0,1, 3,0,1,4, 2,0,3,4, -1,0,0,0, 6,-1},
01959 {1,4, 0,2, 3,0,1,4, 1,1,2,4, -1,0,0,0, 6,-1},
01960 {2,6, 0,2, 4,6,2,3, 1,1,2,6, -1,0,0,0, 4,-1},
01961 {3,6, 0,1, 4,6,2,3, 2,0,3,6, -1,0,0,0, 4,-1},
01962 {-1,-1, -1,-1, 2,0,3,4, 1,1,2,4, 3,0,1,4, 6,-1},
01963 {-1,-1, -1,-1, 2,0,3,6, 1,1,2,6, 4,2,3,6, 4,-1},
01964 };
01965
01966
01967 short earb5[9][18] = {
01968 {0,1, 4,2, 0,0,1,2, 1,0,1,4, -1,0,0,0, 3,-1},
01969 {1,2, 1,3, 0,0,1,2, 2,1,2,4, -1,0,0,0, 3,-1},
01970 {2,3, 2,4, 0,0,2,3, 3,2,3,4, -1,0,0,0, 1,-1},
01971 {0,3, 1,3, 0,0,1,3, 4,0,3,4, -1,0,0,0, 2,-1},
01972 {0,4, 0,2, 9,0,0,0, 9,0,0,0, 9,0,0,0, -1,-1},
01973 {1,4, 0,3, 9,0,0,0, 9,0,0,0, 9,0,0,0, -1,-1},
01974 {2,4, 0,4, 9,0,0,0, 9,0,0,0, 9,0,0,0, -1,-1},
01975 {3,4, 0,1, 9,0,0,0, 9,0,0,0, 9,0,0,0, -1,-1},
01976 {-1,-1, -1,-1, 9,0,0,0, 9,0,0,0, 9,0,0,0, -1,-1},
01977 };
01978
01979
01980 short earb4[5][18] = {
01981 {-1,-1, -1,-1, 9,0,0,0, 9,0,0,0, 9,0,0,0, -1,-1},
01982 {-1,-1, -1,-1, 9,0,0,0, 9,0,0,0, 9,0,0,0, -1,-1},
01983 {-1,-1, -1,-1, 9,0,0,0, 9,0,0,0, 9,0,0,0, -1,-1},
01984 {-1,-1, -1,-1, 9,0,0,0, 9,0,0,0, 9,0,0,0, -1,-1},
01985 {-1,-1, -1,-1, 9,0,0,0, 9,0,0,0, 9,0,0,0, -1,-1},
01986 };
01987
01988 #define RT_ARB_EDIT_EDGE 0
01989 #define RT_ARB_EDIT_POINT 1
01990 #define RT_ARB7_MOVE_POINT_5 11
01991 #define RT_ARB6_MOVE_POINT_5 8
01992 #define RT_ARB6_MOVE_POINT_6 9
01993 #define RT_ARB5_MOVE_POINT_5 8
01994 #define RT_ARB4_MOVE_POINT_4 3
01995
01996 int
01997 rt_arb_edit(Tcl_Interp *interp,
01998 struct rt_arb_internal *arb,
01999 int arb_type,
02000 int edit_type,
02001 vect_t pos_model,
02002 plane_t planes[6],
02003 const struct bn_tol *tol)
02004 {
02005 int pt1, pt2, bp1, bp2, newp, p1, p2, p3;
02006 short *edptr;
02007 short *final;
02008 int i;
02009 const int *iptr;
02010 int edit_class = RT_ARB_EDIT_EDGE;
02011
02012 RT_ARB_CK_MAGIC(arb);
02013
02014
02015 switch (arb_type) {
02016 case ARB4:
02017 edptr = &earb4[edit_type][0];
02018 final = &earb4[edit_type][16];
02019
02020 if (edit_type == RT_ARB4_MOVE_POINT_4)
02021 edit_type = 4;
02022
02023 edit_class = RT_ARB_EDIT_POINT;
02024
02025 break;
02026 case ARB5:
02027 edptr = &earb5[edit_type][0];
02028 final = &earb5[edit_type][16];
02029
02030 if (edit_type == RT_ARB5_MOVE_POINT_5) {
02031 edit_class = RT_ARB_EDIT_POINT;
02032 edit_type = 4;
02033 }
02034
02035 if (edit_class == RT_ARB_EDIT_POINT) {
02036 edptr = &earb5[8][0];
02037 final = &earb5[8][16];
02038 }
02039
02040 break;
02041 case ARB6:
02042 edptr = &earb6[edit_type][0];
02043 final = &earb6[edit_type][16];
02044
02045 if (edit_type == RT_ARB6_MOVE_POINT_5) {
02046 edit_class = RT_ARB_EDIT_POINT;
02047 edit_type = 4;
02048 } else if (edit_type == RT_ARB6_MOVE_POINT_6) {
02049 edit_class = RT_ARB_EDIT_POINT;
02050 edit_type = 6;
02051 }
02052
02053 if (edit_class == RT_ARB_EDIT_POINT) {
02054 i = 9;
02055 if(edit_type == 4)
02056 i = 8;
02057 edptr = &earb6[i][0];
02058 final = &earb6[i][16];
02059 }
02060
02061 break;
02062 case ARB7:
02063 edptr = &earb7[edit_type][0];
02064 final = &earb7[edit_type][16];
02065
02066 if (edit_type == RT_ARB7_MOVE_POINT_5) {
02067 edit_class = RT_ARB_EDIT_POINT;
02068 edit_type = 4;
02069 }
02070
02071 if (edit_class == RT_ARB_EDIT_POINT) {
02072 edptr = &earb7[11][0];
02073 final = &earb7[11][16];
02074 }
02075
02076 break;
02077 case ARB8:
02078 edptr = &earb8[edit_type][0];
02079 final = &earb8[edit_type][16];
02080
02081 break;
02082 default:
02083 Tcl_AppendResult(interp, "rt_arb_edit: unknown ARB type\n", (char *)NULL);
02084
02085 return(1);
02086 }
02087
02088
02089 if (edit_class == RT_ARB_EDIT_POINT) {
02090
02091 VMOVE(arb->pt[edit_type] , pos_model);
02092 edptr += 4;
02093 } else if (edit_class == RT_ARB_EDIT_EDGE) {
02094 vect_t edge_dir;
02095
02096
02097 pt1 = *edptr++;
02098 pt2 = *edptr++;
02099
02100
02101 VSUB2(edge_dir, arb->pt[pt2], arb->pt[pt1]);
02102
02103 if (MAGNITUDE(edge_dir) == 0.0)
02104 goto err;
02105
02106
02107 bp1 = *edptr++;
02108 bp2 = *edptr++;
02109
02110
02111 if (rt_arb_move_edge(interp, arb, pos_model, bp1, bp2, pt1, pt2,
02112 edge_dir, planes, tol))
02113 goto err;
02114 }
02115
02116
02117
02118 newp = *edptr++;
02119
02120 if (newp == 9)
02121 if (rt_arb_calc_planes(interp, arb, arb_type, planes, tol))
02122 goto err;
02123
02124 if (newp >= 0 && newp < 6) {
02125 for (i=0; i<3; i++) {
02126
02127 p1 = *edptr++;
02128 p2 = *edptr++;
02129 p3 = *edptr++;
02130
02131 if (bn_mk_plane_3pts(planes[newp], arb->pt[p1], arb->pt[p2],
02132 arb->pt[p3], tol))
02133 goto err;
02134
02135
02136 if ((newp = *edptr++) == -1 || newp == 8)
02137 break;
02138 }
02139 }
02140
02141 if (newp == 8) {
02142
02143 for (i=0; i<3; i++) {
02144 if ((newp = *edptr++) == -1)
02145 break;
02146
02147 iptr = &rt_arb_faces[arb_type-4][4*newp];
02148 p1 = *iptr++;
02149 p2 = *iptr++;
02150 p3 = *iptr++;
02151
02152 if (bn_mk_plane_3pts(planes[newp], arb->pt[p1], arb->pt[p2],
02153 arb->pt[p3], tol))
02154 goto err;
02155 }
02156 }
02157
02158
02159
02160
02161 edptr = final;
02162 for (i=0; i<2; i++) {
02163 if ((p1 = *edptr++) == -1)
02164 break;
02165
02166
02167
02168 if (rt_arb_3face_intersect(arb->pt[p1], (const plane_t *)planes, arb_type, p1*3))
02169 goto err;
02170 }
02171
02172
02173
02174
02175 if (arb_type == ARB7 && edit_class == RT_ARB_EDIT_POINT) {
02176 if (bn_mk_plane_3pts( planes[2], arb->pt[4], arb->pt[5], arb->pt[6], tol))
02177 goto err;
02178 }
02179
02180
02181 switch (arb_type) {
02182 case ARB8:
02183 break;
02184 case ARB7:
02185 VMOVE(arb->pt[7], arb->pt[4]);
02186 break;
02187 case ARB6:
02188 VMOVE(arb->pt[5], arb->pt[4]);
02189 VMOVE(arb->pt[7], arb->pt[6]);
02190 break;
02191 case ARB5:
02192 for (i=5; i<8; i++)
02193 VMOVE(arb->pt[i], arb->pt[4]);
02194 break;
02195 case ARB4:
02196 VMOVE(arb->pt[3] , arb->pt[0]);
02197 for(i=5; i<8; i++)
02198 VMOVE(arb->pt[i], arb->pt[4])
02199 break;
02200 }
02201
02202 return(0);
02203
02204 err:
02205
02206 {
02207 struct bu_vls tmp_vls;
02208
02209 bu_vls_init(&tmp_vls);
02210 bu_vls_printf(&tmp_vls, "cannot move edge: %d%d\n", pt1+1,pt2+1);
02211 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
02212 bu_vls_free(&tmp_vls);
02213 }
02214
02215 return(1);
02216 }
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227