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 #ifndef lint
00044 static const char RCSsubmodel[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/g_submodel.c,v 14.14 2006/09/16 02:04:24 lbutler Exp $ (BRL)";
00045 #endif
00046
00047 #include "common.h"
00048
00049 #include <stddef.h>
00050 #include <stdio.h>
00051 #include <math.h>
00052 #include <string.h>
00053
00054 #include "machine.h"
00055 #include "vmath.h"
00056 #include "db.h"
00057 #include "nmg.h"
00058 #include "raytrace.h"
00059 #include "rtgeom.h"
00060
00061 #define RT_SUBMODEL_O(m) bu_offsetof(struct rt_submodel_internal, m)
00062
00063 const struct bu_structparse rt_submodel_parse[] = {
00064 {"%S", 1, "file", RT_SUBMODEL_O(file), BU_STRUCTPARSE_FUNC_NULL },
00065 {"%S", 1, "treetop", RT_SUBMODEL_O(treetop), BU_STRUCTPARSE_FUNC_NULL },
00066 {"%d", 1, "meth", RT_SUBMODEL_O(meth), BU_STRUCTPARSE_FUNC_NULL },
00067 {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL }
00068 };
00069
00070
00071 struct submodel_specific {
00072 long magic;
00073 mat_t subm2m;
00074 mat_t m2subm;
00075 struct rt_i *rtip;
00076 };
00077 #define RT_SUBMODEL_SPECIFIC_MAGIC 0x73756253
00078 #define RT_CK_SUBMODEL_SPECIFIC(_p) BU_CKMAG(_p,RT_SUBMODEL_SPECIFIC_MAGIC,"submodel_specific")
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 int
00097 rt_submodel_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
00098 {
00099 struct rt_submodel_internal *sip;
00100 struct submodel_specific *submodel;
00101 struct rt_i *sub_rtip;
00102 struct db_i *sub_dbip;
00103 struct resource *resp;
00104 vect_t radvec;
00105 vect_t diam;
00106 char *argv[2];
00107 struct rt_i **rtipp;
00108
00109 RT_CK_DB_INTERNAL(ip);
00110 sip = (struct rt_submodel_internal *)ip->idb_ptr;
00111 RT_SUBMODEL_CK_MAGIC(sip);
00112
00113 bu_semaphore_acquire(RT_SEM_MODEL);
00114
00115
00116
00117
00118 if( bu_vls_strlen( &sip->file ) == 0 ) {
00119
00120 sub_dbip = rtip->rti_dbip;
00121 } else {
00122
00123 if( (sub_dbip = db_open( bu_vls_addr( &sip->file ), "r" )) == DBI_NULL )
00124 return -1;
00125
00126
00127 if( sub_dbip->dbi_mf ) sub_dbip->dbi_mf->dont_restat = 1;
00128
00129 if( !db_is_directory_non_empty(sub_dbip) ) {
00130
00131 if( db_dirbuild( sub_dbip ) < 0 ) {
00132 db_close( sub_dbip );
00133 bu_semaphore_release(RT_SEM_MODEL);
00134 return -1;
00135 }
00136 }
00137 }
00138
00139
00140
00141
00142
00143
00144
00145 for( BU_PTBL_FOR( rtipp, (struct rt_i **), &sub_dbip->dbi_clients ) ) {
00146 register char *ttp;
00147 RT_CK_RTI(*rtipp);
00148 ttp = (*rtipp)->rti_treetop;
00149 if( ttp && strcmp( ttp, bu_vls_addr( &sip->treetop ) ) == 0 ) {
00150
00151 sub_rtip = *rtipp;
00152 sub_rtip->rti_uses++;
00153
00154 bu_semaphore_release(RT_SEM_MODEL);
00155
00156 if( RT_G_DEBUG & (DEBUG_DB|DEBUG_SOLIDS) ) {
00157 bu_log("rt_submodel_prep(%s): Re-used already prepped database %s, rtip=x%lx\n",
00158 stp->st_dp->d_namep,
00159 sub_dbip->dbi_filename,
00160 (long)sub_rtip );
00161 }
00162 goto done;
00163 }
00164 }
00165
00166 sub_rtip = rt_new_rti( sub_dbip );
00167 RT_CK_RTI(sub_rtip);
00168
00169
00170 sub_rtip->rti_treetop = bu_vls_strdup(&sip->treetop);
00171
00172 bu_semaphore_release(RT_SEM_MODEL);
00173
00174 if( RT_G_DEBUG & (DEBUG_DB|DEBUG_SOLIDS) ) {
00175 bu_log("rt_submodel_prep(%s): Opened database %s\n",
00176 stp->st_dp->d_namep, sub_dbip->dbi_filename );
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186 BU_GETSTRUCT( resp, resource );
00187 BU_PTBL_SET(&sub_rtip->rti_resources, 0, resp);
00188 rt_init_resource( resp, 0, sub_rtip );
00189
00190
00191 sub_rtip->useair = rtip->useair;
00192 sub_rtip->rti_dont_instance = rtip->rti_dont_instance;
00193 sub_rtip->rti_hasty_prep = rtip->rti_hasty_prep;
00194 sub_rtip->rti_tol = rtip->rti_tol;
00195 sub_rtip->rti_ttol = rtip->rti_ttol;
00196
00197 if( sip->meth ) {
00198 sub_rtip->rti_space_partition = sip->meth;
00199 } else {
00200 sub_rtip->rti_space_partition = rtip->rti_space_partition;
00201 }
00202
00203 argv[0] = bu_vls_addr( &sip->treetop );
00204 argv[1] = NULL;
00205 if( rt_gettrees( sub_rtip, 1, (const char **)argv, 1 ) < 0 ) {
00206 bu_log("submodel(%s) rt_gettrees(%s) failed\n", stp->st_name, argv[0]);
00207
00208
00209
00210 return -2;
00211 }
00212
00213 if( sub_rtip->nsolids <= 0 ) {
00214 bu_log("rt_submodel_prep(%s): %s No primitives found\n",
00215 stp->st_dp->d_namep, bu_vls_addr( &sip->file ) );
00216
00217
00218
00219 return -3;
00220 }
00221
00222
00223
00224 rt_prep_parallel(sub_rtip, 1);
00225
00226
00227 if( BU_PTBL_LEN(&sub_rtip->rti_resources) < sub_rtip->rti_resources.blen ) {
00228 BU_PTBL_LEN(&sub_rtip->rti_resources) = sub_rtip->rti_resources.blen;
00229 }
00230
00231 if(RT_G_DEBUG) rt_pr_cut_info( sub_rtip, stp->st_name );
00232
00233 done:
00234 BU_GETSTRUCT( submodel, submodel_specific );
00235 submodel->magic = RT_SUBMODEL_SPECIFIC_MAGIC;
00236 stp->st_specific = (genptr_t)submodel;
00237
00238 MAT_COPY( submodel->subm2m, sip->root2leaf );
00239 bn_mat_inv( submodel->m2subm, sip->root2leaf );
00240 submodel->rtip = sub_rtip;
00241
00242
00243 bn_rotate_bbox( stp->st_min, stp->st_max,
00244 submodel->subm2m,
00245 sub_rtip->mdl_min, sub_rtip->mdl_max );
00246
00247 VSUB2( diam, stp->st_max, stp->st_min );
00248 VADD2SCALE( stp->st_center, stp->st_min, stp->st_max, 0.5 );
00249 VSCALE( radvec, diam, 0.5 );
00250 stp->st_aradius = stp->st_bradius = MAGNITUDE( radvec );
00251
00252 if( RT_G_DEBUG & (DEBUG_DB|DEBUG_SOLIDS) ) {
00253 bu_log("rt_submodel_prep(%s): finished loading database %s\n",
00254 stp->st_dp->d_namep, sub_dbip->dbi_filename );
00255 }
00256
00257 return(0);
00258 }
00259
00260
00261
00262
00263 void
00264 rt_submodel_print(register const struct soltab *stp)
00265 {
00266 register const struct submodel_specific *submodel =
00267 (struct submodel_specific *)stp->st_specific;
00268
00269 RT_CK_SUBMODEL_SPECIFIC(submodel);
00270
00271 bn_mat_print("subm2m", submodel->subm2m);
00272 bn_mat_print("m2subm", submodel->m2subm);
00273
00274 bu_log_indent_delta(4);
00275 bu_log("submodel->rtip=x%x\n", submodel->rtip);
00276
00277
00278 RT_VISIT_ALL_SOLTABS_START( stp, submodel->rtip ) {
00279 rt_pr_soltab(stp);
00280 } RT_VISIT_ALL_SOLTABS_END
00281 bu_log_indent_delta(-4);
00282 }
00283
00284
00285
00286
00287
00288 int
00289 rt_submodel_a_miss(struct application *ap)
00290 {
00291 return 0;
00292 }
00293
00294 struct submodel_gobetween {
00295 struct application *up_ap;
00296 struct seg *up_seghead;
00297 struct soltab *up_stp;
00298 fastf_t delta;
00299 };
00300
00301
00302
00303
00304 int
00305 rt_submodel_a_hit(struct application *ap, struct partition *PartHeadp, struct seg *segHeadp)
00306 {
00307 register struct partition *pp;
00308 struct application *up_ap;
00309 struct soltab *up_stp;
00310 struct region *up_reg;
00311 struct submodel_gobetween *gp;
00312 struct submodel_specific *submodel;
00313 int count = 0;
00314
00315 RT_AP_CHECK(ap);
00316 RT_CK_PT_HD(PartHeadp);
00317 gp = (struct submodel_gobetween *)ap->a_uptr;
00318 up_ap = gp->up_ap;
00319 RT_AP_CHECK(up_ap);
00320 RT_CK_RTI(up_ap->a_rt_i);
00321 up_stp = gp->up_stp;
00322 RT_CK_SOLTAB(up_stp);
00323 submodel = (struct submodel_specific *)up_stp->st_specific;
00324 RT_CK_SUBMODEL_SPECIFIC(submodel);
00325
00326
00327 up_reg = (struct region *)BU_PTBL_GET(&(up_stp->st_regions), 0);
00328 RT_CK_REGION(up_reg);
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 for( BU_LIST_FOR( pp, partition, (struct bu_list *)PartHeadp ) ) {
00340 struct seg *up_segp;
00341 struct seg *inseg;
00342 struct seg *outseg;
00343
00344 RT_CK_PT(pp);
00345 inseg = pp->pt_inseg;
00346 outseg = pp->pt_outseg;
00347 RT_CK_SEG(inseg);
00348 RT_CK_SEG(outseg);
00349
00350
00351
00352
00353
00354
00355
00356 RT_GET_SEG(up_segp, up_ap->a_resource );
00357 up_segp->seg_in = inseg->seg_in;
00358 up_segp->seg_out = outseg->seg_out;
00359 up_segp->seg_stp = up_stp;
00360
00361
00362 MAT4XSCALOR( up_segp->seg_in.hit_dist, submodel->subm2m, inseg->seg_in.hit_dist);
00363 up_segp->seg_in.hit_dist -= gp->delta;
00364 MAT4XSCALOR( up_segp->seg_out.hit_dist, submodel->subm2m, outseg->seg_out.hit_dist);
00365 up_segp->seg_out.hit_dist -= gp->delta;
00366
00367 BU_ASSERT_DOUBLE(up_segp->seg_in.hit_dist, <=, up_segp->seg_out.hit_dist );
00368
00369
00370 up_segp->seg_in.hit_rayp = &up_ap->a_ray;
00371 up_segp->seg_out.hit_rayp = &up_ap->a_ray;
00372
00373
00374 VJOIN1( up_segp->seg_in.hit_point, up_ap->a_ray.r_pt,
00375 up_segp->seg_in.hit_dist, up_ap->a_ray.r_dir );
00376 VJOIN1( up_segp->seg_out.hit_point, up_ap->a_ray.r_pt,
00377 up_segp->seg_out.hit_dist, up_ap->a_ray.r_dir );
00378
00379
00380 inseg->seg_stp->st_meth->ft_norm(
00381 &inseg->seg_in,
00382 inseg->seg_stp,
00383 inseg->seg_in.hit_rayp );
00384 outseg->seg_stp->st_meth->ft_norm(
00385 &outseg->seg_out,
00386 outseg->seg_stp,
00387 outseg->seg_out.hit_rayp );
00388
00389 { fastf_t cosine = fabs(VDOT( ap->a_ray.r_dir, inseg->seg_in.hit_normal ));
00390 if( cosine > 1.00001 ) {
00391 bu_log("rt_submodel_a_hit() cos=1+%g, %s surfno=%d\n",
00392 cosine-1,
00393 inseg->seg_stp->st_dp->d_namep,
00394 inseg->seg_in.hit_surfno );
00395 VPRINT("inseg->seg_in.hit_normal", inseg->seg_in.hit_normal);
00396 }
00397 }
00398 MAT3X3VEC( up_segp->seg_in.hit_normal, submodel->subm2m,
00399 inseg->seg_in.hit_normal );
00400
00401 { fastf_t cosine = fabs(VDOT( up_ap->a_ray.r_dir, up_segp->seg_in.hit_normal ));
00402 if( cosine > 1.00001 ) {
00403 bu_log("rt_submodel_a_hit() cos=1+%g, %s surfno=%d\n",
00404 cosine-1,
00405 inseg->seg_stp->st_dp->d_namep,
00406 inseg->seg_in.hit_surfno );
00407 VPRINT("up_segp->seg_in.hit_normal", up_segp->seg_in.hit_normal);
00408 }
00409 }
00410 MAT3X3VEC( up_segp->seg_out.hit_normal, submodel->subm2m,
00411 outseg->seg_out.hit_normal );
00412
00413
00414 {
00415 struct uvcoord uv;
00416 RT_HIT_UVCOORD( ap, inseg->seg_stp, &inseg->seg_in, &uv );
00417 up_segp->seg_in.hit_vpriv[X] = uv.uv_u;
00418 up_segp->seg_in.hit_vpriv[Y] = uv.uv_v;
00419 if( uv.uv_du >= uv.uv_dv )
00420 up_segp->seg_in.hit_vpriv[Z] = uv.uv_du;
00421 else
00422 up_segp->seg_in.hit_vpriv[Z] = uv.uv_dv;
00423
00424 RT_HIT_UVCOORD( ap, outseg->seg_stp, &outseg->seg_out, &uv );
00425 up_segp->seg_out.hit_vpriv[X] = uv.uv_u;
00426 up_segp->seg_out.hit_vpriv[Y] = uv.uv_v;
00427 if( uv.uv_du >= uv.uv_dv )
00428 up_segp->seg_out.hit_vpriv[Z] = uv.uv_du;
00429 else
00430 up_segp->seg_out.hit_vpriv[Z] = uv.uv_dv;
00431 }
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 up_segp->seg_in.hit_surfno = inseg->seg_stp->st_bit;
00443 up_segp->seg_out.hit_surfno = outseg->seg_stp->st_bit;
00444
00445
00446 BU_LIST_INSERT( &(gp->up_seghead->l), &(up_segp->l) );
00447 count++;
00448 }
00449 return count;
00450 }
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 int
00464 rt_submodel_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
00465 {
00466 register struct submodel_specific *submodel =
00467 (struct submodel_specific *)stp->st_specific;
00468 struct application sub_ap;
00469 struct submodel_gobetween gb;
00470 vect_t vdiff;
00471 int code;
00472 struct bu_ptbl *restbl;
00473 struct resource *resp;
00474 int cpu;
00475
00476 RT_CK_SOLTAB(stp);
00477 RT_CK_RTI(ap->a_rt_i);
00478 RT_CK_SUBMODEL_SPECIFIC(submodel);
00479
00480 gb.up_ap = ap;
00481 gb.up_seghead = seghead;
00482 gb.up_stp = stp;
00483
00484 sub_ap = *ap;
00485 sub_ap.a_rt_i = submodel->rtip;
00486 sub_ap.a_hit = rt_submodel_a_hit;
00487 sub_ap.a_miss = rt_submodel_a_miss;
00488 sub_ap.a_uptr = (genptr_t)&gb;
00489 sub_ap.a_purpose = "rt_submodel_shot";
00490
00491
00492 if( sub_ap.a_onehit < 0 ) {
00493 if( sub_ap.a_onehit&1 ) sub_ap.a_onehit--;
00494 } else {
00495 if( sub_ap.a_onehit&1 ) sub_ap.a_onehit++;
00496 }
00497
00498
00499
00500
00501
00502 restbl = &submodel->rtip->rti_resources;
00503 cpu = ap->a_resource->re_cpu;
00504 BU_ASSERT_LONG( cpu, <, BU_PTBL_END(restbl) );
00505 if( (resp = (struct resource *)BU_PTBL_GET(restbl, cpu)) == NULL ) {
00506
00507 BU_GETSTRUCT( resp, resource );
00508 BU_PTBL_SET(restbl, cpu, resp);
00509 rt_init_resource( resp, cpu, submodel->rtip );
00510 }
00511 RT_CK_RESOURCE(resp);
00512 sub_ap.a_resource = resp;
00513
00514
00515
00516
00517
00518 MAT4X3PNT( sub_ap.a_ray.r_pt, submodel->m2subm, ap->a_ray.r_pt );
00519 MAT3X3VEC( sub_ap.a_ray.r_dir, submodel->m2subm, ap->a_ray.r_dir );
00520
00521
00522
00523 VSUB2( vdiff, rp->r_pt, ap->a_ray.r_pt );
00524 gb.delta = VDOT( vdiff, ap->a_ray.r_dir );
00525
00526 code = rt_shootray( &sub_ap );
00527
00528 if( code <= 0 ) return 0;
00529
00530
00531
00532
00533 return 1;
00534 }
00535
00536 #define RT_SUBMODEL_SEG_MISS(SEG) (SEG).seg_stp=RT_SOLTAB_NULL
00537
00538
00539
00540
00541
00542
00543 void
00544 rt_submodel_vshot(struct soltab **stp, struct xray **rp, struct seg *segp, int n, struct application *ap)
00545
00546
00547
00548
00549
00550 {
00551 rt_vstub( stp, rp, segp, n, ap );
00552 }
00553
00554
00555
00556
00557
00558
00559 void
00560 rt_submodel_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp)
00561 {
00562 RT_CK_HIT(hitp);
00563
00564
00565
00566
00567 { fastf_t cosine = fabs(VDOT( rp->r_dir, hitp->hit_normal ));
00568 if( cosine > 1.00001 ) {
00569 bu_log("rt_submodel_norm() cos=1+%g, %s surfno=%d\n",
00570 cosine-1,
00571 stp->st_dp->d_namep,
00572 hitp->hit_surfno );
00573 }
00574 }
00575 }
00576
00577
00578
00579
00580
00581
00582 void
00583 rt_submodel_curve(register struct curvature *cvp, register struct hit *hitp, struct soltab *stp)
00584 {
00585 cvp->crv_c1 = cvp->crv_c2 = 0;
00586
00587
00588 bn_vec_ortho( cvp->crv_pdir, hitp->hit_normal );
00589
00590
00591 bu_log("rt_submodel_curve() not implemented, need extra fields in 'struct hit'\n");
00592 }
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 void
00603 rt_submodel_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
00604 {
00605 RT_CK_HIT(hitp);
00606
00607 uvp->uv_u = hitp->hit_vpriv[X];
00608 uvp->uv_v = hitp->hit_vpriv[Y];
00609 uvp->uv_du = uvp->uv_dv = hitp->hit_vpriv[Z];
00610 }
00611
00612
00613
00614
00615 void
00616 rt_submodel_free(register struct soltab *stp)
00617 {
00618 register struct submodel_specific *submodel =
00619 (struct submodel_specific *)stp->st_specific;
00620 struct resource **rpp;
00621 struct rt_i *rtip;
00622
00623 RT_CK_SUBMODEL_SPECIFIC(submodel);
00624 rtip = submodel->rtip;
00625 RT_CK_RTI(rtip);
00626
00627
00628 BU_CK_PTBL( &rtip->rti_resources );
00629 for( BU_PTBL_FOR( rpp, (struct resource **), &rtip->rti_resources ) ) {
00630 if( *rpp == NULL ) continue;
00631 if( *rpp == &rt_uniresource ) continue;
00632 RT_CK_RESOURCE(*rpp);
00633
00634 rt_clean_resource(rtip, *rpp);
00635 bu_free( *rpp, "struct resource (submodel)" );
00636
00637 *rpp = NULL;
00638 }
00639
00640
00641 rt_free_rti( submodel->rtip );
00642
00643 bu_free( (genptr_t)submodel, "submodel_specific" );
00644 }
00645
00646
00647
00648
00649 int
00650 rt_submodel_class(const struct soltab *stp, const fastf_t *min, const fastf_t *max, const struct bn_tol *tol)
00651 {
00652 return RT_CLASSIFY_UNIMPLEMENTED;
00653 }
00654
00655 struct goodies {
00656 struct db_i *dbip;
00657 struct bu_list *vheadp;
00658 };
00659
00660
00661
00662
00663
00664
00665
00666 HIDDEN union tree *rt_submodel_wireframe_leaf(struct db_tree_state *tsp, struct db_full_path *pathp, struct rt_db_internal *ip, genptr_t client_data)
00667 {
00668 union tree *curtree;
00669 struct goodies *gp;
00670
00671 RT_CK_TESS_TOL(tsp->ts_ttol);
00672 BN_CK_TOL(tsp->ts_tol);
00673 RT_CK_DB_INTERNAL(ip );
00674 RT_CK_RESOURCE(tsp->ts_resp);
00675
00676 gp = (struct goodies *)tsp->ts_m;
00677 RT_CK_DBI(gp->dbip);
00678
00679
00680 if(bu_is_parallel()) bu_bomb("rt_submodel_wireframe_leaf() non-parallel code\n");
00681
00682 if(RT_G_DEBUG&DEBUG_TREEWALK) {
00683 char *sofar = db_path_to_string(pathp);
00684
00685 bu_log("rt_submodel_wireframe_leaf(%s) path=%s\n",
00686 ip->idb_meth->ft_name, sofar );
00687 bu_free((genptr_t)sofar, "path string");
00688 }
00689
00690 if( ip->idb_meth->ft_plot(
00691 gp->vheadp, ip,
00692 tsp->ts_ttol, tsp->ts_tol ) < 0 ) {
00693 bu_log("rt_submodel_wireframe_leaf(%s): %s plot failure\n",
00694 ip->idb_meth->ft_name,
00695 DB_FULL_PATH_CUR_DIR(pathp)->d_namep );
00696 return(TREE_NULL);
00697 }
00698
00699
00700 RT_GET_TREE( curtree, tsp->ts_resp);
00701 curtree->magic = RT_TREE_MAGIC;
00702 curtree->tr_op = OP_NOP;
00703
00704 return( curtree );
00705 }
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717 int
00718 rt_submodel_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
00719 {
00720 LOCAL struct rt_submodel_internal *sip;
00721 struct db_tree_state state;
00722 int ret;
00723 char *argv[2];
00724 struct goodies good;
00725
00726 RT_CK_DB_INTERNAL(ip);
00727 sip = (struct rt_submodel_internal *)ip->idb_ptr;
00728 RT_SUBMODEL_CK_MAGIC(sip);
00729
00730
00731
00732 state = rt_initial_tree_state;
00733 state.ts_ttol = ttol;
00734 state.ts_tol = tol;
00735 MAT_COPY( state.ts_mat, sip->root2leaf );
00736
00737 state.ts_m = (struct model **)&good;
00738 good.vheadp = vhead;
00739
00740 if( bu_vls_strlen( &sip->file ) != 0 ) {
00741
00742 if( (good.dbip = db_open( bu_vls_addr( &sip->file ), "r" )) == DBI_NULL ) {
00743 bu_log("rt_submodel_plot() db_open(%s) failure\n", bu_vls_addr( &sip->file ));
00744 return -1;
00745 }
00746 if( !db_is_directory_non_empty(good.dbip) ) {
00747
00748 if( db_dirbuild( good.dbip ) < 0 ) {
00749 bu_log("rt_submodel_plot() db_dirbuild() failure\n");
00750 db_close(good.dbip);
00751 return -1;
00752 }
00753 }
00754 } else {
00755
00756
00757
00758 RT_CK_DBI(sip->dbip);
00759 good.dbip = (struct db_i *)sip->dbip;
00760 }
00761
00762 argv[0] = bu_vls_addr( &sip->treetop );
00763 argv[1] = NULL;
00764 ret = db_walk_tree( good.dbip, 1, (const char **)argv,
00765 1,
00766 &state,
00767 0,
00768 NULL,
00769 rt_submodel_wireframe_leaf,
00770 (genptr_t)NULL );
00771
00772 if( ret < 0 ) bu_log("rt_submodel_plot() db_walk_tree(%s) failure\n", bu_vls_addr( &sip->treetop ));
00773 if( bu_vls_strlen( &sip->file ) != 0 )
00774 db_close(good.dbip);
00775 return ret;
00776 }
00777
00778
00779
00780
00781
00782
00783
00784
00785 int
00786 rt_submodel_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
00787 {
00788 LOCAL struct rt_submodel_internal *sip;
00789
00790 RT_CK_DB_INTERNAL(ip);
00791 sip = (struct rt_submodel_internal *)ip->idb_ptr;
00792 RT_SUBMODEL_CK_MAGIC(sip);
00793
00794 return(-1);
00795 }
00796
00797
00798
00799
00800
00801
00802
00803 int
00804 rt_submodel_import(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
00805 {
00806 LOCAL struct rt_submodel_internal *sip;
00807 union record *rp;
00808 struct bu_vls str;
00809
00810 BU_CK_EXTERNAL( ep );
00811 RT_CK_DBI(dbip);
00812
00813 rp = (union record *)ep->ext_buf;
00814
00815 if( rp->u_id != DBID_STRSOL ) {
00816 bu_log("rt_submodel_import: defective strsol record\n");
00817 return(-1);
00818 }
00819
00820 RT_CK_DB_INTERNAL( ip );
00821 ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
00822 ip->idb_type = ID_SUBMODEL;
00823 ip->idb_meth = &rt_functab[ID_SUBMODEL];
00824 ip->idb_ptr = bu_malloc( sizeof(struct rt_submodel_internal), "rt_submodel_internal");
00825 sip = (struct rt_submodel_internal *)ip->idb_ptr;
00826 sip->magic = RT_SUBMODEL_INTERNAL_MAGIC;
00827 sip->dbip = dbip;
00828
00829 MAT_COPY( sip->root2leaf, mat );
00830
00831 bu_vls_init( &str );
00832 bu_vls_strcpy( &str, rp->ss.ss_args );
00833 #if 0
00834 bu_log("rt_submodel_import: '%s'\n", rp->ss.ss_args);
00835 #endif
00836 if( bu_struct_parse( &str, rt_submodel_parse, (char *)sip ) < 0 ) {
00837 bu_vls_free( &str );
00838 fail:
00839 bu_free( (char *)sip , "rt_submodel_import: sip" );
00840 ip->idb_type = ID_NULL;
00841 ip->idb_ptr = (genptr_t)NULL;
00842 return -2;
00843 }
00844 bu_vls_free( &str );
00845
00846
00847 if( bu_vls_strlen( &sip->treetop ) == 0 ) {
00848 bu_log("rt_submodel_import() treetop= must be specified\n");
00849 goto fail;
00850 }
00851 #if 0
00852 bu_log("import: file='%s', treetop='%s', meth=%d\n", bu_vls_addr( &sip->file ), bu_vls_addr( &sip->treetop ), sip->meth);
00853 bn_mat_print("root2leaf", sip->root2leaf );
00854 #endif
00855
00856 return(0);
00857 }
00858
00859
00860
00861
00862
00863
00864 int
00865 rt_submodel_export(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
00866 {
00867 struct rt_submodel_internal *sip;
00868 union record *rec;
00869 struct bu_vls str;
00870
00871 RT_CK_DB_INTERNAL(ip);
00872 if( ip->idb_type != ID_SUBMODEL ) return(-1);
00873 sip = (struct rt_submodel_internal *)ip->idb_ptr;
00874 RT_SUBMODEL_CK_MAGIC(sip);
00875 #if 0
00876 bu_log("export: file='%s', treetop='%s', meth=%d\n", bu_vls_addr( &sip->file ), bu_vls_addr( &sip->treetop ), sip->meth);
00877 #endif
00878
00879
00880 BU_ASSERT( local2mm == 1.0 );
00881
00882 BU_CK_EXTERNAL(ep);
00883 ep->ext_nbytes = sizeof(union record)*DB_SS_NGRAN;
00884 ep->ext_buf = bu_calloc( 1, ep->ext_nbytes, "submodel external");
00885 rec = (union record *)ep->ext_buf;
00886
00887 bu_vls_init( &str );
00888 bu_vls_struct_print( &str, rt_submodel_parse, (char *)sip );
00889
00890 rec->ss.ss_id = DBID_STRSOL;
00891 strncpy( rec->ss.ss_keyword, "submodel", NAMESIZE-1 );
00892 strncpy( rec->ss.ss_args, bu_vls_addr(&str), DB_SS_LEN-1 );
00893 bu_vls_free( &str );
00894 #if 0
00895 bu_log("rt_submodel_export: '%s'\n", rec->ss.ss_args);
00896 #endif
00897
00898 return(0);
00899 }
00900
00901
00902
00903
00904
00905
00906
00907
00908 int
00909 rt_submodel_import5(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
00910 {
00911 LOCAL struct rt_submodel_internal *sip;
00912 struct bu_vls str;
00913
00914 BU_CK_EXTERNAL( ep );
00915 RT_CK_DBI(dbip);
00916
00917 RT_CK_DB_INTERNAL( ip );
00918 ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
00919 ip->idb_type = ID_SUBMODEL;
00920 ip->idb_meth = &rt_functab[ID_SUBMODEL];
00921 ip->idb_ptr = bu_malloc( sizeof(struct rt_submodel_internal), "rt_submodel_internal");
00922 sip = (struct rt_submodel_internal *)ip->idb_ptr;
00923 sip->magic = RT_SUBMODEL_INTERNAL_MAGIC;
00924 sip->dbip = dbip;
00925
00926 MAT_COPY( sip->root2leaf, mat );
00927
00928 bu_vls_init( &str );
00929 bu_vls_strncpy( &str, ep->ext_buf, ep->ext_nbytes );
00930 #if 0
00931 bu_log("rt_submodel_import: '%s'\n", rp->ss.ss_args);
00932 #endif
00933 if( bu_struct_parse( &str, rt_submodel_parse, (char *)sip ) < 0 ) {
00934 bu_vls_free( &str );
00935 fail:
00936 bu_free( (char *)sip , "rt_submodel_import: sip" );
00937 ip->idb_type = ID_NULL;
00938 ip->idb_ptr = (genptr_t)NULL;
00939 return -2;
00940 }
00941 bu_vls_free( &str );
00942
00943
00944 if( bu_vls_strlen( &sip->treetop ) == 0 ) {
00945 bu_log("rt_submodel_import() treetop= must be specified\n");
00946 goto fail;
00947 }
00948 #if 0
00949 bu_log("import: file='%s', treetop='%s', meth=%d\n", bu_vls_addr( &sip->file ), bu_vls_addr( &sip->treetop ), sip->meth);
00950 bn_mat_print("root2leaf", sip->root2leaf );
00951 #endif
00952
00953 return(0);
00954 }
00955
00956
00957
00958
00959
00960
00961 int
00962 rt_submodel_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
00963 {
00964 struct rt_submodel_internal *sip;
00965 struct bu_vls str;
00966
00967 RT_CK_DB_INTERNAL(ip);
00968 if( ip->idb_type != ID_SUBMODEL ) return(-1);
00969 sip = (struct rt_submodel_internal *)ip->idb_ptr;
00970 RT_SUBMODEL_CK_MAGIC(sip);
00971 #if 0
00972 bu_log("export: file='%s', treetop='%s', meth=%d\n", bu_vls_addr( &sip->file ), bu_vls_addr( &sip->treetop ), sip->meth);
00973 #endif
00974
00975
00976 BU_ASSERT( local2mm == 1.0 );
00977 BU_CK_EXTERNAL(ep);
00978
00979 bu_vls_init( &str );
00980 bu_vls_struct_print( &str, rt_submodel_parse, (char *)sip );
00981 ep->ext_nbytes = bu_vls_strlen( &str );
00982 ep->ext_buf = bu_calloc( 1, ep->ext_nbytes, "submodel external");
00983
00984 strncpy(ep->ext_buf, bu_vls_addr(&str), ep->ext_nbytes);
00985 bu_vls_free( &str );
00986 #if 0
00987 bu_log("rt_submodel_export: '%s'\n", rec->ss.ss_args);
00988 #endif
00989
00990 return(0);
00991 }
00992
00993
00994
00995
00996
00997
00998
00999
01000 int
01001 rt_submodel_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
01002 {
01003 register struct rt_submodel_internal *sip =
01004 (struct rt_submodel_internal *)ip->idb_ptr;
01005
01006 RT_SUBMODEL_CK_MAGIC(sip);
01007 bu_vls_strcat( str, "instanced submodel (SUBMODEL)\n");
01008
01009 bu_vls_printf(str, "\tfile='%s', treetop='%s', meth=%d\n",
01010 bu_vls_addr( &sip->file ),
01011 bu_vls_addr( &sip->treetop ),
01012 sip->meth );
01013
01014 return(0);
01015 }
01016
01017
01018
01019
01020
01021
01022 void
01023 rt_submodel_ifree(struct rt_db_internal *ip)
01024 {
01025 register struct rt_submodel_internal *sip;
01026
01027 RT_CK_DB_INTERNAL(ip);
01028 sip = (struct rt_submodel_internal *)ip->idb_ptr;
01029 RT_SUBMODEL_CK_MAGIC(sip);
01030 sip->magic = 0;
01031
01032 bu_free( (genptr_t)sip, "submodel ifree" );
01033 ip->idb_ptr = GENPTR_NULL;
01034 }
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044