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 #ifndef lint
00041 static char rt_hf_RcSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/g_hf.c,v 14.14 2006/09/16 02:04:24 lbutler Exp $ (ARL)";
00042 #endif
00043
00044 #include "common.h"
00045
00046 #include <stdlib.h>
00047 #include <stddef.h>
00048 #include <stdio.h>
00049 #include <math.h>
00050 #include <fcntl.h>
00051 #ifdef HAVE_STRING_H
00052 # include <string.h>
00053 #else
00054 # include <strings.h>
00055 #endif
00056
00057 #include "machine.h"
00058 #include "vmath.h"
00059 #include "db.h"
00060 #include "nmg.h"
00061 #include "raytrace.h"
00062 #include "rtgeom.h"
00063 #include "./debug.h"
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 #define HF_O(m) bu_offsetof(struct rt_hf_internal, m)
00085
00086
00087 const struct bu_structparse rt_hf_parse[] = {
00088 {"%s", 128, "cfile", bu_offsetofarray(struct rt_hf_internal, cfile), BU_STRUCTPARSE_FUNC_NULL},
00089 {"%s", 128, "dfile", bu_offsetofarray(struct rt_hf_internal, dfile), BU_STRUCTPARSE_FUNC_NULL},
00090 {"%s", 8, "fmt", bu_offsetofarray(struct rt_hf_internal, fmt), BU_STRUCTPARSE_FUNC_NULL},
00091 {"%d", 1, "w", HF_O(w), BU_STRUCTPARSE_FUNC_NULL },
00092 {"%d", 1, "n", HF_O(n), BU_STRUCTPARSE_FUNC_NULL },
00093 {"%d", 1, "shorts", HF_O(shorts), BU_STRUCTPARSE_FUNC_NULL },
00094 {"%f", 1, "file2mm", HF_O(file2mm), BU_STRUCTPARSE_FUNC_NULL },
00095 {"%f", 3, "v", HF_O(v[0]), BU_STRUCTPARSE_FUNC_NULL },
00096 {"%f", 3, "x", HF_O(x[0]), BU_STRUCTPARSE_FUNC_NULL },
00097 {"%f", 3, "y", HF_O(y[0]), BU_STRUCTPARSE_FUNC_NULL },
00098 {"%f", 1, "xlen", HF_O(xlen), BU_STRUCTPARSE_FUNC_NULL },
00099 {"%f", 1, "ylen", HF_O(ylen), BU_STRUCTPARSE_FUNC_NULL },
00100 {"%f", 1, "zscale", HF_O(zscale), BU_STRUCTPARSE_FUNC_NULL },
00101 {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL }
00102 };
00103
00104 const struct bu_structparse rt_hf_cparse[] = {
00105 {"%s", 128, "dfile", bu_offsetofarray(struct rt_hf_internal, dfile), BU_STRUCTPARSE_FUNC_NULL},
00106 {"%s", 8, "fmt", bu_offsetofarray(struct rt_hf_internal, fmt), BU_STRUCTPARSE_FUNC_NULL},
00107 {"%d", 1, "w", HF_O(w), BU_STRUCTPARSE_FUNC_NULL },
00108 {"%d", 1, "n", HF_O(n), BU_STRUCTPARSE_FUNC_NULL },
00109 {"%d", 1, "shorts", HF_O(shorts), BU_STRUCTPARSE_FUNC_NULL },
00110 {"%f", 1, "file2mm", HF_O(file2mm), BU_STRUCTPARSE_FUNC_NULL },
00111 {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL }
00112 };
00113
00114 struct hf_specific {
00115 vect_t hf_V;
00116 vect_t hf_VO;
00117 vect_t hf_X;
00118 fastf_t hf_Xlen;
00119 vect_t hf_Y;
00120 fastf_t hf_Ylen;
00121 vect_t hf_N;
00122 fastf_t hf_min;
00123 fastf_t hf_max;
00124 fastf_t hf_file2mm;
00125 int hf_w;
00126 int hf_n;
00127 int hf_shorts;
00128 struct bu_mapped_file *hf_mp;
00129 };
00130
00131
00132
00133
00134
00135
00136
00137
00138 int
00139 rt_hf_to_dsp(struct rt_db_internal *db_intern, struct resource *resp)
00140 {
00141 struct rt_hf_internal *hip = (struct rt_hf_internal *)db_intern->idb_ptr;
00142 struct rt_dsp_internal *dsp;
00143 vect_t tmp;
00144
00145 RT_CK_DB_INTERNAL(db_intern);
00146 RT_CK_RESOURCE(resp);
00147 RT_HF_CK_MAGIC( hip );
00148
00149 if (! hip->shorts) {
00150 bu_log("cannot convert float HF to DSP\n");
00151 return -1;
00152 }
00153
00154 BU_GETSTRUCT( dsp, rt_dsp_internal );
00155 bu_vls_init( &dsp->dsp_name );
00156 bu_vls_strcat( &dsp->dsp_name, hip->dfile );
00157 dsp->dsp_xcnt = hip->w;
00158 dsp->dsp_ycnt = hip->n;
00159 dsp->dsp_smooth = 0;
00160 dsp->dsp_cuttype = DSP_CUT_DIR_ADAPT;
00161 if (RT_G_DEBUG & DEBUG_HF) {
00162 bu_log("Converting from cut-style lower-left/upper-right to adaptive\n");
00163 }
00164 dsp->dsp_datasrc = RT_DSP_SRC_FILE;
00165
00166
00167 MAT_IDN(dsp->dsp_stom);
00168 MAT_DELTAS_VEC(dsp->dsp_stom, hip->v);
00169
00170
00171 VUNITIZE( hip->x );
00172 VSCALE( tmp, hip->x, hip->xlen/(fastf_t)(hip->w - 1) );
00173 dsp->dsp_stom[0] = tmp[0];
00174 dsp->dsp_stom[4] = tmp[1];
00175 dsp->dsp_stom[8] = tmp[2];
00176 VUNITIZE( hip->y );
00177 VSCALE( tmp, hip->y, hip->ylen/(fastf_t)(hip->n - 1) );
00178 dsp->dsp_stom[1] = tmp[0];
00179 dsp->dsp_stom[5] = tmp[1];
00180 dsp->dsp_stom[9] = tmp[2];
00181 VCROSS( tmp, hip->x, hip->y );
00182 VUNITIZE( tmp );
00183
00184
00185
00186
00187
00188
00189
00190 VSCALE( tmp, tmp, hip->file2mm );
00191
00192 dsp->dsp_stom[2] = tmp[0];
00193 dsp->dsp_stom[6] = tmp[1];
00194 dsp->dsp_stom[10] = tmp[2];
00195
00196 bn_mat_inv( dsp->dsp_mtos, dsp->dsp_stom );
00197
00198 dsp->magic = RT_DSP_INTERNAL_MAGIC;
00199
00200 rt_db_free_internal( db_intern, resp );
00201
00202 db_intern->idb_ptr = (genptr_t)dsp;
00203 db_intern->idb_major_type = DB5_MAJORTYPE_BRLCAD;
00204 db_intern->idb_type = ID_DSP;
00205 db_intern->idb_meth = &rt_functab[ID_DSP];
00206
00207 return 0;
00208
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 int
00228 rt_hf_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
00229 {
00230 struct rt_hf_internal *hip;
00231 register struct hf_specific *hf;
00232 const struct bn_tol *tol = &rtip->rti_tol;
00233 double dot;
00234 vect_t height, work;
00235 static int first_time=1;
00236
00237 if (first_time) {
00238 #ifndef lint
00239 bu_log("%s\n",rt_hf_RcSid);
00240 #endif
00241 first_time=0;
00242 }
00243 RT_CK_DB_INTERNAL(ip);
00244 hip = (struct rt_hf_internal *)ip->idb_ptr;
00245 RT_HF_CK_MAGIC(hip);
00246
00247 BU_GETSTRUCT(hf, hf_specific);
00248 stp->st_specific = (genptr_t) hf;
00249
00250
00251
00252 VMOVE(hf->hf_V, hip->v);
00253 VMOVE(hf->hf_X, hip->x);
00254 VUNITIZE(hf->hf_X);
00255 hf->hf_Xlen = hip->xlen;
00256 VMOVE(hf->hf_Y, hip->y);
00257 VUNITIZE(hf->hf_Y);
00258 hf->hf_Ylen = hip->ylen;
00259 hf->hf_file2mm = hip->file2mm;
00260 hf->hf_w = hip->w;
00261 hf->hf_n = hip->n;
00262 hf->hf_mp = hip->mp;
00263 bu_semaphore_acquire( RT_SEM_MODEL);
00264 ++hf->hf_mp->uses;
00265 bu_semaphore_release( RT_SEM_MODEL);
00266 hf->hf_shorts = hip->shorts;
00267
00268
00269
00270
00271
00272
00273
00274
00275 VJOIN2(hf->hf_VO, hip->v, hip->xlen, hip->x, hip->ylen, hip->y);
00276
00277
00278
00279
00280 dot = VDOT(hf->hf_X, hf->hf_Y);
00281 if (fabs(dot) >tol->perp) {
00282 bu_log("Hf(%s): X not perpendicular to Y.\n", stp->st_name);
00283 bu_free((genptr_t)hf, "struct hf");
00284 stp->st_specific = (genptr_t) 0;
00285 return 1;
00286 }
00287 VCROSS(hf->hf_N, hf->hf_X, hf->hf_Y);
00288 VUNITIZE(hf->hf_N);
00289
00290
00291
00292
00293
00294 if (hf->hf_shorts) {
00295 register int max, min;
00296 register int len;
00297 register unsigned short *sp;
00298 register int i;
00299
00300 sp = (unsigned short *)hf->hf_mp->apbuf;
00301 min = max = *sp++;
00302 len = hf->hf_w * hf->hf_n;
00303 for (i=1; i< len; i++, sp++) {
00304 if ((int)*sp > max) max=*sp;
00305 if ((int)*sp < min) min=*sp;
00306 }
00307 hf->hf_min = min * hf->hf_file2mm;
00308 hf->hf_max = max * hf->hf_file2mm;
00309 } else {
00310 fastf_t max, min;
00311 register int len;
00312 register int i;
00313 fastf_t *fp;
00314
00315 fp = (fastf_t *) hf->hf_mp->apbuf;
00316 min = max = *fp++;
00317 len = hf->hf_w * hf->hf_n;
00318 for (i=1; i < len; i++, fp++) {
00319 if (*fp > max) max = *fp;
00320 if (*fp < min) min = *fp;
00321 }
00322 hf->hf_min = min * hf->hf_file2mm;
00323 hf->hf_max = max * hf->hf_file2mm;
00324 }
00325
00326 VSCALE(height, hf->hf_N, hf->hf_max);
00327 VADD2(hf->hf_VO, hf->hf_VO, height);
00328
00329
00330
00331
00332 VMOVE(stp->st_min, hf->hf_V);
00333 VMOVE(stp->st_max, hf->hf_V);
00334 VADD2(work, hf->hf_V, height);
00335 VMINMAX(stp->st_min, stp->st_max, work);
00336 VJOIN1(work, hf->hf_V, hf->hf_Xlen, hf->hf_X);
00337 VMINMAX(stp->st_min, stp->st_max, work);
00338 VADD2(work, work, height);
00339 VMINMAX(stp->st_min, stp->st_max, work);
00340 VJOIN1(work, hf->hf_V, hf->hf_Ylen, hf->hf_Y);
00341 VMINMAX(stp->st_min, stp->st_max, work);
00342 VADD2(work, work, height);
00343 VMINMAX(stp->st_min, stp->st_max, work);
00344 VJOIN2(work, hf->hf_V, hf->hf_Xlen, hf->hf_X, hf->hf_Ylen, hf->hf_Y);
00345 VMINMAX(stp->st_min, stp->st_max, work);
00346 VADD2(work, work, height);
00347 VMINMAX(stp->st_min, stp->st_max, work);
00348
00349 {
00350 LOCAL fastf_t dx,dy,dz;
00351 LOCAL fastf_t f;
00352
00353 VADD2SCALE( stp->st_center, stp->st_max, stp->st_min, 0.5);
00354
00355 dx = (stp->st_max[X] - stp->st_min[X])/2;
00356 dy = (stp->st_max[Y] - stp->st_min[Y])/2;
00357 dz = (stp->st_max[Z] - stp->st_min[Z])/2;
00358 f = dx;
00359 if (dy > f) f = dy;
00360 if (dz > f) f = dz;
00361 stp->st_aradius = f;
00362 stp->st_bradius = sqrt(dx*dx + dy*dy + dz*dz);
00363 }
00364 return 0;
00365 }
00366
00367
00368
00369
00370 void
00371 rt_hf_print(register const struct soltab *stp)
00372 {
00373 register const struct hf_specific *hf =
00374 (struct hf_specific *)stp->st_specific;
00375 VPRINT("V", hf->hf_V);
00376 VPRINT("X", hf->hf_X);
00377 VPRINT("Y", hf->hf_Y);
00378 VPRINT("N", hf->hf_N);
00379 bu_log("XL %g\n", hf->hf_Xlen);
00380 bu_log("YL %g\n", hf->hf_Ylen);
00381 }
00382
00383 static int
00384 rt_hf_cell_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct hit *hitp, int xCell, int yCell)
00385 {
00386 register struct hf_specific *hfp =
00387 (struct hf_specific *)stp->st_specific;
00388
00389 fastf_t dn, abs_dn, k1st=0, k2nd=0, alpha, beta;
00390 int dir1st, dir2nd;
00391 vect_t wxb, xp;
00392 vect_t tri_wn1st, tri_wn2nd, tri_BA1st, tri_BA2nd;
00393 vect_t tri_CA1st, tri_CA2nd;
00394 vect_t xvect, yvect, tri_A, tri_B, tri_C;
00395 int fnd1, fnd2;
00396 register double hf2mm = hfp->hf_file2mm;
00397
00398 if (RT_G_DEBUG & DEBUG_HF) {
00399 bu_log("rt_hf_cell_shot(%s): %d, %d\n", stp->st_name,
00400 xCell, yCell);
00401 }
00402 {
00403 register fastf_t scale;
00404 scale = hfp->hf_Xlen/((double)hfp->hf_w-1);
00405 VSCALE(xvect, hfp->hf_X, scale);
00406 scale = hfp->hf_Ylen/((double)hfp->hf_n-1);
00407 VSCALE(yvect, hfp->hf_Y, scale);
00408 }
00409 if (hfp->hf_shorts) {
00410 register unsigned short *sp;
00411 sp = (unsigned short *)hfp->hf_mp->apbuf +
00412 yCell * hfp->hf_w + xCell;
00413
00414
00415
00416
00417 VJOIN3(tri_A, hfp->hf_V, *sp*hf2mm, hfp->hf_N, xCell+0, xvect,
00418 yCell+0, yvect);
00419 sp++;
00420
00421 VJOIN3(tri_B, hfp->hf_V, *sp*hf2mm, hfp->hf_N, xCell+1, xvect,
00422 yCell+0, yvect);
00423 sp += hfp->hf_w;
00424
00425 VJOIN3(tri_C, hfp->hf_V, *sp*hf2mm, hfp->hf_N, xCell+1, xvect,
00426 yCell+1, yvect);
00427
00428 VSUB2(tri_CA1st, tri_C, tri_A);
00429 VSUB2(tri_BA1st, tri_B, tri_A);
00430 VCROSS(tri_wn1st, tri_BA1st, tri_CA1st);
00431 VMOVE(tri_B, tri_C);
00432 --sp;
00433
00434
00435 VJOIN3(tri_C, hfp->hf_V, *sp*hf2mm, hfp->hf_N, xCell+0, xvect,
00436 yCell+1, yvect);
00437 VSUB2(tri_CA2nd, tri_C, tri_A);
00438
00439
00440
00441 VSUB2(tri_BA2nd, tri_B, tri_A);
00442 VCROSS(tri_wn2nd, tri_BA2nd, tri_CA2nd);
00443 } else {
00444 register double *fp;
00445 fp = (double *)hfp->hf_mp->apbuf +
00446 yCell * hfp->hf_w + xCell;
00447
00448 VJOIN3(tri_A, hfp->hf_V, *fp*hf2mm, hfp->hf_N, xCell+0, xvect,
00449 yCell+0, yvect);
00450 fp++;
00451
00452 VJOIN3(tri_B, hfp->hf_V, *fp*hf2mm, hfp->hf_N, xCell+1, xvect,
00453 yCell+0, yvect);
00454 fp += hfp->hf_w;
00455
00456 VJOIN3(tri_C, hfp->hf_V, *fp*hf2mm, hfp->hf_N, xCell+1, xvect,
00457 yCell+1, yvect);
00458 VSUB2(tri_CA1st, tri_C, tri_A);
00459 VSUB2(tri_BA1st, tri_B, tri_A);
00460 VCROSS(tri_wn1st, tri_BA1st, tri_CA1st);
00461 VMOVE(tri_B, tri_C);
00462 --fp;
00463
00464 VJOIN3(tri_C, hfp->hf_V, *fp*hf2mm, hfp->hf_N, xCell+0, xvect,
00465 yCell+1, yvect);
00466 VSUB2(tri_CA2nd, tri_C, tri_A);
00467
00468 VSUB2(tri_BA2nd, tri_B, tri_A);
00469 VCROSS(tri_wn2nd, tri_BA2nd, tri_CA2nd);
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 fnd1 = fnd2 = 0;
00493
00494 #if 0
00495 dn = VDOT(tri_wn1st, rp->r_dir);
00496 abs_dn = (dn >= 0.0) ? dn : (-dn);
00497 if (abs_dn <SQRT_SMALL_FASTF)
00498 goto other_half;
00499
00500 VSUB2( wxb, tri_A, rp->r_pt);
00501 VCROSS( xp, wxb, rp->r_dir);
00502 alpha = VDOT(tri_CA1st, xp);
00503 if (dn < 0.0) alpha = -alpha;
00504 if (alpha < 0.0 || alpha > abs_dn) goto other_half;
00505 beta = VDOT(tri_BA1st, xp);
00506 if (dn > 0.0) beta = -beta;
00507 if (beta < 0.0 || beta > abs_dn) goto other_half;
00508 if (alpha + beta > abs_dn) goto other_half;
00509 k1st = VDOT(wxb, tri_wn1st) / dn;
00510 fnd1 = 1;
00511 #else
00512
00513
00514
00515
00516 dn = VDOT(tri_wn1st, rp->r_dir);
00517 if (dn >= 0.0) {
00518 dir1st = 1;
00519 abs_dn=dn;
00520 } else {
00521 dir1st = 0;
00522 abs_dn = -dn;
00523 }
00524
00525
00526 if (abs_dn >= SQRT_SMALL_FASTF) {
00527 VSUB2( wxb, tri_A, rp->r_pt);
00528 VCROSS( xp, wxb, rp->r_dir);
00529
00530
00531 alpha = VDOT(tri_CA1st, xp);
00532 if (dn < 0.0) alpha = -alpha;
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 if (alpha >= 0.0 && alpha <= abs_dn) {
00543
00544
00545 beta = VDOT(tri_BA1st, xp);
00546 if (dn > 0.0) beta = -beta;
00547
00548 if (beta >= 0.0 && beta <= abs_dn) {
00549 if (alpha + beta <= abs_dn) {
00550 k1st = VDOT(wxb, tri_wn1st) / dn;
00551 fnd1 = 1;
00552 }
00553 }
00554 }
00555 }
00556 #endif
00557
00558
00559
00560
00561
00562
00563
00564 dn = VDOT(tri_wn2nd, rp->r_dir);
00565 if (dn >= 0.0) {
00566 dir2nd = 1;
00567 abs_dn = dn;
00568 } else {
00569 dir2nd = 0;
00570 abs_dn = -dn;
00571 }
00572 if (abs_dn < SQRT_SMALL_FASTF) goto leave;
00573 VSUB2(wxb, tri_A, rp->r_pt);
00574 VCROSS(xp, wxb, rp->r_dir);
00575 alpha = VDOT(tri_CA2nd, xp);
00576 if (dn <0.0) alpha = -alpha;
00577 if (alpha < 0.0 || alpha > abs_dn) goto leave;
00578 beta = VDOT(tri_BA2nd, xp);
00579 if (dn > 0.0) beta = -beta;
00580 if (beta < 0.0 || beta > abs_dn) goto leave;
00581 if (alpha+beta > abs_dn) goto leave;
00582 k2nd = VDOT(wxb, tri_wn2nd)/ dn;
00583 fnd2 = 1;
00584 leave:
00585 if (!fnd1 && !fnd2) return 0;
00586
00587 if (RT_G_DEBUG & DEBUG_HF) {
00588 bu_log("rt_hf_cell_shot: hit(%d).\n",fnd1+fnd2);
00589 }
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605 if (!fnd2 ) {
00606 hitp->hit_magic = RT_HIT_MAGIC;
00607 hitp->hit_dist = k1st;
00608 VMOVE(hitp->hit_normal, tri_wn1st);
00609 VUNITIZE(hitp->hit_normal);
00610 hitp->hit_surfno = yCell*hfp->hf_w+xCell;
00611 return 1;
00612 }
00613 if (!fnd1) {
00614 hitp->hit_magic = RT_HIT_MAGIC;
00615 hitp->hit_dist = k2nd;
00616 VMOVE(hitp->hit_normal, tri_wn2nd);
00617 VUNITIZE(hitp->hit_normal);
00618 hitp->hit_surfno = yCell*hfp->hf_w+xCell;
00619 return 1;
00620 }
00621 #if 0
00622 if (fabs(k1st) < fabs(k2nd)) {
00623 hitp->hit_magic = RT_HIT_MAGIC;
00624 hitp->hit_dist = k1st;
00625 VMOVE(hitp->hit_normal, tri_wn1st);
00626 VUNITIZE(hitp->hit_normal);
00627 hitp->hit_surfno = yCell*hfp->hf_w+xCell;
00628 return 1;
00629 } else {
00630 hitp->hit_magic = RT_HIT_MAGIC;
00631 hitp->hit_dist = k2nd;
00632 VMOVE(hitp->hit_normal, tri_wn2nd);
00633 VUNITIZE(hitp->hit_normal);
00634 hitp->hit_surfno = yCell*hfp->hf_w+xCell;
00635 return 1;
00636 }
00637 #else
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650 hitp->hit_magic = RT_HIT_MAGIC;
00651 hitp->hit_dist = k1st;
00652 VMOVE(hitp->hit_normal, tri_wn1st);
00653 VUNITIZE(hitp->hit_normal);
00654 hitp->hit_surfno = yCell*hfp->hf_w+xCell;
00655 hitp++;
00656
00657 if ((fabs(k1st-k2nd) < SMALL_FASTF) &&
00658 (dir1st + dir2nd != 1)) return 1;
00659
00660 hitp->hit_magic = RT_HIT_MAGIC;
00661 hitp->hit_dist = k2nd;
00662 VMOVE(hitp->hit_normal, tri_wn2nd);
00663 VUNITIZE(hitp->hit_normal);
00664 hitp->hit_surfno = yCell*hfp->hf_w+xCell;
00665 return 2;
00666 #endif
00667 }
00668
00669 #define MAXHITS 128
00670
00671
00672
00673
00674
00675
00676
00677 static void
00678 axis_plane_isect(int plane, fastf_t inout, struct xray *rp, struct hf_specific *hf, double xWidth, double yWidth, struct hit **hp, int *nhits)
00679 {
00680 double left, right, xx=0, xright=0, answer;
00681 vect_t loc;
00682 int CellX=0, CellY=0;
00683
00684 if (plane == -6) return;
00685
00686 if (plane == -3) {
00687 (*hp)->hit_magic = RT_HIT_MAGIC;
00688 (*hp)->hit_dist = inout;
00689 (*hp)->hit_surfno = plane;
00690 (*hp)++;
00691 if ((*nhits)++>=MAXHITS) rt_bomb("g_hf.c: too many hits.\n");
00692 return;
00693 }
00694
00695 VJOIN1(loc, rp->r_pt, inout, rp->r_dir);
00696 VSUB2(loc,loc,hf->hf_V);
00697
00698
00699 switch (plane) {
00700 case -1:
00701 CellY = loc[Y]/ yWidth;
00702 CellX = 0;
00703 xright = yWidth;
00704 xx = loc[Y] - (CellY* yWidth);
00705 break;
00706 case -2:
00707 CellY = 0;
00708 CellX = loc[X]/ xWidth;
00709 xright = xWidth;
00710 xx = loc[X] - CellX * xWidth;
00711 break;
00712 case -4:
00713 CellY = loc[Y]/ yWidth;
00714 CellX = hf->hf_n-1;
00715 xright = yWidth;
00716 xx = loc[Y] - (CellY* yWidth);
00717 break;
00718 case -5:
00719 CellY = hf->hf_w-1;
00720 CellX = loc[X]/ xWidth;
00721 xright = xWidth;
00722 xx = loc[X] - CellX* xWidth;
00723 break;
00724 }
00725 #if 1
00726 if (xx < 0) {
00727 bu_log("hf: xx < 0, plane = %d\n", plane);
00728 }
00729 #endif
00730
00731 if (hf->hf_shorts) {
00732 register unsigned short *sp;
00733 sp = (unsigned short *)hf->hf_mp->apbuf +
00734 CellY * hf->hf_w + CellX;
00735 left = *sp;
00736 if (plane == -2 || plane == -5) {
00737 sp++;
00738 } else {
00739 sp += hf->hf_w;
00740 }
00741 right = *sp;
00742 } else {
00743 register double *fp;
00744 fp = (double *) hf->hf_mp->apbuf +
00745 CellY * hf->hf_w + CellX;
00746 left = *fp;
00747 if (plane == -2 || plane == -5) {
00748 fp++;
00749 } else {
00750 fp += hf->hf_w;
00751 }
00752 right = *fp;
00753 }
00754 left *= hf->hf_file2mm;
00755 right *= hf->hf_file2mm;
00756 answer = (right-left)/xright*xx+left;
00757 #if 0
00758 bu_log("inout: loc[Z]=%g, answer=%g, left=%g, right=%g, xright=%g, xx=%g\n",
00759 loc[Z], answer, left, right, xright, xx);
00760 #endif
00761
00762 if (loc[Z]-SQRT_SMALL_FASTF < answer) {
00763 (*hp)->hit_magic = RT_HIT_MAGIC;
00764 (*hp)->hit_dist = inout;
00765 (*hp)->hit_surfno = plane;
00766 VJOIN1((*hp)->hit_point, rp->r_pt, inout, rp->r_dir);
00767 (*hp)++;
00768 if ((*nhits)++>=MAXHITS) rt_bomb("g_hf.c: too many hits.\n");
00769 }
00770 }
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785 int
00786 rt_hf_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
00787 {
00788 register struct hf_specific *hf =
00789 (struct hf_specific *)stp->st_specific;
00790
00791 LOCAL struct hit hits[MAXHITS];
00792 struct hit *hp;
00793 LOCAL int nhits;
00794 double xWidth, yWidth;
00795
00796 vect_t peqn;
00797 fastf_t pdist=0;
00798 fastf_t allDist[6];
00799 fastf_t cosine;
00800
00801 LOCAL int iplane, oplane, j;
00802 LOCAL fastf_t in, out;
00803 vect_t aray, curloc;
00804
00805 bzero(hits,sizeof(hits));
00806
00807 in = -INFINITY;
00808 out = INFINITY;
00809 iplane = oplane = 0;
00810
00811 nhits=0;
00812 hp = &hits[0];
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 for (j=-1; j>-7; j--) {
00824 FAST fastf_t dn;
00825 FAST fastf_t dxbdn;
00826 FAST fastf_t s;
00827 int allIndex;
00828
00829 switch (j) {
00830 case -1:
00831
00832 VREVERSE(peqn, hf->hf_X);
00833 pdist = VDOT(peqn, hf->hf_V);
00834 break;
00835 case -2:
00836
00837 VREVERSE(peqn, hf->hf_Y);
00838 pdist = VDOT(peqn, hf->hf_V);
00839 break;
00840 case -3:
00841
00842 VREVERSE(peqn, hf->hf_N);
00843 pdist = VDOT(peqn, hf->hf_V);
00844 break;
00845 case -4:
00846
00847 VMOVE(peqn, hf->hf_X);
00848 pdist = VDOT(peqn, hf->hf_VO);
00849 break;
00850 case -5:
00851
00852 VMOVE(peqn, hf->hf_Y);
00853 pdist = VDOT(peqn, hf->hf_VO);
00854 break;
00855 case -6:
00856
00857 VMOVE(peqn, hf->hf_N);
00858 pdist = VDOT(peqn, hf->hf_VO);
00859 break;
00860 }
00861 allIndex = abs(j)-1;
00862
00863 dxbdn = VDOT( peqn, rp->r_pt) - pdist;
00864 dn = -VDOT( peqn, rp->r_dir);
00865
00866 if (RT_G_DEBUG & DEBUG_HF) {
00867 VPRINT("hf: Plane Equation", peqn);
00868 bu_log("hf: dn=%g, dxbdn=%g, ", dn, dxbdn);
00869 }
00870
00871 if (dn < -SQRT_SMALL_FASTF) {
00872 allDist[allIndex] = s = dxbdn/dn;
00873 if ( out > s ) {
00874 out = s;
00875 oplane = j;
00876 }
00877 if (RT_G_DEBUG & DEBUG_HF) {
00878 bu_log("s=%g out=%g\n", s, out);
00879 }
00880 } else if (dn > SQRT_SMALL_FASTF) {
00881 allDist[allIndex] = s = dxbdn/dn;
00882 if ( in < s ) {
00883 in = s;
00884 iplane = j;
00885 }
00886 if (RT_G_DEBUG & DEBUG_HF) {
00887 bu_log("s=%g in=%g\n", s, in);
00888 }
00889 } else {
00890
00891
00892
00893
00894 if (RT_G_DEBUG & DEBUG_HF) {
00895 bu_log("s=DIVIDE_BY_ZERO\n");
00896 }
00897 if ( dxbdn > SQRT_SMALL_FASTF) {
00898 return 0;
00899 }
00900 allDist[allIndex] = INFINITY;
00901 }
00902 if ( in > out) {
00903 if (RT_G_DEBUG & DEBUG_HF) {
00904 bu_log("rt_hf_shoot(%s): in(%g) > out(%g)\n",
00905 stp->st_name, in, out);
00906 }
00907 return 0;
00908 }
00909 }
00910
00911 if ( iplane >= 0 || oplane >= 0 ) {
00912 bu_log("rt_hf_shoot(%s): 1 hit => MISS\n",
00913 stp->st_name);
00914 return 0;
00915 }
00916
00917 if ( fabs(in-out) < SMALL_FASTF || out >= INFINITY ) {
00918 if (RT_G_DEBUG & DEBUG_HF) {
00919 bu_log("rt_hf_shoot(%s): in(%g) >= out(%g) || out >= INFINITY\n",
00920 stp->st_name, in, out);
00921 }
00922 return 0;
00923 }
00924
00925
00926
00927
00928
00929
00930
00931
00932 xWidth = hf->hf_Xlen/((double)(hf->hf_w-1));
00933 yWidth = hf->hf_Ylen/((double)(hf->hf_n-1));
00934
00935 if (RT_G_DEBUG & DEBUG_HF) {
00936 bu_log("hf: xWidth=%g, yWidth=%g, in=%g, out=%g\n", xWidth,
00937 yWidth, in, out);
00938 }
00939
00940
00941
00942
00943
00944 axis_plane_isect(iplane, in, rp, hf, xWidth, yWidth, &hp, &nhits);
00945 axis_plane_isect(oplane, out, rp, hf, xWidth, yWidth, &hp, &nhits);
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 {
00962 vect_t tmp;
00963 VMOVE(tmp,rp->r_dir);
00964 tmp[Z] = 0.0;
00965 VUNITIZE(tmp);
00966 cosine = VDOT(tmp, hf->hf_X);
00967 }
00968 if (fabs(cosine) < SMALL_FASTF) {
00969 vect_t tmp;
00970 int xCell, yCell, r;
00971 if (RT_G_DEBUG & DEBUG_HF) {
00972 bu_log("hf: Vertical shoot\n");
00973 }
00974 VSUB2(tmp, rp->r_pt, hf->hf_V);
00975 xCell = tmp[X]/hf->hf_Xlen*hf->hf_w;
00976 yCell = tmp[Y]/hf->hf_Ylen*hf->hf_n;
00977 if ( (r=rt_hf_cell_shot(stp, rp, ap, hp, xCell, yCell)) ) {
00978 if ((nhits+=r)>MAXHITS) rt_bomb("g_hf.c: too many hits.\n");
00979 hp+=r;
00980 }
00981 } else if (cosine*cosine > 0.5) {
00982 double tmp;
00983 register double farZ, minZ, maxZ;
00984 int xCell, yCell, signX, signY;
00985 double highest,lowest, error,delta;
00986 double deltaZ;
00987
00988 vect_t goesIN, goesOUT;
00989
00990 VJOIN1(goesIN, rp->r_pt, allDist[3], rp->r_dir);
00991 VJOIN1(goesOUT,rp->r_pt, allDist[0], rp->r_dir);
00992 VSUB2(aray, goesOUT, goesIN);
00993 VSUB2(curloc, goesIN, hf->hf_V);
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003 tmp = xWidth/fabs(aray[X]);
01004
01005 #if 0
01006 bu_log("hf: tmp=%g\n", tmp);
01007 bu_log("hf: before VSCALE... aray=(%g,%g,%g)\n",
01008 aray[X], aray[Y], aray[Z]);
01009 #endif
01010
01011 VSCALE(aray, aray, tmp);
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024 xCell = curloc[X]/xWidth;
01025 tmp = curloc[Y];
01026 if (tmp < 0) {
01027 yCell = tmp/yWidth - 1;
01028 } else {
01029 yCell = tmp/yWidth;
01030 }
01031
01032 signX = (aray[X] < 0.0) ? -1 : 1;
01033 signY = (aray[Y] < 0.0) ? -1 : 1;
01034
01035 if (RT_G_DEBUG & DEBUG_HF ) {
01036 bu_log("hf: curloc=(%g, %g, %g) aray=(%g,%g,%g)\n", curloc[X], curloc[Y],
01037 curloc[Z], aray[X], aray[Y], aray[Z]);
01038 bu_log("hf: from=(%g, %g) to=(%g, %g)\n",
01039 goesIN[X]/xWidth,
01040 goesIN[Y]/yWidth,
01041 goesOUT[X]/xWidth,
01042 goesOUT[Y]/yWidth);
01043 }
01044 error = curloc[Y]-yCell*yWidth;
01045 error /= yWidth;
01046
01047
01048 delta = aray[Y]/fabs(aray[X]);
01049
01050 #if 0
01051 bu_log("aray[Y]/aray[X]=%g\n", delta);
01052 #endif
01053
01054 if (delta < 0.0) {
01055 delta = -delta;
01056 error = -error;
01057 } else {
01058 error -= 1.0;
01059 }
01060
01061
01062
01063
01064
01065 if (xCell >= hf->hf_w-1) {
01066 xCell+=signX;
01067 error += delta;
01068 }
01069 if (RT_G_DEBUG & DEBUG_HF) {
01070 bu_log("hf: delta=%g, error=%g, %d, %d\n",
01071 delta, error, xCell, yCell);
01072 }
01073
01074
01075 deltaZ = (aray[Z] < 0) ? -aray[Z] : aray[Z];
01076 do {
01077 farZ = curloc[Z] + aray[Z];
01078 maxZ = (curloc[Z] > farZ) ? curloc[Z] : farZ;
01079 minZ = (curloc[Z] < farZ) ? curloc[Z] : farZ;
01080 if (RT_G_DEBUG & DEBUG_HF) {
01081 bu_log("hf: cell %d,%d [%g -- %g]",
01082 xCell, yCell, minZ, maxZ);
01083 }
01084
01085
01086
01087
01088
01089 if (yCell < 0 || yCell > hf->hf_n-2) {
01090 if (error > -SQRT_SMALL_FASTF) {
01091 if (yCell >= -1) goto skip_first;
01092 yCell += signY;
01093 error -= 1.0;
01094 }
01095 xCell += signX;
01096 error += delta;
01097 VADD2(curloc, curloc, aray);
01098 continue;
01099 }
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109 if (hf->hf_shorts) {
01110 register unsigned short *sp;
01111 sp = (unsigned short *)hf->hf_mp->apbuf +
01112 yCell * hf->hf_w + xCell;
01113
01114 highest = lowest = *sp++;
01115
01116 if (lowest > (double)*sp) lowest=*sp;
01117 if (highest < (double)*sp) highest=*sp;
01118 sp+=hf->hf_w;
01119
01120 if (lowest > (double)*sp) lowest=*sp;
01121 if (highest < (double)*sp) highest=*sp;
01122 sp--;
01123
01124 if (lowest > (double)*sp) lowest = *sp;
01125 if (highest < (double)*sp) highest = *sp;
01126 lowest *= hf->hf_file2mm;
01127 highest *= hf->hf_file2mm;
01128 } else {
01129 register double *fp;
01130 fp = (double *)hf->hf_mp->apbuf +
01131 yCell * hf->hf_w + xCell;
01132
01133 highest = lowest = *fp++;
01134
01135 if (lowest > *fp) lowest=*fp;
01136 if (highest < *fp) highest=*fp;
01137 fp+=hf->hf_w;
01138
01139 if (lowest > *fp) lowest=*fp;
01140 if (highest < *fp) highest=*fp;
01141 fp--;
01142
01143 if (lowest > *fp) lowest = *fp;
01144 if (highest < *fp) highest = *fp;
01145 lowest *= hf->hf_file2mm;
01146 highest *= hf->hf_file2mm;
01147 }
01148
01149 if (RT_G_DEBUG & DEBUG_HF) {
01150 bu_log("lowest=%g, highest=%g\n",
01151 lowest, highest);
01152 }
01153
01154
01155
01156
01157
01158 #if 1
01159 if (maxZ+deltaZ > lowest &&
01160 minZ-deltaZ < highest ) {
01161 #else
01162 {
01163 #endif
01164 int r;
01165 if ( (r=rt_hf_cell_shot(stp, rp, ap, hp, xCell, yCell)) ) {
01166 if ((nhits+=r)>=MAXHITS) rt_bomb("g_hf.c: too many hits.\n");
01167 hp+=r;
01168 }
01169 }
01170
01171
01172
01173
01174 skip_first:
01175 if (error > SQRT_SMALL_FASTF) {
01176 yCell += signY;
01177 if (RT_G_DEBUG & DEBUG_HF) {
01178 bu_log("hf: cell %d,%d ", xCell, yCell);
01179 }
01180 if ((yCell < 0) || yCell > hf->hf_n-2) {
01181 error -= 1.0;
01182 xCell += signX;
01183 error += delta;
01184 VADD2(curloc, curloc, aray);
01185 continue;
01186 }
01187 if (hf->hf_shorts) {
01188 register unsigned short *sp;
01189 sp = (unsigned short *)hf->hf_mp->apbuf +
01190 yCell * hf->hf_w + xCell;
01191
01192 highest = lowest = *sp++;
01193
01194 if (lowest > (double)*sp) lowest=*sp;
01195 if (highest < (double)*sp) highest=*sp;
01196 sp+=hf->hf_w;
01197
01198 if (lowest > (double)*sp) lowest=*sp;
01199 if (highest < (double)*sp) highest=*sp;
01200 sp--;
01201
01202 if (lowest > (double)*sp) lowest = *sp;
01203 if (highest < (double)*sp) highest = *sp;
01204 lowest *= hf->hf_file2mm;
01205 highest *= hf->hf_file2mm;
01206 } else {
01207 register double *fp;
01208 fp = (double *)hf->hf_mp->apbuf +
01209 yCell * hf->hf_w + xCell;
01210
01211 highest = lowest = *fp++;
01212
01213 if (lowest > *fp) lowest=*fp;
01214 if (highest < *fp) highest=*fp;
01215 fp+=hf->hf_w;
01216
01217 if (lowest > *fp) lowest=*fp;
01218 if (highest < *fp) highest=*fp;
01219 fp--;
01220
01221 if (lowest > *fp) lowest = *fp;
01222 if (highest < *fp) highest = *fp;
01223 lowest *= hf->hf_file2mm;
01224 highest *= hf->hf_file2mm;
01225 }
01226 #if 1
01227 if (maxZ+deltaZ > lowest &&
01228 minZ-deltaZ < highest) {
01229 #else
01230 {
01231 #endif
01232 int r;
01233
01234 if ( (r=rt_hf_cell_shot(stp, rp, ap, hp, xCell, yCell)) ) {
01235 if ((nhits+=r)>=MAXHITS) rt_bomb("g_hf.c: too many hits.\n");
01236 hp+=r;
01237 }
01238 }
01239 error -= 1.0;
01240 } else if (error > -SQRT_SMALL_FASTF) {
01241 yCell += signY;
01242 error -= 1.0;
01243 }
01244 xCell += signX;
01245 error += delta;
01246 VADD2(curloc, curloc, aray);
01247 } while (xCell >= 0 && xCell < hf->hf_w-1 );
01248 if (RT_G_DEBUG & DEBUG_HF) {
01249 bu_log("htf: leaving loop, %d, %d, %g vs. 0--%d, 0--%d, 0.0--%g\n",
01250 xCell, yCell, curloc[Z], hf->hf_w-1, hf->hf_n-1, hf->hf_max);
01251 }
01252
01253 } else {
01254 double tmp;
01255 register double farZ, minZ, maxZ;
01256 double deltaZ;
01257 int xCell, yCell, signX, signY;
01258 double highest,lowest, error,delta;
01259
01260 vect_t goesIN, goesOUT;
01261
01262 VJOIN1(goesIN, rp->r_pt, allDist[4], rp->r_dir);
01263 VJOIN1(goesOUT,rp->r_pt, allDist[1], rp->r_dir);
01264 VSUB2(aray, goesOUT, goesIN);
01265 VSUB2(curloc, goesIN, hf->hf_V);
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275 tmp = yWidth/fabs(aray[Y]);
01276
01277 #if 0
01278 bu_log("hf: tmp=%g\n", tmp);
01279 bu_log("hf: before VSCALE... aray=(%g,%g,%g)\n",
01280 aray[X], aray[Y], aray[Z]);
01281 #endif
01282
01283 VSCALE(aray, aray, tmp);
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296 yCell = curloc[Y]/yWidth;
01297 tmp = curloc[X];
01298 if (tmp < 0) {
01299 xCell = tmp/xWidth - 1;
01300 } else {
01301 xCell = tmp/xWidth;
01302 }
01303
01304 signX = (aray[X] < 0.0) ? -1 : 1;
01305 signY = (aray[Y] < 0.0) ? -1 : 1;
01306
01307 if (RT_G_DEBUG & DEBUG_HF ) {
01308 bu_log("hf: curloc=(%g, %g, %g) aray=(%g,%g,%g)\n", curloc[X], curloc[Y],
01309 curloc[Z], aray[X], aray[Y], aray[Z]);
01310 bu_log("hf: from=(%g, %g) to=(%g, %g)\n",
01311 goesIN[X]/xWidth,
01312 goesIN[Y]/yWidth,
01313 goesOUT[X]/xWidth,
01314 goesOUT[Y]/yWidth);
01315 }
01316 error = curloc[X]-xCell*xWidth;
01317 error /= xWidth;
01318
01319
01320 delta = aray[X]/fabs(aray[Y]);
01321
01322 #if 0
01323 bu_log("aray[X]/aray[Y]=%g\n", delta);
01324 #endif
01325
01326 if (delta < 0.0) {
01327 delta = -delta;
01328 error = -error;
01329 } else {
01330 error -= 1.0;
01331 }
01332
01333
01334
01335
01336
01337 if (yCell >= hf->hf_n-1) {
01338 yCell+=signY;
01339 error += delta;
01340 }
01341 if (RT_G_DEBUG & DEBUG_HF) {
01342 bu_log("hf: delta=%g, error=%g, %d, %d\n",
01343 delta, error, xCell, yCell);
01344 }
01345
01346 deltaZ = (aray[Z] < 0) ? -aray[Z] : aray[Z];
01347 do {
01348 farZ = curloc[Z] + aray[Z];
01349 maxZ = (curloc[Z] > farZ) ? curloc[Z] : farZ;
01350 minZ = (curloc[Z] < farZ) ? curloc[Z] : farZ;
01351 if (RT_G_DEBUG & DEBUG_HF) {
01352 bu_log("hf: cell %d,%d [%g -- %g] ",
01353 xCell, yCell, minZ, maxZ);
01354 }
01355
01356 if (xCell < 0 || xCell > hf->hf_w-2) {
01357 if (error > -SQRT_SMALL_FASTF) {
01358 if (xCell >= -1) goto skip_2nd;
01359 xCell += signX;
01360 error -= 1.0;
01361 }
01362 yCell += signY;
01363 error += delta;
01364 VADD2(curloc, curloc, aray);
01365 continue;
01366 }
01367
01368 if (hf->hf_shorts) {
01369 register unsigned short *sp;
01370 sp = (unsigned short *)hf->hf_mp->apbuf +
01371 yCell * hf->hf_w + xCell;
01372
01373 highest = lowest = *sp++;
01374
01375 if (lowest > (double)*sp) lowest=*sp;
01376 if (highest < (double)*sp) highest=*sp;
01377 sp+=hf->hf_w;
01378
01379 if (lowest > (double)*sp) lowest=*sp;
01380 if (highest < (double)*sp) highest=*sp;
01381 sp--;
01382
01383 if (lowest > (double)*sp) lowest = *sp;
01384 if (highest < (double)*sp) highest = *sp;
01385 lowest *= hf->hf_file2mm;
01386 highest *= hf->hf_file2mm;
01387 } else {
01388 register double *fp;
01389 fp = (double *)hf->hf_mp->apbuf +
01390 yCell * hf->hf_w + xCell;
01391
01392 highest = lowest = *fp++;
01393
01394 if (lowest > *fp) lowest=*fp;
01395 if (highest < *fp) highest=*fp;
01396 fp+=hf->hf_w;
01397
01398 if (lowest > *fp) lowest=*fp;
01399 if (highest < *fp) highest=*fp;
01400 fp--;
01401
01402 if (lowest > *fp) lowest = *fp;
01403 if (highest < *fp) highest = *fp;
01404 lowest *= hf->hf_file2mm;
01405 highest *= hf->hf_file2mm;
01406 }
01407
01408
01409 if (RT_G_DEBUG & DEBUG_HF) {
01410 bu_log("lowest=%g, highest=%g\n",
01411 lowest, highest);
01412 }
01413
01414
01415
01416
01417
01418 #if 1
01419 if (maxZ+deltaZ > lowest &&
01420 minZ-deltaZ < highest ) {
01421 #else
01422 {
01423 #endif
01424 int r;
01425 if ( (r=rt_hf_cell_shot(stp, rp, ap, hp, xCell, yCell)) ) {
01426 if ((nhits+=r)>=MAXHITS) rt_bomb("g_hf.c: too many hits.\n");
01427 hp+=r;
01428 }
01429 }
01430
01431
01432
01433
01434 skip_2nd:
01435 if (error > SQRT_SMALL_FASTF) {
01436 xCell += signX;
01437 if (RT_G_DEBUG & DEBUG_HF) {
01438 bu_log("hf: cell %d,%d\n", xCell, yCell);
01439 }
01440 if ((xCell < 0) || xCell > hf->hf_w-2) {
01441 error -= 1.0;
01442 yCell += signY;
01443 error += delta;
01444 VADD2(curloc, curloc, aray);
01445 continue;
01446 }
01447 if (hf->hf_shorts) {
01448 register unsigned short *sp;
01449 sp = (unsigned short *)hf->hf_mp->apbuf +
01450 yCell * hf->hf_w + xCell;
01451
01452 highest = lowest = *sp++;
01453
01454 if (lowest > (double)*sp) lowest=*sp;
01455 if (highest < (double)*sp) highest=*sp;
01456 sp+=hf->hf_w;
01457
01458 if (lowest > (double)*sp) lowest=*sp;
01459 if (highest < (double)*sp) highest=*sp;
01460 sp--;
01461
01462 if (lowest > (double)*sp) lowest = *sp;
01463 if (highest < (double)*sp) highest = *sp;
01464 lowest *= hf->hf_file2mm;
01465 highest *= hf->hf_file2mm;
01466 } else {
01467 register double *fp;
01468 fp = (double *)hf->hf_mp->apbuf +
01469 yCell * hf->hf_w + xCell;
01470
01471 highest = lowest = *fp++;
01472
01473 if (lowest > *fp) lowest=*fp;
01474 if (highest < *fp) highest=*fp;
01475 fp+=hf->hf_w;
01476
01477 if (lowest > *fp) lowest=*fp;
01478 if (highest < *fp) highest=*fp;
01479 fp--;
01480
01481 if (lowest > *fp) lowest = *fp;
01482 if (highest < *fp) highest = *fp;
01483 lowest *= hf->hf_file2mm;
01484 highest *= hf->hf_file2mm;
01485 }
01486 #if 1
01487 if (maxZ+deltaZ > lowest &&
01488 minZ-deltaZ < highest) {
01489 #else
01490 {
01491 #endif
01492 int r;
01493
01494 if ( (r=rt_hf_cell_shot(stp, rp, ap, hp, xCell, yCell)) ) {
01495 if ((nhits+=r)>=MAXHITS) rt_bomb("g_hf.c: too many hits.\n");
01496 hp+=r;
01497 }
01498 }
01499 error -= 1.0;
01500 } else if (error > -SQRT_SMALL_FASTF) {
01501 xCell += signX;
01502 error -= 1.0;
01503 }
01504 yCell += signY;
01505 error += delta;
01506 VADD2(curloc, curloc, aray);
01507 } while (yCell >= 0 && yCell < hf->hf_n-1 );
01508 if (RT_G_DEBUG & DEBUG_HF) {
01509 bu_log("htf: leaving loop, %d, %d, %g vs. 0--%d, 0--%d, 0.0--%g\n",
01510 xCell, yCell, curloc[Z], hf->hf_w-1, hf->hf_n-1, hf->hf_max);
01511 }
01512 }
01513
01514 {
01515 register int i,j;
01516 LOCAL struct hit tmp;
01517 for ( i=0; i< nhits-1; i++) {
01518 for (j=i+1; j<nhits; j++) {
01519 if (hits[i].hit_dist <= hits[j].hit_dist) continue;
01520 tmp = hits[j];
01521 hits[j]=hits[i];
01522 hits[i]=tmp;
01523 }
01524 }
01525 }
01526 if ( nhits & 1) {
01527 register int i;
01528 static int nerrors = 0;
01529 hits[nhits] = hits[nhits-1];
01530 VREVERSE(hits[nhits].hit_normal, hits[nhits-1].hit_normal);
01531 nhits++;
01532 if (nerrors++ < 300 ) {
01533 bu_log("rt_hf_shot(%s): %d hit(s)@ %d %d: ", stp->st_name, nhits-1,ap->a_x, ap->a_y);
01534 for(i=0; i< nhits; i++) {
01535 bu_log("%f(%d), ",hits[i].hit_dist,hits[i].hit_surfno);
01536 }
01537 bu_log("\n");
01538 }
01539 #if 0
01540 rt_g.debug |= DEBUG_HF;
01541 rt_bomb("Odd number of hits.");
01542 #endif
01543 }
01544
01545 {
01546 register struct seg *segp;
01547 register int i;
01548 for (i=0; i< nhits; i+=2) {
01549 RT_GET_SEG(segp, ap->a_resource);
01550 segp->seg_stp = stp;
01551 segp->seg_in = hits[i];
01552 segp->seg_out= hits[i+1];
01553 BU_LIST_INSERT( &(seghead->l), &(segp->l));
01554 }
01555 }
01556 return nhits;
01557 }
01558
01559
01560
01561
01562
01563 void
01564 rt_hf_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp)
01565 {
01566 register struct hf_specific *hf =
01567 (struct hf_specific *)stp->st_specific;
01568 register int j;
01569
01570 j = hitp->hit_surfno;
01571
01572 VJOIN1( hitp->hit_point, rp->r_pt, hitp->hit_dist, rp->r_dir );
01573 if (j >= 0) {
01574
01575 return;
01576 }
01577
01578 switch (j) {
01579 case -1:
01580 VREVERSE(hitp->hit_normal, hf->hf_X);
01581 break;
01582 case -2:
01583 VREVERSE(hitp->hit_normal, hf->hf_Y);
01584 break;
01585 case -3:
01586 VREVERSE(hitp->hit_normal, hf->hf_N);
01587 break;
01588 case -4:
01589 VMOVE(hitp->hit_normal, hf->hf_X);
01590 break;
01591 case -5:
01592 VMOVE(hitp->hit_normal, hf->hf_Y);
01593 break;
01594 case -6:
01595 VMOVE(hitp->hit_normal, hf->hf_N);
01596 break;
01597 }
01598 VUNITIZE(hitp->hit_normal);
01599
01600 }
01601
01602
01603
01604
01605
01606
01607 void
01608 rt_hf_curve(register struct curvature *cvp, register struct hit *hitp, struct soltab *stp)
01609 {
01610 cvp->crv_c1 = cvp->crv_c2 = 0;
01611
01612
01613 bn_vec_ortho( cvp->crv_pdir, hitp->hit_normal );
01614 }
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624 void
01625 rt_hf_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
01626 {
01627 register struct hf_specific *hf =
01628 (struct hf_specific *)stp->st_specific;
01629 vect_t delta;
01630 fastf_t r = 0;
01631
01632 VSUB2(delta, hitp->hit_point, hf->hf_V);
01633 #if 0
01634 VUNITIZE(delta);
01635 uvp->uv_u = VDOT(delta, hf->hf_X);
01636 uvp->uv_v = VDOT(delta, hf->hf_Y);
01637 r = ap->a_rbeam + ap->a_diverge * hitp->hit_dist;
01638 #else
01639 uvp->uv_u = delta[X] / hf->hf_Xlen;
01640 uvp->uv_v = delta[Y] / hf->hf_Ylen;
01641 r = 0.0;
01642 #endif
01643 if (uvp->uv_u < 0.0) uvp->uv_u=0.0;
01644 if (uvp->uv_u > 1.0) uvp->uv_u=1.0;
01645 if (uvp->uv_v < 0.0) uvp->uv_v=0.0;
01646 if (uvp->uv_v > 1.0) uvp->uv_v=1.0;
01647
01648 uvp->uv_du = r;
01649 uvp->uv_dv = r;
01650 }
01651
01652
01653
01654
01655 void
01656 rt_hf_free(register struct soltab *stp)
01657 {
01658 register struct hf_specific *hf =
01659 (struct hf_specific *)stp->st_specific;
01660
01661 if (hf->hf_mp) {
01662 bu_close_mapped_file(hf->hf_mp);
01663 hf->hf_mp = (struct bu_mapped_file *)0;
01664 }
01665 bu_free( (char *)hf, "hf_specific" );
01666 }
01667
01668
01669
01670
01671 int
01672 rt_hf_class(void)
01673 {
01674 return(0);
01675 }
01676
01677
01678
01679
01680 int
01681 rt_hf_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
01682 {
01683 LOCAL struct rt_hf_internal *xip;
01684 register unsigned short *sp = (unsigned short *)NULL;
01685 register double *dp;
01686 vect_t xbasis;
01687 vect_t ybasis;
01688 vect_t zbasis;
01689 point_t start;
01690 point_t cur;
01691 int x;
01692 int y;
01693 int cmd;
01694 int step;
01695 int half_step;
01696 int goal;
01697
01698 RT_CK_DB_INTERNAL(ip);
01699 xip = (struct rt_hf_internal *)ip->idb_ptr;
01700 RT_HF_CK_MAGIC(xip);
01701
01702 VSCALE( xbasis, xip->x, xip->xlen / (xip->w - 1) );
01703 VSCALE( ybasis, xip->y, xip->ylen / (xip->n - 1) );
01704 VCROSS( zbasis, xip->x, xip->y );
01705 VSCALE( zbasis, zbasis, xip->zscale * xip->file2mm );
01706
01707
01708 goal = 20000;
01709
01710
01711 RT_ADD_VLIST( vhead, xip->v, BN_VLIST_LINE_MOVE );
01712
01713 VJOIN1( start, xip->v, xip->xlen, xip->x );
01714 RT_ADD_VLIST( vhead, start, BN_VLIST_LINE_DRAW );
01715
01716 VJOIN2( start, xip->v, xip->xlen, xip->x, xip->ylen, xip->y );
01717 RT_ADD_VLIST( vhead, start, BN_VLIST_LINE_DRAW );
01718
01719 VJOIN1( start, xip->v, xip->ylen, xip->y );
01720 RT_ADD_VLIST( vhead, start, BN_VLIST_LINE_DRAW );
01721
01722 RT_ADD_VLIST( vhead, xip->v, BN_VLIST_LINE_DRAW );
01723 goal -= 5;
01724
01725 #define HF_GET(_p,_x,_y) ((_p)[(_y)*xip->w+(_x)])
01726
01727
01728
01729 if (xip->shorts) {
01730
01731 RT_ADD_VLIST( vhead, xip->v, BN_VLIST_LINE_MOVE );
01732 sp = &HF_GET((unsigned short *)xip->mp->apbuf, 0, 0 );
01733 for( x = 0; x < xip->w; x++ ) {
01734 VJOIN2( cur, xip->v, x, xbasis, *sp, zbasis );
01735 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_DRAW );
01736 sp++;
01737 }
01738 VJOIN1( cur, xip->v, xip->xlen, xip->x );
01739 RT_ADD_VLIST( vhead, cur, BN_VLIST_LINE_DRAW );
01740
01741
01742 VJOIN1( start, xip->v, xip->ylen, xip->y );
01743 RT_ADD_VLIST( vhead, start, BN_VLIST_LINE_MOVE );
01744 sp = &HF_GET((unsigned short *)xip->mp->apbuf, 0, xip->n - 1 );
01745 VJOIN1( start, xip->v, xip->ylen, xip->y );
01746 for( x = 0; x < xip->w; x++ ) {
01747 VJOIN2( cur, start, x, xbasis, *sp, zbasis );
01748 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_DRAW );
01749 sp++;
01750 }
01751 VJOIN2( cur, xip->v, xip->xlen, xip->x, xip->ylen, xip->y );
01752 RT_ADD_VLIST( vhead, cur, BN_VLIST_LINE_DRAW );
01753
01754
01755 cmd = BN_VLIST_LINE_MOVE;
01756 sp = &HF_GET((unsigned short *)xip->mp->apbuf, 0, 0 );
01757 for( y = 0; y < xip->n; y++ ) {
01758 VJOIN2( cur, xip->v, y, ybasis, *sp, zbasis );
01759 RT_ADD_VLIST(vhead, cur, cmd );
01760 cmd = BN_VLIST_LINE_DRAW;
01761 sp += xip->w;
01762 }
01763
01764
01765 cmd = BN_VLIST_LINE_MOVE;
01766 sp = &HF_GET((unsigned short *)xip->mp->apbuf, xip->w - 1, 0 );
01767 VJOIN1( start, xip->v, xip->xlen, xip->x );
01768 for( y = 0; y < xip->n; y++ ) {
01769 VJOIN2( cur, start, y, ybasis, *sp, zbasis );
01770 RT_ADD_VLIST(vhead, cur, cmd );
01771 cmd = BN_VLIST_LINE_DRAW;
01772 sp += xip->w;
01773 }
01774 } else {
01775
01776 RT_ADD_VLIST( vhead, xip->v, BN_VLIST_LINE_MOVE );
01777 dp = &HF_GET((double *)xip->mp->apbuf, 0, 0 );
01778 for( x = 0; x < xip->w; x++ ) {
01779 VJOIN2( cur, xip->v, x, xbasis, *dp, zbasis );
01780 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_DRAW );
01781 dp++;
01782 }
01783 VJOIN1( cur, xip->v, xip->xlen, xip->x );
01784 RT_ADD_VLIST( vhead, cur, BN_VLIST_LINE_DRAW );
01785
01786
01787 VJOIN1( start, xip->v, xip->ylen, xip->y );
01788 RT_ADD_VLIST( vhead, start, BN_VLIST_LINE_MOVE );
01789 dp = &HF_GET((double *)xip->mp->apbuf, 0, xip->n - 1 );
01790 VJOIN1( start, xip->v, xip->ylen, xip->y );
01791 for( x = 0; x < xip->w; x++ ) {
01792 VJOIN2( cur, start, x, xbasis, *dp, zbasis );
01793 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_DRAW );
01794 dp++;
01795 }
01796 VJOIN2( cur, xip->v, xip->xlen, xip->x, xip->ylen, xip->y );
01797 RT_ADD_VLIST( vhead, cur, BN_VLIST_LINE_DRAW );
01798
01799
01800 cmd = BN_VLIST_LINE_MOVE;
01801 dp = &HF_GET((double *)xip->mp->apbuf, 0, 0 );
01802 for( y = 0; y < xip->n; y++ ) {
01803 VJOIN2( cur, xip->v, y, ybasis, *dp, zbasis );
01804 RT_ADD_VLIST(vhead, cur, cmd );
01805 cmd = BN_VLIST_LINE_DRAW;
01806 sp += xip->w;
01807 }
01808
01809
01810 cmd = BN_VLIST_LINE_MOVE;
01811 dp = &HF_GET((double *)xip->mp->apbuf, xip->w - 1, 0 );
01812 VJOIN1( start, xip->v, xip->xlen, xip->x );
01813 for( y = 0; y < xip->n; y++ ) {
01814 VJOIN2( cur, start, y, ybasis, *dp, zbasis );
01815 RT_ADD_VLIST(vhead, cur, cmd );
01816 cmd = BN_VLIST_LINE_DRAW;
01817 dp += xip->w;
01818 }
01819 }
01820 goal -= 4 + 2 * (xip->w + xip->n);
01821
01822
01823 if( ttol->rel ) {
01824 int rstep;
01825 rstep = xip->w;
01826 V_MAX( rstep, xip->n );
01827 step = (int)(ttol->rel * rstep);
01828 } else {
01829
01830 if( goal <= 0 ) return 0;
01831
01832
01833 step = ceil(sqrt( 2*(xip->w-1)*(xip->n-1) / (double)goal ));
01834 }
01835 if( step < 1 ) step = 1;
01836 if( (half_step = step/2) < 1 ) half_step = 1;
01837
01838
01839 for( y = half_step; y < xip->n-half_step; y += step ) {
01840 VJOIN1( start, xip->v, y, ybasis );
01841 x = 0;
01842 if (xip->shorts) {
01843 sp = &HF_GET((unsigned short *)xip->mp->apbuf, x, y );
01844 VJOIN2( cur, start, x, xbasis, *sp, zbasis );
01845 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_MOVE );
01846 x += half_step;
01847 sp = &HF_GET((unsigned short *)xip->mp->apbuf, x, y );
01848 for( ; x < xip->w; x += step ) {
01849 VJOIN2( cur, start, x, xbasis, *sp, zbasis );
01850 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_DRAW );
01851 sp += step;
01852 }
01853 if( x != step+xip->w-1+step ) {
01854 x = xip->w - 1;
01855 sp = &HF_GET((unsigned short *)xip->mp->apbuf, x, y );
01856 VJOIN2( cur, start, x, xbasis, *sp, zbasis );
01857 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_DRAW );
01858 }
01859 } else {
01860 dp = &HF_GET((double *)xip->mp->apbuf, x, y );
01861 VJOIN2( cur, start, x, xbasis, *dp, zbasis );
01862 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_MOVE );
01863 x += half_step;
01864 dp = &HF_GET((double *)xip->mp->apbuf, x, y);
01865 for (; x < xip->w; x+=step) {
01866 VJOIN2( cur, start, x, xbasis, *dp, zbasis);
01867 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_DRAW);
01868 dp += step;
01869 }
01870 if (x != step+xip->w-1+step) {
01871 x = xip->w - 1;
01872 dp = &HF_GET((double *)xip->mp->apbuf, x, y);
01873 VJOIN2( cur, start, x, xbasis, *dp, zbasis );
01874 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_DRAW);
01875 }
01876 }
01877 }
01878
01879
01880 if (xip->shorts) {
01881 for( x = half_step; x < xip->w-half_step; x += step ) {
01882 VJOIN1( start, xip->v, x, xbasis );
01883 y = 0;
01884 sp = &HF_GET((unsigned short *)xip->mp->apbuf, x, y );
01885 VJOIN2( cur, start, y, ybasis, *sp, zbasis );
01886 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_MOVE );
01887 y += half_step;
01888 for( ; y < xip->n; y += step ) {
01889 sp = &HF_GET((unsigned short *)xip->mp->apbuf, x, y );
01890 VJOIN2( cur, start, y, ybasis, *sp, zbasis );
01891 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_DRAW );
01892 }
01893 if( y != step+xip->n-1+step ) {
01894 y = xip->n - 1;
01895 sp = &HF_GET((unsigned short *)xip->mp->apbuf, x, y );
01896 VJOIN2( cur, start, y, ybasis, *sp, zbasis );
01897 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_DRAW );
01898 }
01899 }
01900 } else {
01901 for( x = half_step; x < xip->w-half_step; x += step ) {
01902 VJOIN1( start, xip->v, x, xbasis );
01903 y = 0;
01904 dp = &HF_GET((double *)xip->mp->apbuf, x, y );
01905 VJOIN2( cur, start, y, ybasis, *dp, zbasis );
01906 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_MOVE );
01907 y += half_step;
01908 for( ; y < xip->n; y += step ) {
01909 dp = &HF_GET((double *)xip->mp->apbuf, x, y );
01910 VJOIN2( cur, start, y, ybasis, *dp, zbasis );
01911 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_DRAW );
01912 }
01913 if( y != step+xip->n-1+step ) {
01914 y = xip->n - 1;
01915 dp = &HF_GET((double *)xip->mp->apbuf, x, y );
01916 VJOIN2( cur, start, y, ybasis, *dp, zbasis );
01917 RT_ADD_VLIST(vhead, cur, BN_VLIST_LINE_DRAW );
01918 }
01919 }
01920 }
01921 return 0;
01922 }
01923
01924
01925
01926
01927
01928
01929
01930
01931 int
01932 rt_hf_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
01933 {
01934 LOCAL struct rt_hf_internal *xip;
01935
01936 RT_CK_DB_INTERNAL(ip);
01937 xip = (struct rt_hf_internal *)ip->idb_ptr;
01938 RT_HF_CK_MAGIC(xip);
01939
01940 return(-1);
01941 }
01942
01943
01944
01945
01946
01947
01948
01949 int
01950 rt_hf_import(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
01951 {
01952 LOCAL struct rt_hf_internal *xip;
01953 union record *rp;
01954 struct bu_vls str;
01955 struct bu_mapped_file *mp;
01956 vect_t tmp;
01957 int in_cookie;
01958 int in_len;
01959 int out_cookie;
01960 int count;
01961 int got;
01962
01963 BU_CK_EXTERNAL( ep );
01964 rp = (union record *)ep->ext_buf;
01965
01966 if( rp->u_id != DBID_STRSOL ) {
01967 bu_log("rt_hf_import: defective record\n");
01968 return(-1);
01969 }
01970
01971 RT_CK_DB_INTERNAL( ip );
01972 ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
01973 ip->idb_type = ID_HF;
01974 ip->idb_meth = &rt_functab[ID_HF];
01975 ip->idb_ptr = bu_calloc( 1, sizeof(struct rt_hf_internal), "rt_hf_internal");
01976 xip = (struct rt_hf_internal *)ip->idb_ptr;
01977 xip->magic = RT_HF_INTERNAL_MAGIC;
01978
01979
01980 xip->shorts = 1;
01981 xip->file2mm = 1.0;
01982 VSETALL( xip->v, 0 );
01983 VSET( xip->x, 1, 0, 0 );
01984 VSET( xip->y, 0, 1, 0 );
01985 xip->xlen = 1000;
01986 xip->ylen = 1000;
01987 xip->zscale = 1;
01988 strcpy( xip->fmt, "nd" );
01989
01990
01991 bu_vls_init( &str );
01992 bu_vls_strcpy( &str, rp->ss.ss_args );
01993 if( bu_struct_parse( &str, rt_hf_parse, (char *)xip ) < 0 ) {
01994 bu_vls_free( &str );
01995 err1:
01996 bu_free( (char *)xip , "rt_hf_import: xip" );
01997 ip->idb_type = ID_NULL;
01998 ip->idb_ptr = (genptr_t)NULL;
01999 return -2;
02000 }
02001 bu_vls_free( &str );
02002
02003
02004 if( xip->cfile[0] ) {
02005 FILE *fp;
02006
02007 bu_semaphore_acquire( BU_SEM_SYSCALL );
02008 fp = fopen( xip->cfile, "r" );
02009 bu_semaphore_release( BU_SEM_SYSCALL );
02010 if( !fp ) {
02011 perror(xip->cfile);
02012 bu_log("rt_hf_import() unable to open cfile=%s\n", xip->cfile);
02013 goto err1;
02014 }
02015 bu_vls_init( &str );
02016 while( bu_vls_gets( &str, fp ) >= 0 )
02017 bu_vls_strcat( &str, " " );
02018 bu_semaphore_acquire( BU_SEM_SYSCALL );
02019 fclose(fp);
02020 bu_semaphore_release( BU_SEM_SYSCALL );
02021 if( bu_struct_parse( &str, rt_hf_cparse, (char *)xip ) < 0 ) {
02022 bu_log("rt_hf_import() parse error in cfile input '%s'\n",
02023 bu_vls_addr(&str) );
02024 bu_vls_free( &str );
02025 goto err1;
02026 }
02027 }
02028
02029
02030 if( !xip->dfile[0] ) {
02031
02032 bu_log("rt_hf_import() no dfile specified\n");
02033 goto err1;
02034 }
02035 if( xip->w < 2 || xip->n < 2 ) {
02036 bu_log("rt_hf_import() w=%d, n=%d too small\n");
02037 goto err1;
02038 }
02039 if( xip->xlen <= 0 || xip->ylen <= 0 ) {
02040 bu_log("rt_hf_import() xlen=%g, ylen=%g too small\n", xip->xlen, xip->ylen);
02041 goto err1;
02042 }
02043
02044
02045 MAT4X3PNT( tmp, mat, xip->v );
02046 VMOVE( xip->v, tmp );
02047 MAT4X3VEC( tmp, mat, xip->x );
02048 VMOVE( xip->x, tmp );
02049 MAT4X3VEC( tmp, mat, xip->y );
02050 VMOVE( xip->y, tmp );
02051 xip->xlen /= mat[15];
02052 xip->ylen /= mat[15];
02053 xip->zscale /= mat[15];
02054
02055 VUNITIZE(xip->x);
02056 VUNITIZE(xip->y);
02057
02058
02059 if( (in_cookie = bu_cv_cookie( xip->fmt )) == 0 ) {
02060 bu_log("rt_hf_import() fmt='%s' unknown\n", xip->fmt);
02061 goto err1;
02062 }
02063 in_len = bu_cv_itemlen( in_cookie );
02064
02065
02066
02067
02068 if( !(mp = bu_open_mapped_file( xip->dfile, "hf" )) ) {
02069 bu_log("rt_hf_import() unable to open '%s'\n", xip->dfile);
02070 goto err1;
02071 }
02072 xip->mp = mp;
02073 count = mp->buflen / in_len;
02074
02075
02076 if( mp->apbuf ) return 0;
02077
02078
02079 if( xip->shorts ) {
02080 mp->apbuflen = sizeof(unsigned short) * count;
02081 out_cookie = bu_cv_cookie("hus");
02082 } else {
02083 mp->apbuflen = sizeof(double) * count;
02084 out_cookie = bu_cv_cookie("hd");
02085 }
02086
02087 if( bu_cv_optimize(in_cookie) == bu_cv_optimize(out_cookie) ) {
02088
02089 mp->apbuf = mp->buf;
02090 return 0;
02091 }
02092
02093 mp->apbuf = (genptr_t)bu_malloc( mp->apbuflen, "rt_hf_import apbuf[]" );
02094 got = bu_cv_w_cookie( mp->apbuf, out_cookie, mp->apbuflen,
02095 mp->buf, in_cookie, count );
02096 if( got != count ) {
02097 bu_log("rt_hf_import(%s) bu_cv_w_cookie count=%d, got=%d\n",
02098 xip->dfile, count, got );
02099 }
02100
02101 return(0);
02102 }
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118 int
02119 rt_hf_export(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
02120 {
02121 struct rt_hf_internal *xip;
02122 union record *rec;
02123 struct bu_vls str;
02124
02125 RT_CK_DB_INTERNAL(ip);
02126 if( ip->idb_type != ID_HF ) return(-1);
02127 xip = (struct rt_hf_internal *)ip->idb_ptr;
02128 RT_HF_CK_MAGIC(xip);
02129
02130
02131 xip->xlen /= local2mm;
02132 xip->ylen /= local2mm;
02133 xip->zscale /= local2mm;
02134
02135 BU_CK_EXTERNAL(ep);
02136 ep->ext_nbytes = sizeof(union record) * DB_SS_NGRAN;
02137 ep->ext_buf = (genptr_t)bu_calloc( 1, ep->ext_nbytes, "hf external");
02138 rec = (union record *)ep->ext_buf;
02139
02140 bu_vls_init( &str );
02141 bu_vls_struct_print( &str, rt_hf_parse, (char *)xip );
02142
02143
02144
02145
02146
02147 rec->s.s_id = DBID_STRSOL;
02148 strncpy( rec->ss.ss_keyword, "hf", NAMESIZE-1 );
02149 strncpy( rec->ss.ss_args, bu_vls_addr(&str), DB_SS_LEN-1 );
02150 bu_vls_free( &str );
02151
02152 return(0);
02153 }
02154
02155 int
02156 rt_hf_import5(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
02157 {
02158 bu_log( "As of release 6.0 the HF primitive is superceded by the DSP primitive.\n" );
02159 bu_log( "\tTo convert HF primitives to DSP, use 'dbupgrade'.\n");
02160
02161 return -1;
02162 }
02163
02164 int
02165 rt_hf_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
02166 {
02167 bu_log( "As of release 6.0 the HF primitive is superceded by the DSP primitive.\n" );
02168 bu_log( "\tTo convert HF primitives to DSP, use 'dbupgrade'.\n" );
02169
02170 return -1;
02171 }
02172
02173
02174
02175
02176
02177
02178
02179
02180 int
02181 rt_hf_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
02182 {
02183 #ifndef NO_MAGIC_CHECKING
02184 register struct rt_hf_internal *xip =
02185 (struct rt_hf_internal *)ip->idb_ptr;
02186
02187 BU_CK_VLS(str);
02188 RT_HF_CK_MAGIC(xip);
02189 #endif
02190 bu_vls_printf( str, "Height Field (HF) mm2local=%g\n", mm2local);
02191 bu_vls_struct_print( str, rt_hf_parse, ip->idb_ptr );
02192 bu_vls_strcat( str, "\n" );
02193
02194 return(0);
02195 }
02196
02197
02198
02199
02200
02201
02202 void
02203 rt_hf_ifree(struct rt_db_internal *ip)
02204 {
02205 register struct rt_hf_internal *xip;
02206
02207 RT_CK_DB_INTERNAL(ip);
02208 xip = (struct rt_hf_internal *)ip->idb_ptr;
02209 RT_HF_CK_MAGIC(xip);
02210 xip->magic = 0;
02211
02212 if( xip->mp )
02213 {
02214 BU_CK_MAPPED_FILE(xip->mp);
02215 bu_close_mapped_file(xip->mp);
02216 }
02217
02218 bu_free( (char *)xip, "hf ifree" );
02219 ip->idb_ptr = GENPTR_NULL;
02220 }
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231