00001 #define FULL_DSP_DEBUGGING 1
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 #ifndef lint
00042 static const char RCSdsp[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/g_dsp.c,v 14.12 2006/09/16 02:04:24 lbutler Exp $ (BRL)";
00043 #endif
00044
00045 #include "common.h"
00046
00047 #include <stddef.h>
00048 #include <stdio.h>
00049 #include <string.h>
00050 #include <math.h>
00051 #include <setjmp.h>
00052
00053 #include "machine.h"
00054 #include "vmath.h"
00055 #include "db.h"
00056 #include "nmg.h"
00057 #include "raytrace.h"
00058 #include "rtgeom.h"
00059 #include "./debug.h"
00060 #include "plot3.h"
00061
00062 #define ORDERED_ISECT 1
00063
00064
00065 #define DIM_BB_CHILDREN 4
00066 #define NUM_BB_CHILDREN (DIM_BB_CHILDREN*DIM_BB_CHILDREN)
00067
00068 struct dsp_rpp {
00069 unsigned short dsp_min[3];
00070 unsigned short dsp_max[3];
00071 };
00072
00073
00074
00075
00076
00077 struct dsp_bb {
00078 long magic;
00079 struct dsp_rpp dspb_rpp;
00080
00081
00082
00083
00084
00085
00086
00087 unsigned short dspb_subcell_size;
00088 unsigned short dspb_ch_dim[2];
00089 struct dsp_bb *dspb_children[NUM_BB_CHILDREN];
00090 };
00091 #define MAGIC_dsp_bb 234
00092 #define DSP_BB_CK(_p) BU_CKMAG(_p, MAGIC_dsp_bb, "dsp_bb")
00093
00094
00095
00096
00097 #define LAYER(l, x,y) l->p[l->dim[1]*y+x]
00098 struct dsp_bb_layer {
00099 int dim[2];
00100 struct dsp_bb *p;
00101 };
00102
00103
00104
00105 extern int rt_retrieve_binunif(struct rt_db_internal *intern,
00106 const struct db_i *dbip,
00107 const char *name);
00108
00109 extern void rt_binunif_ifree( struct rt_db_internal *ip );
00110
00111
00112 #define dlog if (RT_G_DEBUG & DEBUG_HF) bu_log
00113
00114
00115 #define BBOX_PLANES 7
00116 #define XMIN 0
00117 #define XMAX 1
00118 #define YMIN 2
00119 #define YMAX 3
00120 #define ZMIN 4
00121 #define ZMAX 5
00122 #define ZMID 6
00123 #define ZTOP 7
00124
00125
00126
00127
00128
00129
00130
00131
00132 struct dsp_specific {
00133 struct rt_dsp_internal dsp_i;
00134 double dsp_pl_dist[BBOX_PLANES];
00135 int xsiz;
00136 int ysiz;
00137 int layers;
00138 struct dsp_bb_layer *layer;
00139 struct dsp_bb *bb_array;
00140 };
00141
00142
00143
00144
00145 #ifdef FULL_DSP_DEBUGGING
00146 #define DSP(_p,_x,_y) dsp_val(_p, _x, _y, __FILE__, __LINE__)
00147 unsigned short
00148 dsp_val(struct rt_dsp_internal *dsp_i, unsigned x, unsigned y, char *file, int line)
00149 {
00150 RT_DSP_CK_MAGIC(dsp_i);
00151
00152 if (x >= dsp_i->dsp_xcnt || y >= dsp_i->dsp_ycnt) {
00153 bu_log("%s:%d xy: %u,%u cnt: %u,%u\n",
00154 file, line, x, y, dsp_i->dsp_xcnt, dsp_i->dsp_ycnt);
00155 bu_bomb("");
00156 }
00157
00158 return dsp_i->dsp_buf[ y * dsp_i->dsp_xcnt + x ];
00159 }
00160 #else
00161 # define DSP(_p,_x,_y) ( \
00162 ( \
00163 (unsigned short *) \
00164 ((_p)->dsp_buf) \
00165 )[ \
00166 (_y) * ((struct rt_dsp_internal *)_p)->dsp_xcnt + (_x) ] )
00167 #endif
00168
00169 # define XCNT(_p) (((struct rt_dsp_internal *)_p)->dsp_xcnt)
00170 # define YCNT(_p) (((struct rt_dsp_internal *)_p)->dsp_ycnt)
00171 # define XSIZ(_p) (_p->dsp_i.dsp_xcnt - 1)
00172 # define YSIZ(_p) (_p->dsp_i.dsp_ycnt - 1)
00173
00174
00175
00176
00177 struct bbox_isect {
00178 double in_dist;
00179 double out_dist;
00180 int in_surf;
00181 int out_surf;
00182 };
00183
00184
00185
00186
00187
00188 struct isect_stuff {
00189 struct dsp_specific *dsp;
00190 struct bu_list seglist;
00191 struct xray r;
00192 vect_t inv_dir;
00193 struct application *ap;
00194 struct soltab *stp;
00195 struct bn_tol *tol;
00196
00197 struct bbox_isect bbox;
00198 struct bbox_isect minbox;
00199
00200 int num_segs;
00201 int dmin, dmax;
00202 };
00203
00204
00205
00206
00207
00208 static const vect_t dsp_pl[BBOX_PLANES] = {
00209 {-1.0, 0.0, 0.0},
00210 { 1.0, 0.0, 0.0},
00211
00212 {0.0, -1.0, 0.0},
00213 {0.0, 1.0, 0.0},
00214
00215 {0.0, 0.0, -1.0},
00216 {0.0, 0.0, 1.0},
00217 {0.0, 0.0, 1.0},
00218 };
00219
00220
00221
00222
00223
00224 static void
00225 hook_mtos_from_stom(
00226 const struct bu_structparse *ip,
00227 const char *sp_name,
00228 genptr_t base,
00229 char *p)
00230 {
00231 struct rt_dsp_internal *dsp_ip = (struct rt_dsp_internal *)base;
00232
00233 bn_mat_inv(dsp_ip->dsp_mtos, dsp_ip->dsp_stom);
00234 }
00235 static void
00236 hook_file(
00237 const struct bu_structparse *ip,
00238 const char *sp_name,
00239 genptr_t base,
00240 char *p)
00241 {
00242 struct rt_dsp_internal *dsp_ip = (struct rt_dsp_internal *)base;
00243
00244 dsp_ip->dsp_datasrc = RT_DSP_SRC_V4_FILE;
00245 dsp_ip->dsp_bip = (struct rt_db_internal *)NULL;
00246 }
00247
00248 #define DSP_O(m) bu_offsetof(struct rt_dsp_internal, m)
00249 #define DSP_AO(a) bu_offsetofarray(struct rt_dsp_internal, a)
00250
00251
00252
00253
00254 const struct bu_structparse rt_dsp_parse[] = {
00255 {"%S", 1, "file", DSP_O(dsp_name), hook_file },
00256 {"%i", 1, "sm", DSP_O(dsp_smooth), BU_STRUCTPARSE_FUNC_NULL },
00257 {"%d", 1, "w", DSP_O(dsp_xcnt), BU_STRUCTPARSE_FUNC_NULL },
00258 {"%d", 1, "n", DSP_O(dsp_ycnt), BU_STRUCTPARSE_FUNC_NULL },
00259 {"%f", 16, "stom", DSP_AO(dsp_stom), hook_mtos_from_stom },
00260 {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL }
00261 };
00262
00263 const struct bu_structparse rt_dsp_ptab[] = {
00264 {"%S", 1, "file", DSP_O(dsp_name), BU_STRUCTPARSE_FUNC_NULL },
00265 {"%i", 1, "sm", DSP_O(dsp_smooth), BU_STRUCTPARSE_FUNC_NULL },
00266 {"%d", 1, "w", DSP_O(dsp_xcnt), BU_STRUCTPARSE_FUNC_NULL },
00267 {"%d", 1, "n", DSP_O(dsp_ycnt), BU_STRUCTPARSE_FUNC_NULL },
00268 {"%f", 16, "stom", DSP_AO(dsp_stom), BU_STRUCTPARSE_FUNC_NULL },
00269 {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL }
00270 };
00271
00272
00273
00274
00275
00276
00277 static int plot_file_num=0;
00278
00279
00280
00281
00282
00283
00284
00285 static void
00286 plot_rpp(FILE *fp, struct bound_rpp *rpp, int r, int g, int b)
00287 {
00288 pl_color(fp, r, g, b);
00289
00290 pd_3move(fp, rpp->min[X], rpp->min[Y], rpp->min[Z]);
00291 pd_3cont(fp, rpp->max[X], rpp->min[Y], rpp->min[Z]);
00292 pd_3cont(fp, rpp->max[X], rpp->max[Y], rpp->min[Z]);
00293 pd_3cont(fp, rpp->min[X], rpp->max[Y], rpp->min[Z]);
00294 pd_3cont(fp, rpp->min[X], rpp->min[Y], rpp->min[Z]);
00295
00296 pd_3cont(fp, rpp->min[X], rpp->min[Y], rpp->max[Z]);
00297 pd_3cont(fp, rpp->max[X], rpp->min[Y], rpp->max[Z]);
00298 pd_3cont(fp, rpp->max[X], rpp->max[Y], rpp->max[Z]);
00299 pd_3cont(fp, rpp->min[X], rpp->max[Y], rpp->max[Z]);
00300 pd_3cont(fp, rpp->min[X], rpp->min[Y], rpp->max[Z]);
00301 }
00302
00303
00304
00305
00306
00307
00308 static void
00309 plot_dsp_bb(FILE *fp, struct dsp_bb *dsp_bb,
00310 struct dsp_specific *dsp,
00311 int r, int g, int b, int blather)
00312 {
00313 fastf_t *stom = &dsp->dsp_i.dsp_stom[0];
00314 struct bound_rpp rpp;
00315 point_t pt;
00316
00317 DSP_BB_CK(dsp_bb);
00318
00319 VMOVE(pt, dsp_bb->dspb_rpp.dsp_min);
00320 MAT4X3PNT(rpp.min, stom, pt);
00321
00322 VMOVE(pt, dsp_bb->dspb_rpp.dsp_max);
00323 MAT4X3PNT(rpp.max, stom, pt);
00324
00325 if (blather)
00326 bu_log(" (%g %g %g) (%g %g %g)\n",
00327 V3ARGS(rpp.min), V3ARGS(rpp.max) );
00328
00329 plot_rpp(fp, &rpp, r, g, b);
00330 }
00331
00332
00333
00334 static FILE *
00335 draw_dsp_bb(int *plotnum,
00336 struct dsp_bb *dsp_bb,
00337 struct dsp_specific *dsp,
00338 int r, int g, int b)
00339 {
00340 char buf[64];
00341 FILE *fp;
00342 struct dsp_bb bb;
00343
00344 sprintf(buf, "dsp_bb%03d.pl", (*plotnum)++);
00345 if ( (fp=fopen(buf, "w")) == (FILE *)NULL) {
00346 perror(buf);
00347 bu_bomb("");
00348 }
00349
00350 bu_log("plotting %s", buf);
00351 bb = *dsp_bb;
00352 bb.dspb_rpp.dsp_min[Z] = 0.0;
00353 plot_dsp_bb(fp, &bb, dsp, r, g, b, 1);
00354
00355 return fp;
00356 }
00357
00358 #define PLOT_LAYERS
00359 #ifdef PLOT_LAYERS
00360
00361
00362
00363
00364
00365 static void
00366 plot_layers(struct dsp_specific *dsp_sp)
00367 {
00368 FILE *fp;
00369 int l, x, y, n;
00370 char buf[32];
00371 static int colors[7][3] = {
00372 {255, 0, 0},
00373 {0, 255, 0},
00374 {0, 0, 255},
00375 {255, 255, 0},
00376 {255, 0, 255},
00377 {0, 255, 255},
00378 {255, 255, 255}
00379 };
00380 int r, g, b, c;
00381 struct dsp_bb *d_bb;
00382
00383 for (l=0 ; l < dsp_sp->layers ; l++) {
00384 bu_semaphore_acquire( BU_SEM_SYSCALL);
00385 sprintf(buf, "Dsp_layer%d.pl", l);
00386 fp=fopen(buf, "w");
00387 bu_semaphore_release( BU_SEM_SYSCALL);
00388 if ( fp == (FILE *)NULL ) {
00389 bu_log("%s:%d error opening %s\n", __FILE__, __LINE__,
00390 buf);
00391 return;
00392 } else
00393 bu_log("plotting \"%s\" dim:%d,%d\n", buf,
00394 dsp_sp->layer[l].dim[X],
00395 dsp_sp->layer[l].dim[Y]);
00396 c = l % 6;
00397 r = colors[c][0];
00398 g = colors[c][1];
00399 b = colors[c][2];
00400
00401 for (y=0 ; y < dsp_sp->layer[l].dim[Y] ; y+= 2 ) {
00402 for (x=0 ; x < dsp_sp->layer[l].dim[X] ; x+= 2 ) {
00403 n = y * dsp_sp->layer[l].dim[X] + x;
00404 d_bb = &dsp_sp->layer[l].p[n];
00405 plot_dsp_bb(fp, d_bb, dsp_sp, r, g, b, 0);
00406
00407 #if 0
00408 if (RT_G_DEBUG & DEBUG_HF)
00409 bu_log("\t%d,%d ch_dim:%d,%d min:(%d %d %d) max:(%d %d %d)\n",
00410 x, y,
00411 d_bb->dspb_ch_dim[X],
00412 d_bb->dspb_ch_dim[Y],
00413 V3ARGS(d_bb->dspb_rpp.dsp_min),
00414 V3ARGS(d_bb->dspb_rpp.dsp_max));
00415 #endif
00416 }
00417 }
00418 fclose(fp);
00419 }
00420 }
00421 #endif
00422
00423
00424
00425
00426
00427
00428 static void
00429 plot_cell_top(struct isect_stuff *isect,
00430 struct dsp_bb *dsp_bb,
00431 point_t A,
00432 point_t B,
00433 point_t C,
00434 point_t D,
00435 struct hit hitlist[],
00436 int hitflags,
00437 int style)
00438 {
00439 fastf_t *stom = &isect->dsp->dsp_i.dsp_stom[0];
00440 char buf[64];
00441 static int plotcnt = 0;
00442 static int cnt = 0;
00443 FILE *fp;
00444 point_t p1, p2, p3, p4;
00445 int i;
00446 int in_seg;
00447 static unsigned char colors[4][3] = {
00448 {255, 255, 128},
00449 {255, 128, 255},
00450 {128, 255, 128},
00451 {128, 255, 255},
00452 };
00453
00454 DSP_BB_CK(dsp_bb);
00455
00456 bu_semaphore_acquire( BU_SEM_SYSCALL);
00457 if (style)
00458 sprintf(buf, "dsp_cell_isect%04d.pl", cnt++);
00459 else
00460 sprintf(buf, "dsp_cell_top%04d.pl", plotcnt++);
00461
00462 fp=fopen(buf, "w");
00463
00464 bu_semaphore_release( BU_SEM_SYSCALL);
00465
00466 if ( fp == (FILE *)NULL) {
00467 bu_log("error opening \"%s\"\n", buf);
00468 return;
00469 } else {
00470 bu_log("plotting %s flags 0x%x\n\t", buf, hitflags);
00471 }
00472
00473 plot_dsp_bb(fp, dsp_bb, isect->dsp, 128, 128, 128, 1);
00474
00475
00476 pl_color(fp, 255, 255, 255);
00477 MAT4X3PNT(p1, stom, A);
00478 MAT4X3PNT(p2, stom, B);
00479 MAT4X3PNT(p3, stom, C);
00480 MAT4X3PNT(p4, stom, D);
00481
00482 pdv_3move(fp, p1);
00483 if (style) {
00484 pdv_3cont(fp, p2);
00485 pdv_3cont(fp, p4);
00486 pdv_3cont(fp, p1);
00487 pdv_3cont(fp, p3);
00488 pdv_3cont(fp, p4);
00489 } else {
00490 pdv_3cont(fp, p2);
00491 pdv_3cont(fp, p4);
00492 pdv_3cont(fp, p3);
00493 pdv_3cont(fp, p1);
00494 }
00495
00496
00497
00498 for (in_seg = 0, i = 0 ; i < 4 ; i++ ) {
00499 if (hitflags & (1<<i)) {
00500 if (in_seg) {
00501 in_seg = 0;
00502 MAT4X3PNT(p1, stom, hitlist[i].hit_point);
00503 pdv_3cont(fp, p1);
00504 } else {
00505 in_seg = 1;
00506 pl_color(fp, colors[i][0], colors[i][1], colors[i][2]);
00507 MAT4X3PNT(p1, stom, hitlist[i].hit_point);
00508 pdv_3move(fp, p1);
00509 }
00510 }
00511 }
00512 fclose(fp);
00513 }
00514
00515
00516
00517 static void
00518 dsp_print_v4(struct bu_vls *vls, const struct rt_dsp_internal *dsp_ip)
00519 {
00520 point_t pt, v;
00521 RT_DSP_CK_MAGIC(dsp_ip);
00522 BU_CK_VLS(&dsp_ip->dsp_name);
00523 BU_CK_VLS(vls);
00524
00525 bu_vls_printf( vls, "Displacement Map\n file='%s' w=%d n=%d sm=%d",
00526 bu_vls_addr(&dsp_ip->dsp_name),
00527 dsp_ip->dsp_xcnt,
00528 dsp_ip->dsp_ycnt,
00529 dsp_ip->dsp_smooth);
00530
00531 VSETALL(pt, 0.0);
00532
00533 MAT4X3PNT(v, dsp_ip->dsp_stom, pt);
00534
00535 bu_vls_printf( vls, " (origin at %g %g %g)mm\n", V3INTCLAMPARGS(v));
00536
00537 bu_vls_printf( vls, " stom=\n");
00538 bu_vls_printf( vls, " %8.3f %8.3f %8.3f %8.3f\n",
00539 V4INTCLAMPARGS(dsp_ip->dsp_stom) );
00540
00541 bu_vls_printf( vls, " %8.3f %8.3f %8.3f %8.3f\n",
00542 V4INTCLAMPARGS( &dsp_ip->dsp_stom[4]) );
00543
00544 bu_vls_printf( vls, " %8.3f %8.3f %8.3f %8.3f\n",
00545 V4INTCLAMPARGS( &dsp_ip->dsp_stom[8]) );
00546
00547 bu_vls_printf( vls, " %8.3f %8.3f %8.3f %8.3f\n",
00548 V4INTCLAMPARGS( &dsp_ip->dsp_stom[12]) );
00549 }
00550
00551
00552
00553 static void
00554 dsp_print_v5(struct bu_vls *vls,
00555 const struct rt_dsp_internal *dsp_ip)
00556 {
00557 point_t pt, v;
00558
00559 BU_CK_VLS(vls);
00560
00561 RT_DSP_CK_MAGIC(dsp_ip);
00562 BU_CK_VLS(&dsp_ip->dsp_name);
00563
00564
00565 bu_vls_printf( vls, "Displacement Map\n" );
00566
00567 switch (dsp_ip->dsp_datasrc) {
00568 case RT_DSP_SRC_V4_FILE:
00569 bu_vls_printf( vls, " Error Error Error");
00570 break;
00571 case RT_DSP_SRC_FILE:
00572 bu_vls_printf( vls, " file");
00573 break;
00574 case RT_DSP_SRC_OBJ:
00575 bu_vls_printf( vls, " obj");
00576 break;
00577 default:
00578 bu_vls_printf( vls, "unk src type'%c'", dsp_ip->dsp_datasrc);
00579 break;
00580 }
00581
00582 bu_vls_printf( vls, "='%s'\n w=%d n=%d sm=%d ",
00583 bu_vls_addr(&dsp_ip->dsp_name),
00584 dsp_ip->dsp_xcnt,
00585 dsp_ip->dsp_ycnt,
00586 dsp_ip->dsp_smooth);
00587
00588 switch (dsp_ip->dsp_cuttype) {
00589 case DSP_CUT_DIR_ADAPT:
00590 bu_vls_printf( vls, "cut=ad" ); break;
00591 case DSP_CUT_DIR_llUR:
00592 bu_vls_printf( vls, "cut=lR" ); break;
00593 case DSP_CUT_DIR_ULlr:
00594 bu_vls_printf( vls, "cut=Lr" ); break;
00595 default:
00596 bu_vls_printf( vls, "cut bogus('%c'/%d)",
00597 dsp_ip->dsp_cuttype,
00598 dsp_ip->dsp_cuttype ); break;
00599 }
00600
00601
00602 VSETALL(pt, 0.0);
00603
00604 MAT4X3PNT(v, dsp_ip->dsp_stom, pt);
00605
00606 bu_vls_printf( vls, " (origin at %g %g %g)mm\n", V3INTCLAMPARGS(v));
00607
00608 bu_vls_printf( vls, " stom=\n");
00609 bu_vls_printf( vls, " %8.3f %8.3f %8.3f %8.3f\n", V4INTCLAMPARGS(dsp_ip->dsp_stom) );
00610 bu_vls_printf( vls, " %8.3f %8.3f %8.3f %8.3f\n", V4INTCLAMPARGS( &dsp_ip->dsp_stom[4]) );
00611 bu_vls_printf( vls, " %8.3f %8.3f %8.3f %8.3f\n", V4INTCLAMPARGS( &dsp_ip->dsp_stom[8]) );
00612 bu_vls_printf( vls, " %8.3f %8.3f %8.3f %8.3f\n", V4INTCLAMPARGS( &dsp_ip->dsp_stom[12]) );
00613 }
00614
00615
00616
00617
00618 void
00619 rt_dsp_print(register const struct soltab *stp)
00620 {
00621 register const struct dsp_specific *dsp =
00622 (struct dsp_specific *)stp->st_specific;
00623 struct bu_vls vls;
00624
00625
00626 RT_DSP_CK_MAGIC(dsp);
00627 BU_CK_VLS(&dsp->dsp_i.dsp_name);
00628
00629 bu_vls_init( &vls );
00630 BU_CK_VLS(&vls);
00631
00632 bu_vls_printf(&vls, "\n---------db version: %d----------\n",
00633 stp->st_rtip->rti_dbip->dbi_version );
00634
00635 switch (stp->st_rtip->rti_dbip->dbi_version) {
00636 case 4:
00637 BU_CK_VLS(&vls);
00638 dsp_print_v4(&vls, &(dsp->dsp_i) );
00639 break;
00640 case 5:
00641 BU_CK_VLS(&vls);
00642 dsp_print_v5(&vls, &(dsp->dsp_i) );
00643 break;
00644 }
00645
00646 bu_log("%s", bu_vls_addr( &vls));
00647
00648 if (BU_VLS_IS_INITIALIZED( &vls )) bu_vls_free( &vls );
00649
00650 }
00651
00652
00653
00654
00655
00656
00657 static void
00658 dsp_layers(struct dsp_specific *dsp, unsigned short *d_min, unsigned short *d_max)
00659 {
00660 int idx, i, j, k, curr_layer, x, y, xs, ys, xv, yv, tot;
00661 unsigned short dsp_min, dsp_max, cell_min, cell_max;
00662 unsigned short elev;
00663 struct dsp_bb *dsp_bb;
00664 struct dsp_rpp *t;
00665 struct dsp_bb_layer *curr, *prev;
00666 unsigned short subcell_size;
00667
00668
00669 xs = dsp->xsiz;
00670 ys = dsp->ysiz;
00671 tot = xs * ys;
00672
00673 dsp->layers = 1;
00674 while ( xs > 1 || ys > 1 ) {
00675 xv = xs / DIM_BB_CHILDREN;
00676 yv = ys / DIM_BB_CHILDREN;
00677 if (xs % DIM_BB_CHILDREN) xv++;
00678 if (ys % DIM_BB_CHILDREN) yv++;
00679
00680 #ifdef FULL_DSP_DEBUGGING
00681 if (RT_G_DEBUG & DEBUG_HF)
00682 bu_log("layer %d %dx%d\n", dsp->layers, xv, yv);
00683 #endif
00684 tot += xv * yv;
00685
00686 if (xv > 0) xs = xv;
00687 else xs = 1;
00688
00689 if (yv > 0) ys = yv;
00690 else ys = 1;
00691 dsp->layers++;
00692 }
00693
00694
00695 #ifdef FULL_DSP_DEBUGGING
00696 if (RT_G_DEBUG & DEBUG_HF)
00697 bu_log("%d layers total\n", dsp->layers);
00698 #endif
00699
00700
00701 dsp->layer = bu_malloc(dsp->layers * sizeof(struct dsp_bb_layer),
00702 "dsp_bb_layers array");
00703 dsp->bb_array = bu_malloc(tot * sizeof(struct dsp_bb), "dsp_bb array");
00704
00705
00706
00707
00708 dsp->layer[0].dim[X] = dsp->xsiz;
00709 dsp->layer[0].dim[Y] = dsp->ysiz;
00710 dsp->layer[0].p = dsp->bb_array;
00711
00712 xs = dsp->xsiz;
00713 ys = dsp->ysiz;
00714
00715 dsp_min = 0xffff;
00716 dsp_max = 0;
00717
00718 for (y=0 ; y < YSIZ(dsp) ; y++) {
00719
00720 cell_min = 0xffff;
00721 cell_max = 0;
00722
00723 for (x=0 ; x < XSIZ(dsp) ; x++) {
00724
00725 #if 0
00726 if (RT_G_DEBUG & DEBUG_HF)
00727 bu_log("filling %d,%d\n", x, y);
00728 #endif
00729 elev = DSP(&dsp->dsp_i, x, y);
00730 cell_min = cell_max = elev;
00731
00732 elev = DSP(&dsp->dsp_i, x+1, y);
00733 V_MIN(cell_min, elev);
00734 V_MAX(cell_max, elev);
00735
00736 elev = DSP(&dsp->dsp_i, x, y+1);
00737 V_MIN(cell_min, elev);
00738 V_MAX(cell_max, elev);
00739
00740 elev = DSP(&dsp->dsp_i, x+1, y+1);
00741 V_MIN(cell_min, elev);
00742 V_MAX(cell_max, elev);
00743
00744
00745 V_MIN(dsp_min, cell_min);
00746 V_MAX(dsp_max, cell_max);
00747
00748
00749 i = y*XSIZ(dsp) + x;
00750 dsp_bb = &dsp->layer[0].p[i];
00751 VSET(dsp_bb->dspb_rpp.dsp_min, x, y, cell_min);
00752 VSET(dsp_bb->dspb_rpp.dsp_max, x+1, y+1, cell_max);
00753
00754 dsp_bb->dspb_subcell_size = 0;
00755
00756
00757 dsp_bb->dspb_ch_dim[X] = 0;
00758 dsp_bb->dspb_ch_dim[Y] = 0;
00759 for (k=0 ; k < NUM_BB_CHILDREN ; k++ ) {
00760 dsp_bb->dspb_children[k] =
00761 (struct dsp_bb *)NULL;
00762 }
00763 dsp_bb->magic = MAGIC_dsp_bb;
00764 #if 0
00765 dlog("cell %d,%d min: %d,%d,%d max: %d,%d,%d\n",
00766 x, y, V3ARGS(dsp_bb->dspb_rpp.dsp_min),
00767 V3ARGS(dsp_bb->dspb_rpp.dsp_max) );
00768 #endif
00769
00770
00771
00772
00773 }
00774 }
00775
00776 *d_min = dsp_min;
00777 *d_max = dsp_max;
00778
00779
00780 if (RT_G_DEBUG & DEBUG_HF)
00781 bu_log("layer 0 filled\n");
00782
00783 subcell_size = 1;
00784
00785
00786 for (curr_layer = 1 ; curr_layer < dsp->layers ; curr_layer++ ) {
00787
00788
00789 xs = dsp->layer[curr_layer-1].dim[X];
00790 if (xs % DIM_BB_CHILDREN)
00791 dsp->layer[curr_layer].dim[X] =
00792 xs / DIM_BB_CHILDREN + 1;
00793 else
00794 dsp->layer[curr_layer].dim[X] =
00795 xs / DIM_BB_CHILDREN;
00796
00797 ys = dsp->layer[curr_layer-1].dim[Y];
00798 if (ys % DIM_BB_CHILDREN)
00799 dsp->layer[curr_layer].dim[Y] =
00800 ys / DIM_BB_CHILDREN + 1;
00801 else
00802 dsp->layer[curr_layer].dim[Y] =
00803 ys / DIM_BB_CHILDREN;
00804
00805
00806 dsp->layer[curr_layer].p =
00807 &dsp->layer[curr_layer-1].p[dsp->layer[curr_layer-1].dim[X] * dsp->layer[curr_layer-1].dim[Y] ];
00808
00809 curr = &dsp->layer[curr_layer];
00810 prev = &dsp->layer[curr_layer-1];
00811
00812 if (RT_G_DEBUG & DEBUG_HF)
00813 bu_log("layer %d subcell size %d\n", curr_layer, subcell_size);
00814
00815
00816 for (y=0 ; y < curr->dim[Y] ; y++ ) {
00817 for (x=0 ; x < curr->dim[X] ; x++ ) {
00818 int n, xp, yp;
00819
00820
00821
00822
00823 xp = x * DIM_BB_CHILDREN;
00824 yp = y * DIM_BB_CHILDREN;
00825
00826
00827 dsp_bb = &curr->p[y*curr->dim[X]+x];
00828 dsp_bb->magic = MAGIC_dsp_bb;
00829 n = (int)pow( (double)DIM_BB_CHILDREN, (double)curr_layer);
00830 VSET(dsp_bb->dspb_rpp.dsp_min,
00831 x * n, y * n, 0x0ffff);
00832 VSET(dsp_bb->dspb_rpp.dsp_max,
00833 x * n, y * n, 0);
00834
00835
00836 dsp_bb->dspb_subcell_size = subcell_size;
00837
00838
00839 tot = 0;
00840 #if 0
00841 dlog(" cell %d,%d (%d,%d-%d,%d)\n", x, y,
00842 dsp_bb->dspb_rpp.dsp_min[X],
00843 dsp_bb->dspb_rpp.dsp_min[Y],
00844 (x+1) * n, (y+1)*n);
00845 #endif
00846 i=0;
00847 for (j=0 ; j<DIM_BB_CHILDREN && (yp+j)<prev->dim[Y] ; j++) {
00848 for (i=0 ; i<DIM_BB_CHILDREN && (xp+i)<prev->dim[X]; i++) {
00849
00850 idx = (yp+j) * prev->dim[X] + xp+i;
00851
00852 t = &prev->p[ idx ].dspb_rpp;
00853
00854 VMINMAX(dsp_bb->dspb_rpp.dsp_min,
00855 dsp_bb->dspb_rpp.dsp_max, t->dsp_min);
00856 VMINMAX(dsp_bb->dspb_rpp.dsp_min,
00857 dsp_bb->dspb_rpp.dsp_max, t->dsp_max);
00858
00859 dsp_bb->dspb_children[tot++] = &prev->p[ idx ];
00860
00861 #if 0
00862 dlog("\t\tsubcell %d,%d min: %d,%d,%d max: %d,%d,%d\n",
00863 xp+i, yp+j, V3ARGS(t->dsp_min), V3ARGS(t->dsp_max) );
00864
00865 if (RT_G_DEBUG & DEBUG_HF)
00866 if (i+1 >= DIM_BB_CHILDREN || xp+i+1 >= prev->dim[X])
00867 bu_log("\n");
00868 #endif
00869 }
00870 }
00871 #if 0
00872 dlog("\t\txy: %d,%d, ij:%d,%d min:%d,%d,%d max:%d,%d,%d\n",
00873 x, y, i, j,
00874 V3ARGS(dsp_bb->dspb_rpp.dsp_min),
00875 V3ARGS(dsp_bb->dspb_rpp.dsp_max) );
00876 #endif
00877
00878 dsp_bb->dspb_ch_dim[X] = i;
00879 dsp_bb->dspb_ch_dim[Y] = j;
00880 }
00881 }
00882 subcell_size *= DIM_BB_CHILDREN;
00883 }
00884
00885 #ifdef PLOT_LAYERS
00886 if (RT_G_DEBUG & DEBUG_HF) {
00887 plot_layers(dsp);
00888 bu_log("_ x:%d y:%d min %d max %d\n",
00889 XCNT(dsp), YCNT(dsp), dsp_min, dsp_max);
00890 }
00891 #endif
00892 }
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910 int
00911 rt_dsp_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
00912 {
00913 struct rt_dsp_internal *dsp_ip;
00914 register struct dsp_specific *dsp;
00915 unsigned short dsp_min, dsp_max;
00916 point_t pt, bbpt;
00917 vect_t work;
00918 fastf_t f;
00919
00920 if (RT_G_DEBUG & DEBUG_HF)
00921 bu_log("rt_dsp_prep()\n");
00922
00923 RT_CK_DB_INTERNAL(ip);
00924 dsp_ip = (struct rt_dsp_internal *)ip->idb_ptr;
00925 RT_DSP_CK_MAGIC(dsp_ip);
00926 BU_CK_VLS(&dsp_ip->dsp_name);
00927
00928 switch (dsp_ip->dsp_datasrc) {
00929 case RT_DSP_SRC_V4_FILE:
00930 case RT_DSP_SRC_FILE:
00931 BU_CK_MAPPED_FILE(dsp_ip->dsp_mp);
00932
00933
00934
00935
00936 bu_semaphore_acquire( RT_SEM_MODEL);
00937 ++dsp_ip->dsp_mp->uses;
00938 bu_semaphore_release( RT_SEM_MODEL);
00939 break;
00940 case RT_DSP_SRC_OBJ:
00941 RT_CK_DB_INTERNAL(dsp_ip->dsp_bip);
00942 RT_CK_BINUNIF(dsp_ip->dsp_bip->idb_ptr);
00943 break;
00944 }
00945
00946
00947 BU_GETSTRUCT( dsp, dsp_specific );
00948 stp->st_specific = (genptr_t) dsp;
00949
00950
00951
00952
00953
00954 dsp->dsp_i = *dsp_ip;
00955
00956
00957 dsp_ip->dsp_bip = (struct rt_db_internal *)NULL;
00958
00959
00960 dsp->xsiz = dsp_ip->dsp_xcnt-1;
00961 dsp->ysiz = dsp_ip->dsp_ycnt-1;
00962
00963
00964
00965 dsp_layers(dsp, &dsp_min, &dsp_max);
00966
00967
00968
00969 dsp->dsp_pl_dist[XMIN] = 0.0;
00970 dsp->dsp_pl_dist[XMAX] = (fastf_t)dsp->xsiz;
00971 dsp->dsp_pl_dist[YMIN] = 0.0;
00972 dsp->dsp_pl_dist[YMAX] = (fastf_t)dsp->ysiz;
00973 dsp->dsp_pl_dist[ZMIN] = 0.0;
00974 dsp->dsp_pl_dist[ZMAX] = (fastf_t)dsp_max;
00975 dsp->dsp_pl_dist[ZMID] = (fastf_t)dsp_min;
00976
00977
00978
00979 #define BBOX_PT(_x, _y, _z) \
00980 VSET(pt, (fastf_t)_x, (fastf_t)_y, (fastf_t)_z); \
00981 MAT4X3PNT(bbpt, dsp_ip->dsp_stom, pt); \
00982 VMINMAX( stp->st_min, stp->st_max, bbpt)
00983
00984 BBOX_PT(-.1, -.1, -.1);
00985 BBOX_PT(dsp_ip->dsp_xcnt+.1, -.1, -.1);
00986 BBOX_PT(dsp_ip->dsp_xcnt+.1, dsp_ip->dsp_ycnt+.1, -1);
00987 BBOX_PT(-.1, dsp_ip->dsp_ycnt+.1, -1);
00988 BBOX_PT(-.1, -.1, dsp_max+.1);
00989 BBOX_PT(dsp_ip->dsp_xcnt+.1, -.1, dsp_max+.1);
00990 BBOX_PT(dsp_ip->dsp_xcnt+.1, dsp_ip->dsp_ycnt+.1, dsp_max+.1);
00991 BBOX_PT(-.1, dsp_ip->dsp_ycnt+.1, dsp_max+.1);
00992
00993 #undef BBOX_PT
00994
00995 VADD2SCALE( stp->st_center, stp->st_min, stp->st_max, 0.5 );
00996 VSUB2SCALE( work, stp->st_max, stp->st_min, 0.5 );
00997
00998 f = work[X];
00999 if (work[Y] > f ) f = work[Y];
01000 if (work[Z] > f ) f = work[Z];
01001 stp->st_aradius = f;
01002 stp->st_bradius = MAGNITUDE(work);
01003
01004 if (RT_G_DEBUG & DEBUG_HF) {
01005 bu_log(" model space bbox (%g %g %g) (%g %g %g)\n",
01006 V3ARGS(stp->st_min),
01007 V3ARGS(stp->st_max));
01008 }
01009
01010
01011 switch (dsp_ip->dsp_datasrc) {
01012 case RT_DSP_SRC_V4_FILE:
01013 case RT_DSP_SRC_FILE:
01014 BU_CK_MAPPED_FILE(dsp->dsp_i.dsp_mp);
01015 break;
01016 case RT_DSP_SRC_OBJ:
01017 RT_CK_DB_INTERNAL(dsp->dsp_i.dsp_bip);
01018 RT_CK_BINUNIF(dsp->dsp_i.dsp_bip->idb_ptr);
01019 break;
01020 }
01021
01022 return 0;
01023 }
01024
01025 static void
01026 plot_seg(struct isect_stuff *isect,
01027 struct hit *in_hit,
01028 struct hit *out_hit,
01029 const point_t bbmin,
01030 const point_t bbmax,
01031 int r, int g, int b)
01032 {
01033 fastf_t *stom = &isect->dsp->dsp_i.dsp_stom[0];
01034 struct bound_rpp rpp;
01035 char fname[32];
01036 FILE *fp;
01037 static int segnum =0;
01038
01039
01040 bu_semaphore_acquire( BU_SEM_SYSCALL);
01041 sprintf(fname, "dsp_seg%04d.pl", segnum++);
01042 fp=fopen(fname, "w");
01043 bu_semaphore_release( BU_SEM_SYSCALL);
01044
01045 if (fp != (FILE *)NULL) {
01046 bu_log("plotting %s\n", fname);
01047
01048 MAT4X3PNT(rpp.min, stom, bbmin);
01049 MAT4X3PNT(rpp.max, stom, bbmax);
01050 plot_rpp(fp, &rpp, r/2, g/2, b/2);
01051
01052
01053 MAT4X3PNT(rpp.min, stom, in_hit->hit_point);
01054 MAT4X3PNT(rpp.max, stom, out_hit->hit_point);
01055
01056 pl_color(fp, r, g, b);
01057 pdv_3line(fp, rpp.min, rpp.max);
01058
01059 bu_semaphore_acquire( BU_SEM_SYSCALL);
01060 fclose(fp);
01061 bu_semaphore_release( BU_SEM_SYSCALL);
01062 }
01063 }
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073 #define ADD_SEG(isect, in, out, min, max, r, g, b) \
01074 add_seg(isect, in, out, min, max, r, g, b, __LINE__)
01075
01076
01077 static int
01078 add_seg(struct isect_stuff *isect,
01079 struct hit *in_hit,
01080 struct hit *out_hit,
01081 const point_t bbmin,
01082 const point_t bbmax,
01083 int r, int g, int b,
01084 int line)
01085
01086 {
01087 struct seg *seg;
01088 double tt = isect->tol->dist;
01089 double delta;
01090 #ifndef ORDERED_ISECT
01091 struct bu_list *spot;
01092 #endif
01093
01094 dlog("add_seg %g %g line %d vpriv:%g %g\n", in_hit->hit_dist, out_hit->hit_dist, line, in_hit->hit_vpriv[X], in_hit->hit_vpriv[Y]);
01095
01096 tt *= tt;
01097
01098 #ifdef ORDERED_ISECT
01099 if (BU_LIST_NON_EMPTY(&isect->seglist) ) {
01100
01101
01102
01103 seg = BU_LIST_LAST(seg, &isect->seglist);
01104 if ( fabs(seg->seg_out.hit_dist - in_hit->hit_dist) <= tt) {
01105
01106 #if 0
01107 seg->seg_out = *out_hit;
01108 seg->seg_out.hit_magic = RT_HIT_MAGIC;
01109 #else
01110 seg->seg_out.hit_dist = out_hit->hit_dist;
01111 seg->seg_out.hit_surfno = out_hit->hit_surfno;
01112 VMOVE(seg->seg_out.hit_normal, out_hit->hit_normal);
01113 #endif
01114 if (out_hit->hit_surfno == ZTOP) {
01115 seg->seg_out.hit_vpriv[X] = out_hit->hit_vpriv[X];
01116 seg->seg_out.hit_vpriv[Y] = out_hit->hit_vpriv[Y];
01117 }
01118 seg->seg_out.hit_vpriv[Z] = 1.0;
01119
01120 if (RT_G_DEBUG & DEBUG_HF) {
01121 bu_log("extending previous seg to %g\n", out_hit->hit_dist);
01122 plot_seg(isect, in_hit, out_hit, bbmin, bbmax, r, g, b);
01123 }
01124 return 0;
01125 }
01126 }
01127 #else
01128
01129 dlog("searching for insertion point for seg w in/out dist %g %g\n",
01130 in_hit->hit_dist, out_hit->hit_dist);
01131
01132 for ( BU_LIST_FOR(seg, seg, &isect->seglist) ) {
01133 dlog("checking %g->%g seg\n", seg->seg_in.hit_dist,
01134 seg->seg_out.hit_dist);
01135
01136 if ( fabs(seg->seg_out.hit_dist - in_hit->hit_dist) <= tt ) {
01137 seg->seg_out = *out_hit;
01138 seg->seg_out.hit_magic = RT_HIT_MAGIC;
01139 seg->seg_out.hit_vpriv[Z] = 1.0;
01140
01141 if (RT_G_DEBUG & DEBUG_HF) {
01142 bu_log("extending previous seg to %g\n",
01143 out_hit->hit_dist);
01144 plot_seg(isect, in_hit, out_hit, bbmin, bbmax, r, g, b);
01145 }
01146 return 0;
01147 }
01148 if (in_hit->hit_dist < seg->seg_in.hit_dist) {
01149 spot = &seg->l;
01150 dlog("insert before this one\n");
01151 goto found_spot;
01152 }
01153 }
01154 spot = &isect->seglist;
01155 seg = BU_LIST_LAST(seg, &isect->seglist);
01156 dlog("insert at end\n");
01157 found_spot:
01158 #endif
01159
01160
01161
01162
01163
01164 if (NEAR_ZERO(in_hit->hit_point[Z], isect->tol->dist) &&
01165 NEAR_ZERO(out_hit->hit_point[Z], isect->tol->dist) ) {
01166 return 0;
01167 }
01168
01169
01170
01171
01172 delta = out_hit->hit_dist - in_hit->hit_dist;
01173
01174 if (delta == 0.0) {
01175 return 0;
01176 }
01177
01178
01179 if (delta < 0.0 && !NEAR_ZERO(delta, isect->tol->dist)) {
01180 bu_log(" %s:%dDSP: Adding inside-out seg in:%g out:%g\n",
01181 __FILE__, __LINE__,
01182 in_hit->hit_dist, out_hit->hit_dist);
01183
01184 VPRINT("\tin_pt", in_hit->hit_point);
01185 VPRINT("\tout_pt", out_hit->hit_point);
01186 }
01187
01188
01189
01190
01191 RT_GET_SEG(seg, isect->ap->a_resource);
01192
01193 #if 0
01194 seg->seg_in = *in_hit;
01195 seg->seg_in.hit_magic = RT_HIT_MAGIC;
01196 seg->seg_out = *out_hit;
01197 seg->seg_out.hit_magic = RT_HIT_MAGIC;
01198
01199 #else
01200 seg->seg_in.hit_dist = in_hit->hit_dist;
01201 seg->seg_out.hit_dist = out_hit->hit_dist;
01202
01203 seg->seg_in.hit_surfno = in_hit->hit_surfno;
01204 seg->seg_out.hit_surfno = out_hit->hit_surfno;
01205
01206 VMOVE(seg->seg_in.hit_normal, in_hit->hit_normal);
01207 VMOVE(seg->seg_out.hit_normal, out_hit->hit_normal);
01208
01209 #endif
01210 if (in_hit->hit_surfno >= ZMAX) {
01211 seg->seg_in.hit_vpriv[X] = in_hit->hit_vpriv[X];
01212 seg->seg_in.hit_vpriv[Y] = in_hit->hit_vpriv[Y];
01213 }
01214
01215 if (out_hit->hit_surfno >= ZMAX) {
01216 seg->seg_out.hit_vpriv[X] = out_hit->hit_vpriv[X];
01217 seg->seg_out.hit_vpriv[Y] = out_hit->hit_vpriv[Y];
01218 }
01219
01220 seg->seg_in.hit_vpriv[Z] = 0.0;
01221 seg->seg_out.hit_vpriv[Z] = 1.0;
01222
01223 seg->seg_stp = isect->stp;
01224
01225 #ifdef FULL_DSP_DEBUGGING
01226 if (VDOT(seg->seg_in.hit_normal, isect->r.r_dir) > 0 ) {
01227 bu_log("----------------------------------------------------------\n");
01228 bu_log("pixel %d,%d bogus seg in, inward normal\nN: %g %g %g\nd: %g %g %g\n",
01229 isect->ap->a_x, isect->ap->a_y,
01230 V3ARGS(seg->seg_in.hit_normal), V3ARGS(isect->r.r_dir) );
01231 bu_bomb("");
01232 }
01233 if (VDOT(seg->seg_out.hit_normal, isect->r.r_dir) < 0 ) {
01234 bu_log("----------------------------------------------------------\n");
01235 bu_log("pixel %d,%d bogus seg out, inward normal\nN: %g %g %g\nd: %g %g %g\n",
01236 isect->ap->a_x, isect->ap->a_y,
01237 V3ARGS(seg->seg_out.hit_normal), V3ARGS(isect->r.r_dir) );
01238 bu_bomb("");
01239 }
01240 #endif
01241
01242 #ifdef ORDERED_ISECT
01243 BU_LIST_INSERT(&isect->seglist, &seg->l);
01244 #else
01245 BU_LIST_INSERT(spot, &seg->l);
01246 #endif
01247
01248
01249
01250
01251 if (RT_G_DEBUG & DEBUG_HF)
01252 plot_seg(isect, in_hit, out_hit, bbmin, bbmax, r, g, b);
01253
01254
01255 if (seg->seg_in.hit_dist > 0.0 || seg->seg_out.hit_dist > 0.0) {
01256 return (++isect->num_segs > isect->ap->a_onehit);
01257 }
01258 return 0;
01259 }
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272 static int
01273 isect_ray_triangle(struct isect_stuff *isect,
01274 point_t A,
01275 point_t B,
01276 point_t C,
01277 struct hit *hitp,
01278 double alphabbeta[])
01279 {
01280 point_t P;
01281 vect_t AB, AC, AP;
01282 plane_t N;
01283 double NdotDir;
01284 double alpha, beta;
01285 double hitdist;
01286 double toldist;
01287
01288 #ifdef FULL_DSP_DEBUGGING
01289 if (RT_G_DEBUG & DEBUG_HF) {
01290 fastf_t *stom = &isect->dsp->dsp_i.dsp_stom[0];
01291
01292 MAT4X3PNT(P, stom, A);
01293 bu_log("isect_ray_triangle...\n A %g %g %g (%g %g %g)\n",
01294 V3ARGS(A), V3ARGS(P));
01295
01296 MAT4X3PNT(P, stom, B);
01297 bu_log(" B %g %g %g (%g %g %g)\n",
01298 V3ARGS(B), V3ARGS(P));
01299
01300 MAT4X3PNT(P, stom, C);
01301 bu_log(" C %g %g %g (%g %g %g)\n",
01302 V3ARGS(C), V3ARGS(P));
01303
01304 }
01305 #endif
01306 VSUB2(AB, B, A);
01307 VSUB2(AC, C, A);
01308
01309
01310 VCROSS(N, AB, AC);
01311 VUNITIZE(N);
01312 N[H] = VDOT(N, A);
01313
01314
01315
01316 NdotDir = VDOT(N, isect->r.r_dir);
01317 if ( BN_VECT_ARE_PERP(NdotDir, isect->tol) ) {
01318
01319 return -1;
01320 }
01321
01322
01323 hitdist = (N[H]-VDOT(N, isect->r.r_pt)) / NdotDir;
01324
01325 VJOIN1(P, isect->r.r_pt, hitdist, isect->r.r_dir);
01326
01327 #ifdef FULL_DSP_DEBUGGING
01328 if (RT_G_DEBUG & DEBUG_HF) {
01329 FILE *fp;
01330 char buf[32];
01331 static int plotnum = 0;
01332 fastf_t *stom = &isect->dsp->dsp_i.dsp_stom[0];
01333 point_t p1, p2;
01334
01335 bu_semaphore_acquire( BU_SEM_SYSCALL);
01336 sprintf(buf, "dsp_tri%03d.pl", plotnum++);
01337 fp=fopen(buf, "w");
01338 bu_semaphore_release( BU_SEM_SYSCALL);
01339
01340 if ( fp == (FILE *)NULL) {
01341 bu_log("%s:%d error opening \"%s\"\n", __FILE__, __LINE__, buf);
01342 bu_bomb("");
01343 } else
01344 bu_log(" plotting %s\n", buf);
01345
01346
01347 pl_color(fp, 255, 255, 255);
01348 MAT4X3PNT(p1, stom, A); pdv_3move(fp, p1);
01349 MAT4X3PNT(p2, stom, B); pdv_3cont(fp, p2);
01350 MAT4X3PNT(p2, stom, C); pdv_3cont(fp, p2);
01351 pdv_3cont(fp, p1);
01352
01353
01354 pl_color(fp, 255, 255, 0);
01355 MAT4X3PNT(p1, stom, P);
01356 MAT4X3PNT(p2, stom, isect->r.r_pt);
01357 pdv_3line(fp, p1, p2);
01358
01359 bu_semaphore_acquire( BU_SEM_SYSCALL);
01360 fclose(fp);
01361 bu_semaphore_release( BU_SEM_SYSCALL);
01362
01363 bu_log(" dist:%g plane point: %g %g %g\n", hitdist, V3ARGS(p2));
01364 }
01365 #endif
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398 toldist = isect->tol->dist;
01399
01400
01401 VSUB2(AP, P, A);
01402 #ifdef FULL_DSP_DEBUGGING
01403 if (RT_G_DEBUG & DEBUG_HF) {
01404 VPRINT(" AP", AP);
01405 VPRINT(" AB", AB);
01406 VPRINT(" AC", AC);
01407 }
01408 #endif
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420 if (AB[X] == 0) {
01421 beta = AB[Y] * AP[Y];
01422 } else {
01423 beta = AB[X] * AP[X];
01424 }
01425
01426 if (AC[X] == 0) {
01427 alpha = AC[Y] * AP[Y];
01428 } else {
01429 alpha = AC[X] * AP[X];
01430 }
01431
01432
01433 alphabbeta[0] = alpha;
01434 alphabbeta[1] = beta;
01435
01436 #ifdef FULL_DSP_DEBUGGING
01437 if (alpha < -toldist ) {
01438 dlog("alpha < 0\n");
01439 return 0;
01440 }
01441 if (beta < -toldist ) {
01442 dlog("beta < 0\n");
01443 return 0;
01444 }
01445 if ( (alpha+beta) > (1.0 + toldist) ) {
01446 dlog("alpha+beta > 1\n");
01447 return 0;
01448 }
01449 #else
01450 if (alpha < -toldist || beta < -toldist || (alpha+beta) > (1.0 + toldist))
01451 return 0;
01452 #endif
01453
01454 hitp->hit_dist = hitdist;
01455 VMOVE(hitp->hit_normal, N);
01456 VMOVE(hitp->hit_point, P);
01457 return 1;
01458 }
01459
01460
01461
01462
01463
01464
01465
01466 static int
01467 permute_cell(point_t A,
01468 point_t B,
01469 point_t C,
01470 point_t D,
01471 struct dsp_specific *dsp,
01472 struct dsp_rpp *dsp_rpp)
01473 {
01474 int x, y;
01475
01476
01477 #ifdef FULL_DSP_DEBUGGING
01478 if (RT_G_DEBUG & DEBUG_HF) {
01479 VPRINT("\tA", A);
01480 VPRINT("\tB", B);
01481 VPRINT("\tC", C);
01482 VPRINT("\tD", D);
01483 }
01484 #endif
01485
01486 switch (dsp->dsp_i.dsp_cuttype) {
01487 case DSP_CUT_DIR_llUR:
01488 return DSP_CUT_DIR_llUR;
01489 break;
01490
01491 case DSP_CUT_DIR_ADAPT: {
01492 int lo[2], hi[2];
01493 point_t tmp;
01494 double h1, h2, h3, h4;
01495 double cAD, cBC;
01496
01497 if (RT_G_DEBUG & DEBUG_HF)
01498 bu_log("cell %d,%d adaptive triangulation... ",
01499 dsp_rpp->dsp_min[X],
01500 dsp_rpp->dsp_min[Y]);
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520 lo[X] = dsp_rpp->dsp_min[X] - 1;
01521 lo[Y] = dsp_rpp->dsp_min[Y] - 1;
01522 hi[X] = dsp_rpp->dsp_max[X] + 1;
01523 hi[Y] = dsp_rpp->dsp_max[Y] + 1;
01524
01525
01526 if (lo[X] < 0) lo[X] = 0;
01527 if (lo[Y] < 0) lo[Y] = 0;
01528 if (hi[X] > dsp->xsiz)
01529 hi[X] = dsp->xsiz;
01530
01531 if (hi[Y] > dsp->ysiz)
01532 hi[Y] = dsp->ysiz;
01533
01534
01535 h1 = DSP(&dsp->dsp_i, lo[X], lo[Y]);
01536 h2 = A[Z];
01537 h3 = D[Z];
01538 h4 = DSP(&dsp->dsp_i, hi[X], hi[Y]);
01539
01540 cAD = fabs(h3 + h1 - 2*h2 ) + fabs( h4 + h2 - 2*h3 );
01541
01542
01543
01544 h1 = DSP(&dsp->dsp_i, hi[X], lo[Y]);
01545 h2 = B[Z];
01546 h3 = C[Z];
01547 h4 = DSP(&dsp->dsp_i, lo[X], hi[Y]);
01548
01549 cBC = fabs(h3 + h1 - 2*h2 ) + fabs( h4 + h2 - 2*h3 );
01550
01551 if ( cAD < cBC ) {
01552
01553 if (RT_G_DEBUG & DEBUG_HF)
01554 bu_log("A-D cut\n");
01555
01556 return DSP_CUT_DIR_llUR;
01557
01558 }
01559
01560
01561 VMOVE(tmp, A);
01562 VMOVE(A, B);
01563 VMOVE(B, D);
01564 VMOVE(D, C);
01565 VMOVE(C, tmp);
01566 if (RT_G_DEBUG & DEBUG_HF)
01567 bu_log("B-C cut\n");
01568
01569 return DSP_CUT_DIR_ULlr;
01570
01571 break;
01572 }
01573 case DSP_CUT_DIR_ULlr:
01574
01575
01576
01577
01578
01579
01580
01581
01582 x = dsp_rpp->dsp_min[X];
01583 y = dsp_rpp->dsp_min[Y];
01584 VSET(B, x, y, DSP(&dsp->dsp_i, x, y) );
01585
01586 x = dsp_rpp->dsp_max[X];
01587 VSET(A, x, y, DSP(&dsp->dsp_i, x, y) );
01588
01589 y = dsp_rpp->dsp_max[Y];
01590 VSET(C, x, y, DSP(&dsp->dsp_i, x, y) );
01591
01592 x = dsp_rpp->dsp_min[X];
01593 VSET(D, x, y, DSP(&dsp->dsp_i, x, y) );
01594
01595 return DSP_CUT_DIR_ULlr;
01596 break;
01597 }
01598 bu_log("%s:%d Unknown DSP cut direction: %d\n",
01599 __FILE__, __LINE__, dsp->dsp_i.dsp_cuttype);
01600 bu_bomb("");
01601
01602 return -1;
01603 }
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631 static int
01632 check_bbpt_hit_elev(int i,
01633 point_t A,
01634 point_t B,
01635 point_t C,
01636 point_t D,
01637 point_t P)
01638 {
01639 double slope = 0.0;
01640 double delta = 0.0;
01641 double origin = 0.0;
01642
01643 #ifdef FULL_DSP_DEBUGGING
01644 dlog("check_bbpt_hit_elev(");
01645 #endif
01646 switch (i) {
01647 case XMIN:
01648
01649
01650
01651
01652 #ifdef FULL_DSP_DEBUGGING
01653 dlog("XMIN)\n");
01654 #endif
01655 slope = C[Z] - A[Z];
01656 delta = P[Y] - A[Y];
01657 origin = A[Z];
01658 break;
01659 case XMAX:
01660
01661
01662
01663
01664 #ifdef FULL_DSP_DEBUGGING
01665 dlog("XMAX)\n");
01666 #endif
01667 slope = D[Z] - B[Z];
01668 delta = P[Y] - B[Y];
01669 origin = B[Z];
01670 break;
01671 case YMIN:
01672
01673
01674
01675
01676 #ifdef FULL_DSP_DEBUGGING
01677 dlog("YMIN)\n");
01678 #endif
01679 slope = B[Z] - A[Z];
01680 delta = P[X] - A[X];
01681 origin = A[Z];
01682 break;
01683 case YMAX:
01684
01685
01686
01687
01688 #ifdef FULL_DSP_DEBUGGING
01689 dlog("YMAX)\n");
01690 #endif
01691 slope = D[Z] - C[Z];
01692 delta = P[X] - C[X];
01693 origin = C[Z];
01694 break;
01695 case ZMIN:
01696 #ifdef FULL_DSP_DEBUGGING
01697 dlog("ZMIN)\n");
01698 #endif
01699 return 1;
01700 break;
01701 case ZMAX:
01702 #ifdef FULL_DSP_DEBUGGING
01703 dlog("ZMAX)\n");
01704 #endif
01705 return 0;
01706 break;
01707 default:
01708 bu_log("%s:%d Coding error, bad face %d\n", __FILE__, __LINE__, i);
01709 bu_bomb("");
01710 break;
01711 }
01712
01713 if ( (origin + slope * delta) < P[Z] ) return 0;
01714
01715 return 1;
01716 }
01717
01718
01719
01720
01721
01722
01723
01724
01725 static int
01726 isect_ray_cell_top(struct isect_stuff *isect, struct dsp_bb *dsp_bb)
01727 {
01728 point_t A, B, C, D, P;
01729 int x, y;
01730 double ab_first[2], ab_second[2];
01731 struct hit hits[4];
01732 struct hit *hitp;
01733 int hitf = 0;
01734 int cond, i;
01735 int hitcount = 0;
01736 point_t bbmin, bbmax;
01737 double dot, dot2;
01738
01739
01740 dlog("isect_ray_cell_top\n");
01741 DSP_BB_CK(dsp_bb);
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751 x = dsp_bb->dspb_rpp.dsp_min[X];
01752 y = dsp_bb->dspb_rpp.dsp_min[Y];
01753 VSET(A, x, y, DSP(&isect->dsp->dsp_i, x, y) );
01754
01755 x = dsp_bb->dspb_rpp.dsp_max[X];
01756 VSET(B, x, y, DSP(&isect->dsp->dsp_i, x, y) );
01757
01758 y = dsp_bb->dspb_rpp.dsp_max[Y];
01759 VSET(D, x, y, DSP(&isect->dsp->dsp_i, x, y) );
01760
01761 x = dsp_bb->dspb_rpp.dsp_min[X];
01762 VSET(C, x, y, DSP(&isect->dsp->dsp_i, x, y) );
01763
01764
01765 #ifdef DEBUG_FULL
01766 if (RT_G_DEBUG & DEBUG_HF) {
01767 point_t p1, p2;
01768
01769 VJOIN1(p1, isect->r.r_pt, isect->r.r_min, isect->r.r_dir);
01770 VMOVE(hits[0].hit_point, p1);
01771 hits[0].hit_dist = isect->r.r_min;
01772
01773 VJOIN1(p2, isect->r.r_pt, isect->r.r_max, isect->r.r_dir);
01774 VMOVE(hits[1].hit_point, p2);
01775 hits[1].hit_dist = isect->r.r_max;
01776
01777 plot_cell_top(isect, dsp_bb, A, B, C, D, hits, 3, 0);
01778 }
01779 #endif
01780
01781
01782
01783
01784
01785 VJOIN1(P, isect->r.r_pt, isect->r.r_min, isect->r.r_dir);
01786 if ( check_bbpt_hit_elev(isect->dmin, A, B, C, D, P) ) {
01787 hits[0].hit_dist = isect->r.r_min;
01788 VMOVE(hits[0].hit_point, P);
01789 VMOVE(hits[0].hit_normal, dsp_pl[isect->dmin]);
01790
01791 hits[0].hit_vpriv[X] = dsp_bb->dspb_rpp.dsp_min[X];
01792 hits[0].hit_vpriv[Y] = dsp_bb->dspb_rpp.dsp_min[Y];
01793
01794 hits[0].hit_surfno = isect->dmin;
01795
01796 hitcount++;
01797
01798 hitf = 1;
01799 if (RT_G_DEBUG & DEBUG_HF) {
01800 dot = VDOT(hits[0].hit_normal, isect->r.r_dir);
01801 bu_log("hit ray/bb min Normal: %g %g %g %s\n",
01802 V3ARGS(hits[0].hit_normal),
01803 ((dot > 0.0) ? "outbound" : "inbound"));
01804 }
01805 } else {
01806 dlog("miss ray/bb min\n");
01807 }
01808
01809
01810
01811 VJOIN1(P, isect->r.r_pt, isect->r.r_max, isect->r.r_dir);
01812 if (check_bbpt_hit_elev(isect->dmax, A, B, C, D, P) ) {
01813
01814 hits[3].hit_dist = isect->r.r_max;
01815 VMOVE(hits[3].hit_point, P);
01816 VMOVE(hits[3].hit_normal, dsp_pl[isect->dmax]);
01817
01818 hits[3].hit_vpriv[X] = dsp_bb->dspb_rpp.dsp_min[X];
01819 hits[3].hit_vpriv[Y] = dsp_bb->dspb_rpp.dsp_min[Y];
01820
01821 hits[3].hit_surfno = isect->dmax;
01822
01823 hitcount++;
01824
01825 hitf |= 8;
01826 if (RT_G_DEBUG & DEBUG_HF) {
01827 dot = VDOT(hits[3].hit_normal, isect->r.r_dir);
01828 bu_log("hit ray/bb max Normal: %g %g %g %s\n",
01829 V3ARGS(hits[3].hit_normal),
01830 ((dot > 0.0) ? "outbound" : "inbound"));
01831 }
01832 } else {
01833 dlog("miss ray/bb max\n");
01834 }
01835
01836
01837
01838 (void)permute_cell(A, B, C, D, isect->dsp, &dsp_bb->dspb_rpp);
01839
01840 if ((cond=isect_ray_triangle(isect, B, D, A, &hits[1], ab_first)) > 0.0){
01841
01842
01843
01844 hits[1].hit_vpriv[X] = dsp_bb->dspb_rpp.dsp_min[X];
01845 hits[1].hit_vpriv[Y] = dsp_bb->dspb_rpp.dsp_min[Y];
01846 hits[1].hit_surfno = ZTOP;
01847
01848 hitcount++;
01849 hitf |= 2;
01850 dlog(" hit triangle 1 (alpha: %g beta:%g alpha+beta: %g) vpriv %g %g\n",
01851 ab_first[0], ab_first[1], ab_first[0] + ab_first[1],
01852 hits[1].hit_vpriv[X], hits[1].hit_vpriv[Y]);
01853 } else {
01854 dlog(" miss triangle 1 (alpha: %g beta:%g a+b: %g) cond:%d\n",
01855 ab_first[0], ab_first[1], ab_first[0] + ab_first[1], cond);
01856 }
01857 if ((cond=isect_ray_triangle(isect, C, A, D, &hits[2], ab_second)) > 0.0) {
01858
01859
01860
01861 hits[2].hit_vpriv[X] = dsp_bb->dspb_rpp.dsp_min[X];
01862 hits[2].hit_vpriv[Y] = dsp_bb->dspb_rpp.dsp_min[Y];
01863 hits[2].hit_surfno = ZTOP;
01864
01865 hitcount++;
01866
01867 hitf |= 4;
01868 dlog(" hit triangle 2 (alpha: %g beta:%g alpha+beta: %g) vpriv %g %g\n",
01869 ab_second[0], ab_second[1], ab_second[0] + ab_second[1],
01870 hits[2].hit_vpriv[X], hits[2].hit_vpriv[Y]);
01871
01872 if (hitf & 2) {
01873
01874
01875
01876 if (hits[1].hit_dist > hits[2].hit_dist) {
01877 struct hit tmp;
01878 tmp = hits[1];
01879 hits[1] = hits[2];
01880 hits[2] = tmp;
01881 dlog("re-ordered triangle hits\n");
01882
01883 } else
01884 dlog("triangle hits in order\n");
01885 }
01886
01887
01888 } else {
01889 dlog(" miss triangle 2 (alpha: %g beta:%g alpha+beta: %g) cond:%d\n",
01890 ab_second[0], ab_second[1], ab_second[0] + ab_second[1], cond);
01891 }
01892
01893 if (RT_G_DEBUG & DEBUG_HF) {
01894 bu_log("hitcount: %d flags: 0x%0x\n", hitcount, hitf);
01895
01896 plot_cell_top(isect, dsp_bb, A, B, C, D, hits, hitf, 1);
01897 for (i=0 ; i < 4 ; i++) {
01898 if (hitf & (1<<i)) {
01899 double v = VDOT(isect->r.r_dir, hits[i].hit_normal);
01900
01901 bu_log("%d dist:%g N:%g %g %g ",
01902 i, hits[i].hit_dist, V3ARGS(hits[i].hit_normal));
01903
01904 if (v > 0.0) bu_log("outbound\n");
01905 else if (v < 0.0) bu_log("inbound\n");
01906 else bu_log("perp\n");
01907 }
01908 }
01909 bu_log("assembling segs\n");
01910 }
01911
01912
01913
01914
01915 hitp = 0;
01916 for (i = 0 ; i < 4 ; i++ ) {
01917 if (hitf & (1<<i)) {
01918 if (hitp) {
01919
01920 dot2 = VDOT(isect->r.r_dir, hits[i].hit_normal);
01921
01922
01923 if ( dot2 < 0.0 ) {
01924 dlog("dot2(%g) < 0.0\n", dot2);
01925 if (hitp->hit_dist > hits[i].hit_dist) {
01926 dlog("skipping duplicate entry point at dist %g\n",
01927 hitp->hit_dist);
01928
01929 hitp = &hits[i];
01930 } else {
01931 dlog("skipping duplicate entry point at dist %g\n",
01932 hits[i].hit_dist);
01933 }
01934
01935 continue;
01936 }
01937
01938
01939 if (RT_G_DEBUG & DEBUG_HF) {
01940
01941 VMOVE(bbmin, dsp_bb->dspb_rpp.dsp_min);
01942 VMOVE(bbmax, dsp_bb->dspb_rpp.dsp_max);
01943 }
01944
01945 if (ADD_SEG(isect, hitp, &hits[i], bbmin, bbmax,255, 255, 255))
01946 return 1;
01947
01948 hitp = 0;
01949 } else {
01950 dot = VDOT(isect->r.r_dir, hits[i].hit_normal);
01951 if (dot >= 0.0)
01952 continue;
01953
01954
01955 if (RT_G_DEBUG & DEBUG_HF) {
01956 bu_log("in-hit at dist %g\n", hits[i].hit_dist);
01957 }
01958 hitp = &hits[i];
01959 }
01960 }
01961 }
01962
01963 if (hitp && hitcount > 1) {
01964 point_t p1, p2;
01965
01966 bu_log("----------------ERROR incomplete segment-------------\n");
01967 bu_log(" pixel %d %d\n", isect->ap->a_x, isect->ap->a_y);
01968
01969 VJOIN1(p1, isect->r.r_pt, isect->r.r_min, isect->r.r_dir);
01970 VMOVE(hits[0].hit_point, p1);
01971 hits[0].hit_dist = isect->r.r_min;
01972
01973 VJOIN1(p2, isect->r.r_pt, isect->r.r_max, isect->r.r_dir);
01974 VMOVE(hits[1].hit_point, p2);
01975 hits[1].hit_dist = isect->r.r_max;
01976
01977 if (RT_G_DEBUG & DEBUG_HF)
01978 plot_cell_top(isect, dsp_bb, A, B, C, D, hits, 3, 0);
01979 }
01980 return 0;
01981 }
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011 int
02012 dsp_in_rpp(struct isect_stuff *isect,
02013 register const fastf_t *min,
02014 register const fastf_t *max)
02015 {
02016 struct xray *rp = &isect->r;
02017
02018 register const fastf_t *invdir = isect->inv_dir;
02019 register const fastf_t *pt = &rp->r_pt[0];
02020 register fastf_t sv;
02021 register fastf_t rmin = -INFINITY;
02022 register fastf_t rmax = INFINITY;
02023 int dmin = -1;
02024 int dmax = -1;
02025
02026
02027
02028
02029 if( *invdir < 0.0 ) {
02030
02031
02032 if(rmax > (sv = (*min - *pt) * *invdir) ) {
02033 rmax = sv;
02034 dmax = XMIN;
02035 }
02036 if( rmin < (sv = (*max - *pt) * *invdir) ) {
02037 rmin = sv;
02038 dmin = XMAX;
02039 }
02040 } else if( *invdir > 0.0 ) {
02041
02042
02043 if (rmax > (sv = (*max - *pt) * *invdir) ) {
02044 rmax = sv;
02045 dmax = XMAX;
02046 }
02047 if( rmin < ((sv = (*min - *pt) * *invdir)) ) {
02048 rmin = sv;
02049 dmin = XMIN;
02050 }
02051 } else {
02052
02053
02054
02055
02056
02057 if( (*min > *pt) || (*max < *pt) )
02058 return(0);
02059 }
02060
02061
02062 pt++; invdir++; max++; min++;
02063 if( *invdir < 0.0 ) {
02064 if (rmax > (sv = (*min - *pt) * *invdir) ) {
02065
02066 rmax = sv;
02067 dmax = YMIN;
02068 }
02069 if (rmin < (sv = (*max - *pt) * *invdir) ) {
02070 rmin = sv;
02071 dmin = YMAX;
02072 }
02073 } else if( *invdir > 0.0 ) {
02074
02075 if(rmax > (sv = (*max - *pt) * *invdir) ) {
02076 rmax = sv;
02077 dmax = YMAX;
02078 }
02079 if( rmin < ((sv = (*min - *pt) * *invdir)) ) {
02080 rmin = sv;
02081 dmin = YMIN;
02082 }
02083 } else {
02084 if( (*min > *pt) || (*max < *pt) )
02085 return(0);
02086 }
02087
02088
02089 pt++; invdir++; max++; min++;
02090 if( *invdir < 0.0 ) {
02091
02092 if(rmax > (sv = (*min - *pt) * *invdir) ) {
02093 rmax = sv;
02094 dmax = ZMIN;
02095 }
02096 if( rmin < (sv = (*max - *pt) * *invdir) ) {
02097 rmin = sv;
02098 dmin = ZMAX;
02099 }
02100 } else if( *invdir > 0.0 ) {
02101
02102 if(rmax > (sv = (*max - *pt) * *invdir) ) {
02103 rmax = sv;
02104 dmax = ZMAX;
02105 }
02106 if( rmin < ((sv = (*min - *pt) * *invdir)) ) {
02107 rmin = sv;
02108 dmin = ZMIN;
02109 }
02110 } else {
02111 if( (*min > *pt) || (*max < *pt) )
02112 return(0);
02113 }
02114
02115
02116 if( rmin > rmax )
02117 return(0);
02118
02119
02120 rp->r_min = rmin;
02121 rp->r_max = rmax;
02122
02123 isect->dmin = dmin;
02124 isect->dmax = dmax;
02125 return(1);
02126 }
02127 #ifdef ORDERED_ISECT
02128 static int
02129 isect_ray_dsp_bb(struct isect_stuff *isect, struct dsp_bb *dsp_bb);
02130
02131
02132
02133
02134
02135
02136
02137
02138 static int
02139 recurse_dsp_bb(struct isect_stuff *isect,
02140 struct dsp_bb *dsp_bb,
02141 point_t minpt,
02142 point_t maxpt,
02143 point_t bbmin,
02144 point_t bbmax)
02145 {
02146 double tDX;
02147 double tDY;
02148 double tX, tY;
02149 double curr_dist;
02150 short cX, cY;
02151 short cs;
02152 short stepX, stepY;
02153 short stepPX, stepPY;
02154 double out_dist;
02155 struct dsp_bb **p;
02156 fastf_t *stom = &isect->dsp->dsp_i.dsp_stom[0];
02157 point_t pt, v;
02158 int loop = 0;
02159
02160 DSP_BB_CK(dsp_bb);
02161
02162
02163 cs = dsp_bb->dspb_subcell_size;
02164
02165
02166 cX = (minpt[X] - bbmin[X]) / cs;
02167 cY = (minpt[Y] - bbmin[Y]) / cs;
02168
02169
02170
02171
02172 if (cX >= dsp_bb->dspb_ch_dim[X]) cX = dsp_bb->dspb_ch_dim[X] - 1;
02173 if (cY >= dsp_bb->dspb_ch_dim[Y]) cY = dsp_bb->dspb_ch_dim[Y] - 1;
02174
02175 #ifdef FULL_DSP_DEBUGGING
02176 dlog("recurse_dsp_bb cell size: %d current cell: %d %d\n",
02177 cs, cX, cY);
02178 dlog("dspb_ch_dim x:%d y:%d\n",
02179 dsp_bb->dspb_ch_dim[X], dsp_bb->dspb_ch_dim[Y]);
02180 #endif
02181
02182 tX = tY = curr_dist = isect->r.r_min;
02183
02184 if (isect->r.r_dir[X] < 0.0) {
02185 stepPX = stepX = -1;
02186
02187
02188
02189
02190 tDX = -cs / isect->r.r_dir[X];
02191
02192
02193
02194
02195 tX += ( (bbmin[X] + (cX * cs)) - minpt[X]) / isect->r.r_dir[X];
02196 } else {
02197 stepPX = stepX = 1;
02198 tDX = cs / isect->r.r_dir[X];
02199
02200 if (isect->r.r_dir[X] > 0.0)
02201 tX += ((bbmin[X] + ((cX+1) * cs)) - minpt[X]) / isect->r.r_dir[X];
02202 else
02203 tX = MAX_FASTF;
02204 }
02205
02206 if (isect->r.r_dir[Y] < 0) {
02207
02208 stepY = -1;
02209 stepPY = -dsp_bb->dspb_ch_dim[X];
02210 tDY = -cs / isect->r.r_dir[Y];
02211 tY += ( (bbmin[Y] + (cY * cs)) - minpt[Y]) / isect->r.r_dir[Y];
02212 } else {
02213 stepY = 1;
02214 stepPY = dsp_bb->dspb_ch_dim[X];
02215 tDY = cs / isect->r.r_dir[Y];
02216
02217 if (isect->r.r_dir[Y] > 0.0)
02218 tY += ((bbmin[Y] + ((cY+1) * cs)) - minpt[Y]) / isect->r.r_dir[Y];
02219 else
02220 tY = MAX_FASTF;
02221 }
02222
02223
02224 out_dist = isect->r.r_max - isect->tol->dist;
02225
02226 p = &dsp_bb->dspb_children[dsp_bb->dspb_ch_dim[X] * cY + cX];
02227 #ifdef FULL_DSP_DEBUGGING
02228 dlog("tX:%g tY:%g\n", tX, tY);
02229
02230 #endif
02231
02232 do {
02233
02234 if (RT_G_DEBUG & DEBUG_HF) {
02235 if (loop)
02236 bu_log("\nisect sub-cell %d %d in dist:%g ",
02237 cX, cY, curr_dist, out_dist);
02238 else {
02239 bu_log("isect sub-cell %d %d in dist:%g ",
02240 cX, cY, curr_dist, out_dist);
02241 loop = 1;
02242 }
02243 VJOIN1(pt, isect->r.r_pt, curr_dist, isect->r.r_dir);
02244 MAT4X3PNT(v, stom, pt);
02245 bu_log("pt %g %g %g\n", V3ARGS(v));
02246 }
02247
02248
02249
02250
02251
02252
02253
02254
02255 if (RT_G_DEBUG & DEBUG_HF)
02256 bu_log_indent_delta(4);
02257
02258 if (isect_ray_dsp_bb(isect, *p)) return 1;
02259
02260 if (RT_G_DEBUG & DEBUG_HF)
02261 bu_log_indent_delta(-4);
02262
02263
02264 if (tX < tY) {
02265 cX += stepX;
02266 p += stepPX;
02267 #ifdef FULL_DSP_DEBUGGING
02268 dlog("stepping X to %d because %g < %g\n", cX, tX, tY);
02269 #endif
02270 curr_dist = tX;
02271 tX += tDX;
02272 } else {
02273 cY += stepY;
02274 p += stepPY;
02275 #ifdef FULL_DSP_DEBUGGING
02276 dlog("stepping Y to %d because %g >= %g\n", cY, tX, tY);
02277 #endif
02278 curr_dist = tY;
02279 tY += tDY;
02280 }
02281 #ifdef FULL_DSP_DEBUGGING
02282 dlog("curr_dist %g, out_dist %g\n", curr_dist, out_dist);
02283 #endif
02284 } while ( curr_dist < out_dist &&
02285 cX < dsp_bb->dspb_ch_dim[X] && cX >= 0 &&
02286 cY < dsp_bb->dspb_ch_dim[Y] && cY >= 0 );
02287
02288 return 0;
02289 }
02290 #endif
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302 static int
02303 isect_ray_dsp_bb(struct isect_stuff *isect, struct dsp_bb *dsp_bb)
02304 {
02305 point_t bbmin, bbmax;
02306 point_t minpt, maxpt;
02307 double min_z;
02308
02309 FILE *fp;
02310 static int plotnum;
02311 fastf_t *stom;
02312 point_t pt;
02313 struct xray *r = &isect->r;
02314
02315 if (dsp_bb) {
02316 DSP_BB_CK(dsp_bb);
02317 } else {
02318 bu_log("%s:%d null ptr pixel %d %d\n",
02319 __FILE__, __LINE__, isect->ap->a_x, isect->ap->a_y);
02320 bu_bomb("");
02321 }
02322
02323 if (RT_G_DEBUG & DEBUG_HF) {
02324 bu_log("\nisect_ray_dsp_bb( (%d,%d,%d) (%d,%d,%d))\n",
02325 V3ARGS(dsp_bb->dspb_rpp.dsp_min),
02326 V3ARGS(dsp_bb->dspb_rpp.dsp_max));
02327 }
02328
02329
02330 VMOVE(bbmax, dsp_bb->dspb_rpp.dsp_max);
02331 VSET(bbmin,
02332 dsp_bb->dspb_rpp.dsp_min[X],
02333 dsp_bb->dspb_rpp.dsp_min[Y], 0.0);
02334
02335
02336 if ( ! dsp_in_rpp(isect, bbmin, bbmax) ) {
02337
02338
02339 if (RT_G_DEBUG & DEBUG_HF) {
02340 bu_log("missed... ");
02341 fclose(draw_dsp_bb(&plotnum, dsp_bb, isect->dsp, 0, 150, 0));
02342 }
02343
02344 return 0;
02345 }
02346
02347
02348
02349 VJOIN1(minpt, r->r_pt, r->r_min, r->r_dir);
02350 VJOIN1(maxpt, r->r_pt, r->r_max, r->r_dir);
02351
02352
02353
02354
02355
02356 if (RT_G_DEBUG & DEBUG_HF) {
02357
02358 stom = &isect->dsp->dsp_i.dsp_stom[0];
02359
02360 bu_log("hit b-box ");
02361 fp = draw_dsp_bb(&plotnum, dsp_bb, isect->dsp, 200, 200, 100);
02362
02363 pl_color(fp, 150, 150, 255);
02364 MAT4X3PNT(pt, stom, minpt);
02365 pdv_3move(fp, pt);
02366 MAT4X3PNT(pt, stom, maxpt);
02367 pdv_3cont(fp, pt);
02368
02369 fclose(fp);
02370 }
02371
02372
02373
02374
02375
02376 min_z = dsp_bb->dspb_rpp.dsp_min[Z];
02377
02378 if (minpt[Z] < min_z && maxpt[Z] < min_z) {
02379
02380 struct hit seg_in, seg_out;
02381
02382 seg_in.hit_magic = RT_HIT_MAGIC;
02383 seg_in.hit_dist = r->r_min;
02384 VMOVE(seg_in.hit_point, minpt);
02385 VMOVE(seg_in.hit_normal, dsp_pl[isect->dmin]);
02386
02387
02388 seg_in.hit_surfno = isect->dmin;
02389
02390
02391 seg_out.hit_dist = r->r_max;
02392
02393 VMOVE(seg_out.hit_point, maxpt);
02394 VMOVE(seg_out.hit_normal, dsp_pl[isect->dmax]);
02395
02396
02397 seg_out.hit_surfno = isect->dmax;
02398
02399
02400 if (RT_G_DEBUG & DEBUG_HF) {
02401
02402
02403
02404
02405
02406 VMOVE(bbmax, dsp_bb->dspb_rpp.dsp_max);
02407 VMOVE(bbmin, dsp_bb->dspb_rpp.dsp_min);
02408 bbmax[Z] = bbmin[Z];
02409 bbmin[Z] = 0.0;
02410 }
02411
02412
02413 return (ADD_SEG(isect, &seg_in, &seg_out, bbmin, bbmax, 0, 255, 255));
02414 }
02415
02416
02417
02418
02419
02420 if (dsp_bb->dspb_ch_dim[0]) {
02421 #ifdef ORDERED_ISECT
02422 return (recurse_dsp_bb(isect, dsp_bb, minpt, maxpt, bbmin, bbmax));
02423 #else
02424 int i;
02425
02426 i = dsp_bb->dspb_ch_dim[X] * dsp_bb->dspb_ch_dim[Y] - 1;
02427 if (RT_G_DEBUG & DEBUG_HF)
02428 bu_log_indent_delta(4);
02429
02430 for ( ; i >= 0 ; i--)
02431 isect_ray_dsp_bb(isect, dsp_bb->dspb_children[i]);
02432
02433 if (RT_G_DEBUG & DEBUG_HF)
02434 bu_log_indent_delta(-4);
02435
02436 return 0;
02437
02438 #endif
02439 }
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456 bbmin[Z] = dsp_bb->dspb_rpp.dsp_min[Z];
02457 if (dsp_in_rpp(isect, bbmin, bbmax) ) {
02458
02459
02460 isect_ray_cell_top(isect, dsp_bb);
02461 }
02462
02463
02464
02465
02466
02467
02468 bbmax[Z] = dsp_bb->dspb_rpp.dsp_min[Z];
02469 bbmin[Z] = 0.0;
02470 if (dsp_in_rpp(isect, bbmin, bbmax) ) {
02471
02472 struct hit in_hit, out_hit;
02473
02474 VJOIN1(minpt, r->r_pt, r->r_min, r->r_dir);
02475 VJOIN1(maxpt, r->r_pt, r->r_max, r->r_dir);
02476
02477 in_hit.hit_dist = r->r_min;
02478 in_hit.hit_surfno = isect->dmin;
02479 VMOVE(in_hit.hit_point, minpt);
02480 VMOVE(in_hit.hit_normal, dsp_pl[isect->dmin]);
02481
02482 out_hit.hit_dist = r->r_max;
02483 out_hit.hit_surfno = isect->dmax;
02484 VMOVE(out_hit.hit_point, maxpt);
02485 VMOVE(out_hit.hit_normal, dsp_pl[isect->dmax]);
02486
02487
02488 return (ADD_SEG(isect, &in_hit, &out_hit, bbmin, bbmax, 255, 255, 0));
02489 }
02490
02491 return 0;
02492 }
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505 int
02506 rt_dsp_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
02507 {
02508 register struct dsp_specific *dsp =
02509 (struct dsp_specific *)stp->st_specific;
02510 register struct seg *segp;
02511 int i;
02512 vect_t dir;
02513 vect_t v;
02514 struct isect_stuff isect;
02515 double delta;
02516
02517 RT_DSP_CK_MAGIC(dsp);
02518 BU_CK_VLS(&dsp->dsp_i.dsp_name);
02519
02520 switch (dsp->dsp_i.dsp_datasrc) {
02521 case RT_DSP_SRC_V4_FILE:
02522 case RT_DSP_SRC_FILE:
02523 BU_CK_MAPPED_FILE(dsp->dsp_i.dsp_mp);
02524 break;
02525 case RT_DSP_SRC_OBJ:
02526 RT_CK_DB_INTERNAL(dsp->dsp_i.dsp_bip);
02527 RT_CK_BINUNIF(dsp->dsp_i.dsp_bip->idb_ptr);
02528 break;
02529 }
02530
02531
02532
02533
02534 MAT4X3PNT(isect.r.r_pt, dsp->dsp_i.dsp_mtos, rp->r_pt);
02535 MAT4X3VEC(dir, dsp->dsp_i.dsp_mtos, rp->r_dir);
02536 VMOVE(isect.r.r_dir, dir);
02537 VUNITIZE(isect.r.r_dir);
02538
02539
02540 isect.ap = ap;
02541 isect.stp = stp;
02542 isect.dsp = (struct dsp_specific *)stp->st_specific;
02543 isect.tol = &ap->a_rt_i->rti_tol;
02544 isect.num_segs = 0;
02545
02546 VINVDIR(isect.inv_dir, isect.r.r_dir);
02547 BU_LIST_INIT(&isect.seglist);
02548
02549
02550 if (RT_G_DEBUG & DEBUG_HF) {
02551 bu_log("rt_dsp_shot(pt:(%g %g %g)\n\tdir[%g]:(%g %g %g))\n pixel(%d,%d)\n",
02552 V3ARGS(rp->r_pt),
02553 MAGNITUDE(rp->r_dir),
02554 V3ARGS(rp->r_dir),
02555 ap->a_x, ap->a_y);
02556
02557 bn_mat_print("mtos", dsp->dsp_i.dsp_mtos);
02558 bu_log("Solid space ray pt:(%g %g %g)\n", V3ARGS(isect.r.r_pt));
02559 bu_log("\tdir[%g]: [%g %g %g]\n\tunit_dir(%g %g %g)\n",
02560 MAGNITUDE(dir),
02561 V3ARGS(dir),
02562 V3ARGS(isect.r.r_dir));
02563 }
02564
02565
02566
02567
02568 if (isect.dsp->layer[isect.dsp->layers-1].dim[X] != 1 ||
02569 isect.dsp->layer[isect.dsp->layers-1].dim[Y] != 1) {
02570 bu_log("%s:%d how do i find the topmost layer?\n",
02571 __FILE__, __LINE__);
02572 bu_bomb("");
02573 }
02574
02575
02576
02577 (void)isect_ray_dsp_bb(&isect, isect.dsp->layer[isect.dsp->layers-1].p);
02578
02579
02580 if (BU_LIST_IS_EMPTY(&isect.seglist))
02581 return 0;
02582
02583
02584 i = 0;
02585 for (BU_LIST_FOR(segp, seg, &isect.seglist)) {
02586 i += 2;
02587 if (RT_G_DEBUG & DEBUG_HF) {
02588 bu_log("\nsolid in:%6g out:%6g\t",
02589 segp->seg_in.hit_dist,
02590 segp->seg_out.hit_dist);
02591 }
02592
02593
02594 VSCALE(dir, isect.r.r_dir, segp->seg_in.hit_dist);
02595
02596 MAT4X3VEC(v, dsp->dsp_i.dsp_stom, dir);
02597
02598 segp->seg_in.hit_dist = MAGNITUDE(v);
02599
02600 if (VDOT(v, rp->r_dir) < 0.0) segp->seg_in.hit_dist *= -1.0;
02601
02602 VSCALE(dir, isect.r.r_dir, segp->seg_out.hit_dist);
02603 MAT4X3VEC(v, dsp->dsp_i.dsp_stom, dir);
02604 segp->seg_out.hit_dist = MAGNITUDE(v);
02605 if (VDOT(v, rp->r_dir) < 0.0) segp->seg_out.hit_dist *= -1.0;
02606
02607
02608 delta = segp->seg_out.hit_dist - segp->seg_in.hit_dist;
02609
02610 if (delta < 0.0 && !NEAR_ZERO(delta, ap->a_rt_i->rti_tol.dist)) {
02611 bu_log("Pixel %d %d seg inside out in:%g out:%g seg_len:%g\n",
02612 ap->a_x, ap->a_y, segp->seg_in.hit_dist, segp->seg_out.hit_dist,
02613 delta);
02614 }
02615
02616 #if 0
02617
02618 MAT4X3VEC(v, dsp->dsp_i.dsp_mtos, segp->seg_in.hit_normal);
02619 VMOVE(segp->seg_in.hit_normal, v);
02620 VUNITIZE( segp->seg_in.hit_normal );
02621
02622 MAT4X3VEC(v, dsp->dsp_i.dsp_mtos, segp->seg_out.hit_normal);
02623 VMOVE(segp->seg_out.hit_normal, v);
02624 VUNITIZE( segp->seg_out.hit_normal );
02625 #endif
02626 if (RT_G_DEBUG & DEBUG_HF) {
02627 bu_log("model in:%6g out:%6g\t",
02628 segp->seg_in.hit_dist,
02629 segp->seg_out.hit_dist);
02630 }
02631 }
02632
02633 if (RT_G_DEBUG & DEBUG_HF) {
02634 double NdotD;
02635 double d;
02636 static const plane_t plane = {0.0, 0.0, -1.0, 0.0};
02637
02638 NdotD = VDOT(plane, rp->r_dir);
02639 d = - ( (VDOT(plane, rp->r_pt) - plane[H]) / NdotD);
02640 bu_log("rp -> Z=0 dist: %g\n", d);
02641 }
02642
02643
02644 BU_LIST_APPEND_LIST( &(seghead->l), &isect.seglist);
02645
02646 return i;
02647 }
02648
02649 #define RT_DSP_SEG_MISS(SEG) (SEG).seg_stp=RT_SOLTAB_NULL
02650
02651
02652
02653
02654
02655
02656 void
02657 rt_dsp_vshot(struct soltab **stp, struct xray **rp, struct seg *segp, int n, struct application *ap)
02658
02659
02660
02661
02662
02663 {
02664 if (RT_G_DEBUG & DEBUG_HF)
02665 bu_log("rt_dsp_vshot()\n");
02666
02667 (void)rt_vstub( stp, rp, segp, n, ap );
02668 }
02669
02670
02671
02672
02673
02674
02675
02676
02677 static void
02678 compute_normal_at_gridpoint(vect_t N,
02679 struct dsp_specific *dsp,
02680 int x,
02681 int y,
02682 FILE *fd,
02683 int boolean,
02684 double len)
02685 {
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700 point_t A, C, D, E, tmp, pt, endpt;
02701 vect_t Vac, Vde;
02702
02703 if (RT_G_DEBUG & DEBUG_HF) {
02704 bu_log("normal at %d %d\n", x, y);
02705 mat_print("\tstom", dsp->dsp_i.dsp_stom);
02706 }
02707 VSET(tmp, x, y, DSP(&dsp->dsp_i, x, y));
02708
02709 if (x == 0) { VMOVE(A, tmp); }
02710 else { VSET(A, x-1, y, DSP(&dsp->dsp_i, x-1, y) ); }
02711
02712 if (x >= XSIZ(dsp)) { VMOVE(C, tmp); }
02713 else { VSET(C, x+1, y, DSP(&dsp->dsp_i, x+1, y) );}
02714
02715 if (y == 0) { VMOVE(D, tmp); }
02716 else { VSET(D, x, y-1, DSP(&dsp->dsp_i, x, y-1) ); }
02717
02718 if (y >= YSIZ(dsp)) { VMOVE(E, tmp); }
02719 else { VSET(E, x, y+1, DSP(&dsp->dsp_i, x, y+1) ); }
02720
02721 MAT4X3PNT(pt, dsp->dsp_i.dsp_stom, tmp);
02722
02723
02724
02725 VMOVE(tmp, A);
02726 MAT4X3PNT(A, dsp->dsp_i.dsp_stom, tmp);
02727
02728 VMOVE(tmp, C);
02729 MAT4X3PNT(C, dsp->dsp_i.dsp_stom, tmp);
02730
02731 VMOVE(tmp, D);
02732 MAT4X3PNT(D, dsp->dsp_i.dsp_stom, tmp);
02733
02734 VMOVE(tmp, E);
02735 MAT4X3PNT(E, dsp->dsp_i.dsp_stom, tmp);
02736
02737 VSUB2(Vac, C, A);
02738 VSUB2(Vde, E, D);
02739
02740 VUNITIZE(Vac);
02741 VUNITIZE(Vde);
02742 VCROSS(N, Vac, Vde);
02743
02744 if (RT_G_DEBUG & DEBUG_HF) {
02745 VPRINT("\tA", A);
02746 VPRINT("\tC", C);
02747 VPRINT("\tD", D);
02748 VPRINT("\tE", E);
02749 VPRINT("\tVac", Vac);
02750 VPRINT("\tVde", Vde);
02751 VPRINT("\tModel Cross N", N);
02752 }
02753 VUNITIZE(N);
02754
02755 if (RT_G_DEBUG & DEBUG_HF) {
02756 VPRINT("\tModel Unit N", N);
02757 }
02758 if (fd) {
02759 VJOIN1(endpt, pt, len, N);
02760
02761 pl_color(fd, 220, 220, 90);
02762 pdv_3line(fd, A, C);
02763 pdv_3line(fd, D, E);
02764
02765 pdv_3line(fd, pt, endpt);
02766 }
02767
02768
02769 }
02770
02771
02772
02773
02774
02775
02776 void
02777 rt_dsp_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp)
02778 {
02779 vect_t N, t, tmp, A;
02780 struct dsp_specific *dsp = (struct dsp_specific *)stp->st_specific;
02781 vect_t Anorm, Bnorm, Dnorm, Cnorm, ABnorm, CDnorm;
02782 double Xfrac, Yfrac;
02783 int x, y;
02784 point_t pt;
02785 double dot;
02786 double len;
02787 FILE *fd = (FILE *)NULL;
02788
02789
02790 RT_DSP_CK_MAGIC(dsp);
02791 BU_CK_VLS(&dsp->dsp_i.dsp_name);
02792
02793 switch (dsp->dsp_i.dsp_datasrc) {
02794 case RT_DSP_SRC_V4_FILE:
02795 case RT_DSP_SRC_FILE:
02796 BU_CK_MAPPED_FILE(dsp->dsp_i.dsp_mp);
02797 break;
02798 case RT_DSP_SRC_OBJ:
02799 RT_CK_DB_INTERNAL(dsp->dsp_i.dsp_bip);
02800 RT_CK_BINUNIF(dsp->dsp_i.dsp_bip->idb_ptr);
02801 break;
02802 }
02803
02804 if (RT_G_DEBUG & DEBUG_HF) {
02805 bu_log("rt_dsp_norm(%g %g %g)\n", V3ARGS(hitp->hit_normal));
02806 VJOIN1( hitp->hit_point, rp->r_pt, hitp->hit_dist, rp->r_dir );
02807 VPRINT("\thit point", hitp->hit_point);
02808 bu_log("hit dist: %g\n", hitp->hit_dist);
02809 bu_log("%s:%d vpriv: %g,%g %g\n",
02810 __FILE__, __LINE__, V3ARGS(hitp->hit_vpriv));
02811 }
02812
02813 if ( hitp->hit_surfno < XMIN || hitp->hit_surfno > ZTOP ) {
02814 bu_log("%s:%d bogus surface of DSP %d\n",
02815 __FILE__, __LINE__, hitp->hit_surfno);
02816 bu_bomb("");
02817 }
02818
02819
02820 VJOIN1( hitp->hit_point, rp->r_pt, hitp->hit_dist, rp->r_dir );
02821
02822
02823 if ( hitp->hit_surfno != ZTOP || !dsp->dsp_i.dsp_smooth ) {
02824
02825
02826
02827
02828
02829
02830
02831 MAT4X3VEC(tmp, dsp->dsp_i.dsp_mtos, hitp->hit_normal);
02832 VUNITIZE( tmp );
02833 VMOVE(hitp->hit_normal, tmp);
02834
02835 if (RT_G_DEBUG & DEBUG_HF)
02836 bu_log("\tno Interpolation needed. Normal: %g,%g,%g\n",
02837 V3ARGS(hitp->hit_normal));
02838 return;
02839 }
02840
02841 if (RT_G_DEBUG & DEBUG_HF)
02842 bu_log("\tNormal Interpolation flag: %d\n", dsp->dsp_i.dsp_smooth);
02843
02844
02845
02846 VSET(tmp, 1.0, 0.0, 0.0);
02847 MAT4X3VEC(t, dsp->dsp_i.dsp_stom, tmp);
02848 len = MAGNITUDE(t);
02849
02850 if (RT_G_DEBUG & DEBUG_HF) {
02851 fd = bu_fopen_uniq("plotting normals in %s",
02852 "dsp_gourand%02d.pl", plot_file_num++);
02853
02854
02855 pl_color(fd, 255, 0, 0);
02856 pdv_3line(fd, rp->r_pt, hitp->hit_point);
02857
02858
02859 pl_color(fd, 0, 255, 0);
02860 VJOIN1(tmp, hitp->hit_point, len, hitp->hit_normal);
02861 pdv_3line(fd, hitp->hit_point, tmp);
02862
02863 }
02864
02865
02866 x = hitp->hit_vpriv[X];
02867 y = hitp->hit_vpriv[Y];
02868
02869 compute_normal_at_gridpoint(Anorm, dsp, x, y, fd, 1, len);
02870 compute_normal_at_gridpoint(Anorm, dsp, x, y, fd, 0, len);
02871 compute_normal_at_gridpoint(Bnorm, dsp, x+1, y, fd, 0, len);
02872 compute_normal_at_gridpoint(Dnorm, dsp, x+1, y+1, fd, 0, len);
02873 compute_normal_at_gridpoint(Cnorm, dsp, x, y+1, fd, 0, len);
02874
02875
02876 MAT4X3PNT(pt, dsp->dsp_i.dsp_mtos, hitp->hit_point);
02877
02878 Xfrac = (pt[X] - x);
02879 Yfrac = (pt[Y] - y);
02880 if (RT_G_DEBUG & DEBUG_HF)
02881 bu_log("Xfract:%g Yfract:%g\n", Xfrac, Yfrac);
02882
02883 if (Xfrac < 0.0) Xfrac = 0.0;
02884 else if (Xfrac > 1.0) Xfrac = 1.0;
02885
02886 if (Yfrac < 0.0) Yfrac = 0.0;
02887 else if (Yfrac > 1.0) Yfrac = 1.0;
02888
02889
02890 if (dsp->dsp_i.dsp_smooth == 2) {
02891
02892
02893
02894 #define SMOOTHSTEP(x) ((x)*(x)*(3 - 2*(x)))
02895 Xfrac = SMOOTHSTEP( Xfrac );
02896 Yfrac = SMOOTHSTEP( Yfrac );
02897 #undef SMOOTHSTEP
02898 }
02899
02900
02901 VSCALE(Anorm, Anorm, (1.0-Xfrac) );
02902 VSCALE(Bnorm, Bnorm, Xfrac );
02903 VADD2(ABnorm, Anorm, Bnorm);
02904 VUNITIZE(ABnorm);
02905
02906 VSCALE(Cnorm, Cnorm, (1.0-Xfrac) );
02907 VSCALE(Dnorm, Dnorm, Xfrac );
02908 VADD2(CDnorm, Dnorm, Cnorm);
02909 VUNITIZE(CDnorm);
02910
02911
02912 VSCALE(ABnorm, ABnorm, (1.0-Yfrac) );
02913 VSCALE(CDnorm, CDnorm, Yfrac );
02914 VADD2(N, ABnorm, CDnorm);
02915
02916 VUNITIZE(N);
02917
02918 dot = VDOT(N, rp->r_dir);
02919 if (RT_G_DEBUG & DEBUG_HF)
02920 bu_log("interpolated %g %g %g dot:%g\n", V3ARGS(N), dot);
02921
02922 if ( (hitp->hit_vpriv[Z] == 0.0 && dot > 0.0) ||
02923 (hitp->hit_vpriv[Z] == 1.0 && dot < 0.0)){
02924
02925
02926
02927 VCROSS(A, rp->r_dir, N);
02928 VCROSS(N, A, rp->r_dir);
02929
02930 VUNITIZE(N);
02931
02932 dot = VDOT(N, rp->r_dir);
02933
02934
02935 if (RT_G_DEBUG & DEBUG_HF)
02936 bu_log("corrected: %g %g %g dot:%g\n", V3ARGS(N), dot);
02937 }
02938 VMOVE(hitp->hit_normal, N);
02939
02940 if (RT_G_DEBUG & DEBUG_HF) {
02941 pl_color(fd, 255, 255, 255);
02942 VJOIN1(tmp, hitp->hit_point, len, hitp->hit_normal);
02943 pdv_3line(fd, hitp->hit_point, tmp);
02944
02945 bu_semaphore_acquire( BU_SEM_SYSCALL);
02946 fclose(fd);
02947 bu_semaphore_release( BU_SEM_SYSCALL);
02948 }
02949 }
02950
02951
02952
02953
02954
02955
02956 void
02957 rt_dsp_curve(register struct curvature *cvp, register struct hit *hitp, struct soltab *stp)
02958 {
02959
02960 if (RT_G_DEBUG & DEBUG_HF)
02961 bu_log("rt_dsp_curve()\n");
02962
02963 cvp->crv_c1 = cvp->crv_c2 = 0;
02964
02965
02966 bn_vec_ortho( cvp->crv_pdir, hitp->hit_normal );
02967 }
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977 void
02978 rt_dsp_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
02979 {
02980 register struct dsp_specific *dsp =
02981 (struct dsp_specific *)stp->st_specific;
02982 point_t pt;
02983 vect_t tmp;
02984 double r;
02985 fastf_t min_r_U, min_r_V;
02986 vect_t norm;
02987 vect_t rev_dir;
02988 fastf_t dot_N;
02989 vect_t UV_dir;
02990 vect_t U_dir, V_dir;
02991 fastf_t U_len, V_len;
02992 double one_over_len;
02993
02994 MAT4X3PNT(pt, dsp->dsp_i.dsp_mtos, hitp->hit_point);
02995
02996
02997 uvp->uv_u = pt[X] / (double)XSIZ(dsp);
02998 CLAMP(uvp->uv_u, 0.0, 1.0);
02999
03000 uvp->uv_v = pt[Y] / (double)YSIZ(dsp);
03001 CLAMP(uvp->uv_v, 0.0, 1.0);
03002
03003
03004
03005
03006
03007
03008
03009 VSET( tmp, XSIZ(dsp), 0.0, 0.0 );
03010 MAT4X3VEC( U_dir, dsp->dsp_i.dsp_stom, tmp );
03011 U_len = MAGNITUDE( U_dir );
03012 one_over_len = 1.0/U_len;
03013 VSCALE( U_dir, U_dir, one_over_len );
03014
03015 VSET( tmp, 0.0, YSIZ(dsp), 0.0 );
03016 MAT4X3VEC( V_dir, dsp->dsp_i.dsp_stom, tmp );
03017 V_len = MAGNITUDE( V_dir );
03018 one_over_len = 1.0/V_len;
03019 VSCALE( V_dir, V_dir, one_over_len );
03020
03021
03022 r = ap->a_rbeam + ap->a_diverge * hitp->hit_dist;
03023 min_r_U = r / U_len;
03024 min_r_V = r / V_len;
03025
03026
03027
03028
03029 VREVERSE( rev_dir, ap->a_ray.r_dir );
03030 VMOVE( norm, hitp->hit_normal );
03031 dot_N = VDOT( rev_dir, norm );
03032 VJOIN1( UV_dir, rev_dir, -dot_N, norm );
03033 VUNITIZE( UV_dir );
03034
03035 if (NEAR_ZERO( dot_N, SMALL_FASTF ) ) {
03036
03037 uvp->uv_du = min_r_U;
03038 uvp->uv_dv = min_r_V;
03039 } else {
03040
03041 uvp->uv_du = (r / U_len) * VDOT( UV_dir, U_dir ) / dot_N;
03042 uvp->uv_dv = (r / V_len) * VDOT( UV_dir, V_dir ) / dot_N;
03043 }
03044
03045
03046
03047 if (uvp->uv_du < 0.0 )
03048 uvp->uv_du = -uvp->uv_du;
03049 if (uvp->uv_du < min_r_U )
03050 uvp->uv_du = min_r_U;
03051
03052 if (uvp->uv_dv < 0.0 )
03053 uvp->uv_dv = -uvp->uv_dv;
03054 if (uvp->uv_dv < min_r_V )
03055 uvp->uv_dv = min_r_V;
03056
03057 if (RT_G_DEBUG & DEBUG_HF)
03058 bu_log("rt_dsp_uv(pt:%g,%g siz:%d,%d)\n U_len=%g V_len=%g\n r=%g rbeam=%g diverge=%g dist=%g\n u=%g v=%g du=%g dv=%g\n",
03059 pt[X], pt[Y], XSIZ(dsp), YSIZ(dsp),
03060 U_len, V_len,
03061 r, ap->a_rbeam, ap->a_diverge, hitp->hit_dist,
03062 uvp->uv_u, uvp->uv_v,
03063 uvp->uv_du, uvp->uv_dv);
03064 }
03065
03066
03067
03068
03069 void
03070 rt_dsp_free(register struct soltab *stp)
03071 {
03072 register struct dsp_specific *dsp =
03073 (struct dsp_specific *)stp->st_specific;
03074
03075 if (RT_G_DEBUG & DEBUG_HF)
03076 bu_log("rt_dsp_free()\n");
03077
03078 switch (dsp->dsp_i.dsp_datasrc) {
03079 case RT_DSP_SRC_V4_FILE:
03080 case RT_DSP_SRC_FILE:
03081 if (dsp->dsp_i.dsp_mp) {
03082 BU_CK_MAPPED_FILE(dsp->dsp_i.dsp_mp);
03083 bu_close_mapped_file(dsp->dsp_i.dsp_mp);
03084 } else if (dsp->dsp_i.dsp_buf) {
03085 bu_free(dsp->dsp_i.dsp_buf, "dsp fake data");
03086 }
03087 break;
03088 case RT_DSP_SRC_OBJ:
03089 break;
03090 }
03091
03092 bu_free( (char *)dsp, "dsp_specific" );
03093 }
03094
03095
03096
03097
03098 int
03099 rt_dsp_class(void)
03100 {
03101 if (RT_G_DEBUG & DEBUG_HF)
03102 bu_log("rt_dsp_class()\n");
03103
03104 return(0);
03105 }
03106
03107
03108
03109
03110 int
03111 rt_dsp_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
03112 {
03113 struct rt_dsp_internal *dsp_ip =
03114 (struct rt_dsp_internal *)ip->idb_ptr;
03115 point_t m_pt;
03116 point_t s_pt;
03117 point_t o_pt;
03118 int x, y;
03119 int step;
03120 int xlim = dsp_ip->dsp_xcnt - 1;
03121 int ylim = dsp_ip->dsp_ycnt - 1;
03122 int xfudge, yfudge;
03123 int drawing;
03124
03125 if (RT_G_DEBUG & DEBUG_HF)
03126 bu_log("rt_dsp_plot()\n");
03127
03128 RT_CK_DB_INTERNAL(ip);
03129 RT_DSP_CK_MAGIC(dsp_ip);
03130
03131 switch (dsp_ip->dsp_datasrc) {
03132 case RT_DSP_SRC_V4_FILE:
03133 case RT_DSP_SRC_FILE:
03134 BU_CK_MAPPED_FILE(dsp_ip->dsp_mp);
03135 if (! dsp_ip->dsp_mp ) {
03136 bu_log("cannot find data for DSP\n");
03137 return 0;
03138 }
03139 break;
03140 case RT_DSP_SRC_OBJ:
03141 RT_CK_DB_INTERNAL(dsp_ip->dsp_bip);
03142 RT_CK_BINUNIF(dsp_ip->dsp_bip->idb_ptr);
03143 if (! dsp_ip->dsp_bip ) {
03144 bu_log("cannot find data for DSP\n");
03145 return 0;
03146 }
03147 break;
03148 }
03149
03150
03151 #define MOVE(_pt) \
03152 MAT4X3PNT(m_pt, dsp_ip->dsp_stom, _pt); \
03153 RT_ADD_VLIST( vhead, m_pt, BN_VLIST_LINE_MOVE )
03154
03155 #define DRAW(_pt) \
03156 MAT4X3PNT(m_pt, dsp_ip->dsp_stom, _pt); \
03157 RT_ADD_VLIST( vhead, m_pt, BN_VLIST_LINE_DRAW )
03158
03159
03160
03161 VSETALL(s_pt, 0.0);
03162 MOVE(s_pt);
03163
03164 s_pt[X] = xlim;
03165 DRAW(s_pt);
03166
03167 s_pt[Y] = ylim;
03168 DRAW(s_pt);
03169
03170 s_pt[X] = 0.0;
03171 DRAW(s_pt);
03172
03173 s_pt[Y] = 0.0;
03174 DRAW(s_pt);
03175
03176
03177
03178 s_pt[Z] = DSP(dsp_ip, 0, 0);
03179 DRAW(s_pt);
03180
03181 VSET(s_pt, xlim, 0.0, 0.0);
03182 MOVE(s_pt);
03183 s_pt[Z] = DSP(dsp_ip, xlim, 0);
03184 DRAW(s_pt);
03185
03186
03187 VSET(s_pt, xlim, ylim, 0.0);
03188 MOVE(s_pt);
03189 s_pt[Z] = DSP(dsp_ip, xlim, ylim);
03190 DRAW(s_pt);
03191
03192 VSET(s_pt, 0.0, ylim, 0.0);
03193 MOVE(s_pt);
03194 s_pt[Z] = DSP(dsp_ip, 0, ylim);
03195 DRAW(s_pt);
03196
03197
03198
03199
03200
03201
03202
03203 for (y=0 ; y < dsp_ip->dsp_ycnt ; y += ylim ) {
03204 VSET(s_pt, 0.0, y, DSP(dsp_ip, 0, y));
03205 MOVE(s_pt);
03206
03207 for (x=0 ; x < dsp_ip->dsp_xcnt ; x++) {
03208 s_pt[X] = x;
03209 s_pt[Z] = DSP(dsp_ip, x, y);
03210 DRAW(s_pt);
03211 }
03212 }
03213
03214
03215 for (x=0 ; x < dsp_ip->dsp_xcnt ; x += xlim ) {
03216 VSET(s_pt, x, 0.0, DSP(dsp_ip, x, 0));
03217 MOVE(s_pt);
03218
03219 for (y=0 ; y < dsp_ip->dsp_ycnt ; y++) {
03220 s_pt[Y] = y;
03221 s_pt[Z] = DSP(dsp_ip, x, y);
03222 DRAW(s_pt);
03223 }
03224 }
03225
03226
03227 if (ttol->rel ) {
03228 int rstep;
03229 rstep = dsp_ip->dsp_xcnt;
03230 V_MAX( rstep, dsp_ip->dsp_ycnt );
03231 step = (int)(ttol->rel * rstep);
03232 } else {
03233 int goal = 10000;
03234 goal -= 5;
03235 goal -= 8 + 2 * (dsp_ip->dsp_xcnt+dsp_ip->dsp_ycnt);
03236
03237 if (goal <= 0) return 0;
03238
03239
03240 step = ceil(
03241 sqrt( 2*(xlim)*(ylim) /
03242 (double)goal )
03243 );
03244 }
03245 if (step < 1 ) step = 1;
03246
03247
03248 xfudge = (dsp_ip->dsp_xcnt % step + step) / 2 ;
03249 yfudge = (dsp_ip->dsp_ycnt % step + step) / 2 ;
03250
03251 if (xfudge < 1) xfudge = 1;
03252 if (yfudge < 1) yfudge = 1;
03253
03254
03255 for (y=yfudge ; y < ylim ; y += step ) {
03256 VSET(s_pt, 0.0, y, DSP(dsp_ip, 0, y));
03257 VMOVE(o_pt, s_pt);
03258 if (o_pt[Z]) {
03259 drawing = 1;
03260 MOVE(o_pt);
03261 } else {
03262 drawing = 0;
03263 }
03264
03265 for (x=xfudge ; x < xlim ; x+=step ) {
03266 s_pt[X] = x;
03267
03268 if ( (s_pt[Z] = DSP(dsp_ip, x, y)) ) {
03269 if (drawing) {
03270 DRAW(s_pt);
03271 } else {
03272 MOVE(o_pt);
03273 DRAW(s_pt);
03274 drawing = 1;
03275 }
03276 } else {
03277 if (drawing) {
03278 DRAW(s_pt);
03279 drawing = 0;
03280 }
03281 }
03282
03283 VMOVE(o_pt, s_pt);
03284 }
03285
03286 s_pt[X] = xlim;
03287 if ( (s_pt[Z] = DSP(dsp_ip, xlim, y)) ) {
03288 if (drawing) {
03289 DRAW(s_pt);
03290 } else {
03291 MOVE(o_pt);
03292 DRAW(s_pt);
03293 drawing = 1;
03294 }
03295 } else {
03296 if (drawing) {
03297 DRAW(s_pt);
03298 drawing = 0;
03299 }
03300 }
03301
03302 }
03303
03304 for (x=xfudge ; x < xlim ; x += step ) {
03305 VSET(s_pt, x, 0.0, DSP(dsp_ip, x, 0));
03306 VMOVE(o_pt, s_pt);
03307 if (o_pt[Z]) {
03308 drawing = 1;
03309 MOVE(o_pt);
03310 } else {
03311 drawing = 0;
03312 }
03313
03314
03315 for (y=yfudge ; y < ylim ; y+=step) {
03316 s_pt[Y] = y;
03317
03318 if ( (s_pt[Z] = DSP(dsp_ip, x, y)) ) {
03319 if (drawing) {
03320 DRAW(s_pt);
03321 } else {
03322 MOVE(o_pt);
03323 DRAW(s_pt);
03324 drawing = 1;
03325 }
03326 } else {
03327 if (drawing) {
03328 DRAW(s_pt);
03329 drawing = 0;
03330 }
03331 }
03332
03333 VMOVE(o_pt, s_pt);
03334 }
03335
03336 s_pt[Y] = ylim;
03337 if ( (s_pt[Z] = DSP(dsp_ip, x, ylim)) ) {
03338 if (drawing) {
03339 DRAW(s_pt);
03340 } else {
03341 MOVE(o_pt);
03342 DRAW(s_pt);
03343 drawing = 1;
03344 }
03345 } else {
03346 if (drawing) {
03347 DRAW(s_pt);
03348 drawing = 0;
03349 }
03350 }
03351 }
03352
03353 #undef MOVE
03354 #undef DRAW
03355 return(0);
03356 }
03357
03358
03359
03360
03361
03362
03363
03364
03365 int
03366 rt_dsp_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
03367 {
03368 LOCAL struct rt_dsp_internal *dsp_ip;
03369
03370 if (RT_G_DEBUG & DEBUG_HF)
03371 bu_log("rt_dsp_tess()\n");
03372
03373 RT_CK_DB_INTERNAL(ip);
03374 dsp_ip = (struct rt_dsp_internal *)ip->idb_ptr;
03375 RT_DSP_CK_MAGIC(dsp_ip);
03376
03377 return(-1);
03378 }
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388 static int
03389 get_file_data(struct rt_dsp_internal *dsp_ip,
03390 struct rt_db_internal *ip,
03391 const struct bu_external *ep,
03392 register const mat_t mat,
03393 const struct db_i *dbip)
03394 {
03395 struct bu_mapped_file *mf;
03396 int count, in_cookie, out_cookie;
03397
03398 RT_DSP_CK_MAGIC(dsp_ip);
03399 RT_CK_DBI(dbip);
03400
03401
03402 mf = dsp_ip->dsp_mp =
03403 bu_open_mapped_file_with_path(dbip->dbi_filepath,
03404 bu_vls_addr(&dsp_ip->dsp_name), "dsp");
03405 if (!mf) {
03406 bu_log("mapped file open failed\n");
03407 return 0;
03408 }
03409
03410 if (dsp_ip->dsp_mp->buflen != dsp_ip->dsp_xcnt*dsp_ip->dsp_ycnt*2) {
03411 bu_log("DSP buffer wrong size: %d s/b %d ",
03412 dsp_ip->dsp_mp->buflen, dsp_ip->dsp_xcnt*dsp_ip->dsp_ycnt*2);
03413 return -1;
03414 }
03415
03416 in_cookie = bu_cv_cookie("nus");
03417 out_cookie = bu_cv_cookie("hus");
03418
03419 if ( bu_cv_optimize(in_cookie) != bu_cv_optimize(out_cookie) ) {
03420 int got;
03421
03422
03423
03424 count = dsp_ip->dsp_xcnt * dsp_ip->dsp_ycnt;
03425 mf->apbuflen = count * sizeof(unsigned short);
03426 mf->apbuf = bu_malloc(mf->apbuflen, "apbuf");
03427
03428 got = bu_cv_w_cookie(mf->apbuf, out_cookie, mf->apbuflen,
03429 mf->buf, in_cookie, count);
03430 if (got != count) {
03431 bu_log("got %d != count %d", got, count);
03432 bu_bomb("\n");
03433 }
03434 dsp_ip->dsp_buf = dsp_ip->dsp_mp->apbuf;
03435 } else {
03436 dsp_ip->dsp_buf = dsp_ip->dsp_mp->buf;
03437 }
03438 return 0;
03439 }
03440
03441
03442
03443
03444
03445 static int
03446 get_obj_data(struct rt_dsp_internal *dsp_ip,
03447 struct rt_db_internal *ip,
03448 const struct bu_external *ep,
03449 register const mat_t mat,
03450 const struct db_i *dbip)
03451 {
03452 struct rt_binunif_internal *bip;
03453 int in_cookie, out_cookie, got;
03454
03455 BU_GETSTRUCT(dsp_ip->dsp_bip, rt_db_internal);
03456
03457 if (rt_retrieve_binunif(dsp_ip->dsp_bip, dbip,
03458 bu_vls_addr( &dsp_ip->dsp_name) ))
03459 return -1;
03460
03461 if (RT_G_DEBUG & DEBUG_HF)
03462 bu_log("db_internal magic: 0x%08x major: %d minor:%d\n",
03463 dsp_ip->dsp_bip->idb_magic,
03464 dsp_ip->dsp_bip->idb_major_type,
03465 dsp_ip->dsp_bip->idb_minor_type);
03466
03467 bip = dsp_ip->dsp_bip->idb_ptr;
03468
03469 if (RT_G_DEBUG & DEBUG_HF)
03470 bu_log("binunif magic: 0x%08x type: %d count:%d data[0]:%u\n",
03471 bip->magic, bip->type, bip->count, bip->u.uint16[0]);
03472
03473
03474 in_cookie = bu_cv_cookie("nus");
03475 out_cookie = bu_cv_cookie("hus");
03476
03477 if ( bu_cv_optimize(in_cookie) != bu_cv_optimize(out_cookie) ) {
03478
03479
03480
03481
03482 got = bu_cv_w_cookie(bip->u.uint16, out_cookie,
03483 bip->count * sizeof(unsigned short),
03484 bip->u.uint16, in_cookie, bip->count);
03485
03486 if (got != bip->count) {
03487 bu_log("got %d != count %d", got, bip->count);
03488 bu_bomb("\n");
03489 }
03490 }
03491
03492 dsp_ip->dsp_buf = bip->u.uint16;
03493 return 0;
03494 }
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508 static int
03509 dsp_get_data(struct rt_dsp_internal *dsp_ip,
03510 struct rt_db_internal *ip,
03511 const struct bu_external *ep,
03512 register const mat_t mat,
03513 const struct db_i *dbip)
03514 {
03515 mat_t tmp;
03516 char *p;
03517
03518
03519 MAT_COPY(tmp, dsp_ip->dsp_stom);
03520 bn_mat_mul(dsp_ip->dsp_stom, mat, tmp);
03521
03522 bn_mat_inv(dsp_ip->dsp_mtos, dsp_ip->dsp_stom);
03523
03524 p = bu_vls_addr(&dsp_ip->dsp_name);
03525
03526 switch (dsp_ip->dsp_datasrc) {
03527 case RT_DSP_SRC_FILE:
03528 case RT_DSP_SRC_V4_FILE:
03529
03530 if (RT_G_DEBUG & DEBUG_HF)
03531 bu_log("getting data from file \"%s\"\n", p);
03532
03533 if (get_file_data(dsp_ip, ip, ep, mat, dbip) != 0) {
03534 p = "file";
03535 } else {
03536 return 0;
03537 }
03538
03539 break;
03540 case RT_DSP_SRC_OBJ:
03541
03542 if (RT_G_DEBUG & DEBUG_HF)
03543 bu_log("getting data from object \"%s\"\n", p);
03544
03545 if (get_obj_data(dsp_ip, ip, ep, mat, dbip) != 0) {
03546 p = "object";
03547 }
03548 else {
03549 RT_CK_DB_INTERNAL(dsp_ip->dsp_bip);
03550 RT_CK_BINUNIF(dsp_ip->dsp_bip->idb_ptr);
03551 return 0;
03552 }
03553 break;
03554 default:
03555 bu_log("%s:%d Odd dsp data src '%c' s/b '%c' or '%c'\n",
03556 __FILE__, __LINE__, dsp_ip->dsp_datasrc,
03557 RT_DSP_SRC_FILE, RT_DSP_SRC_OBJ);
03558 return -1;
03559 }
03560
03561 bu_log("Cannot retrieve DSP data from %s \"%s\"\n", p,
03562 bu_vls_addr(&dsp_ip->dsp_name));
03563
03564 dsp_ip->dsp_mp = (struct bu_mapped_file *)NULL;
03565 dsp_ip->dsp_buf = bu_calloc(sizeof(short),
03566 dsp_ip->dsp_xcnt*dsp_ip->dsp_ycnt,
03567 "dsp fake data");
03568
03569 return 1;
03570 }
03571
03572
03573
03574
03575
03576
03577
03578 int
03579 rt_dsp_import(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
03580 {
03581 LOCAL struct rt_dsp_internal *dsp_ip;
03582 union record *rp;
03583 struct bu_vls str;
03584
03585
03586
03587 if (RT_G_DEBUG & DEBUG_HF)
03588 bu_log("rt_dsp_import_v4()\n");
03589
03590
03591
03592 #define IMPORT_FAIL(_s) \
03593 bu_log("rt_dsp_import(%d) '%s' %s\n", __LINE__, \
03594 bu_vls_addr(&dsp_ip->dsp_name), _s);\
03595 bu_free( (char *)dsp_ip , "rt_dsp_import: dsp_ip" ); \
03596 ip->idb_type = ID_NULL; \
03597 ip->idb_ptr = (genptr_t)NULL; \
03598 return -2
03599
03600 BU_CK_EXTERNAL( ep );
03601 rp = (union record *)ep->ext_buf;
03602
03603 if (RT_G_DEBUG & DEBUG_HF)
03604 bu_log("rt_dsp_import(%s)\n", rp->ss.ss_args);
03605
03606
03607
03608
03609
03610 if (rp->u_id != DBID_STRSOL ) {
03611 bu_log("rt_dsp_import: defective record\n");
03612 return(-1);
03613 }
03614
03615 RT_CK_DB_INTERNAL( ip );
03616 ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
03617 ip->idb_type = ID_DSP;
03618 ip->idb_meth = &rt_functab[ID_DSP];
03619 ip->idb_ptr = bu_malloc( sizeof(struct rt_dsp_internal), "rt_dsp_internal");
03620 dsp_ip = (struct rt_dsp_internal *)ip->idb_ptr;
03621 dsp_ip->magic = RT_DSP_INTERNAL_MAGIC;
03622
03623
03624
03625
03626
03627 dsp_ip->dsp_xcnt = dsp_ip->dsp_ycnt = 0;
03628
03629 dsp_ip->dsp_cuttype = DSP_CUT_DIR_ADAPT;
03630 dsp_ip->dsp_smooth = 1;
03631 MAT_IDN(dsp_ip->dsp_stom);
03632 MAT_IDN(dsp_ip->dsp_mtos);
03633
03634 bu_vls_init( &str );
03635 bu_vls_strcpy( &str, rp->ss.ss_args );
03636 if (bu_struct_parse( &str, rt_dsp_parse, (char *)dsp_ip ) < 0) {
03637 if (BU_VLS_IS_INITIALIZED( &str )) bu_vls_free( &str );
03638 IMPORT_FAIL("parse error");
03639 }
03640
03641
03642
03643 if (dsp_ip->dsp_xcnt == 0 || dsp_ip->dsp_ycnt == 0) {
03644 IMPORT_FAIL("zero dimension on map");
03645 }
03646
03647 if (dsp_get_data(dsp_ip, ip, ep, mat, dbip)!=0) {
03648 IMPORT_FAIL("unable to load displacement map data");
03649 }
03650
03651 if (RT_G_DEBUG & DEBUG_HF) {
03652 bu_vls_trunc(&str, 0);
03653 bu_vls_struct_print( &str, rt_dsp_ptab, (char *)dsp_ip);
03654 bu_log(" imported as(%s)\n", bu_vls_addr(&str));
03655
03656 }
03657
03658 if (BU_VLS_IS_INITIALIZED( &str )) bu_vls_free( &str );
03659
03660 RT_CK_DB_INTERNAL(dsp_ip->dsp_bip);
03661 RT_CK_BINUNIF(dsp_ip->dsp_bip->idb_ptr);
03662
03663 return(0);
03664 }
03665
03666
03667
03668
03669
03670
03671
03672 int
03673 rt_dsp_export(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
03674 {
03675 struct rt_dsp_internal *dsp_ip;
03676 struct rt_dsp_internal dsp;
03677 union record *rec;
03678 struct bu_vls str;
03679
03680
03681 RT_CK_DB_INTERNAL(ip);
03682 if (ip->idb_type != ID_DSP ) return(-1);
03683 dsp_ip = (struct rt_dsp_internal *)ip->idb_ptr;
03684 RT_DSP_CK_MAGIC(dsp_ip);
03685 BU_CK_VLS(&dsp_ip->dsp_name);
03686
03687
03688 BU_CK_EXTERNAL(ep);
03689 ep->ext_nbytes = sizeof(union record)*DB_SS_NGRAN;
03690 ep->ext_buf = bu_calloc( 1, ep->ext_nbytes, "dsp external");
03691 rec = (union record *)ep->ext_buf;
03692
03693 dsp = *dsp_ip;
03694
03695
03696
03697
03698
03699 dsp.dsp_stom[15] *= local2mm;
03700
03701 bu_vls_init( &str );
03702 bu_vls_struct_print( &str, rt_dsp_ptab, (char *)&dsp);
03703 if (RT_G_DEBUG & DEBUG_HF)
03704 bu_log("rt_dsp_export_v4(%s)\n", bu_vls_addr(&str) );
03705
03706 rec->ss.ss_id = DBID_STRSOL;
03707 strncpy( rec->ss.ss_keyword, "dsp", NAMESIZE-1 );
03708 strncpy( rec->ss.ss_args, bu_vls_addr(&str), DB_SS_LEN-1 );
03709
03710
03711 if (BU_VLS_IS_INITIALIZED( &str )) bu_vls_free( &str );
03712
03713 return(0);
03714 }
03715
03716
03717
03718
03719
03720
03721
03722
03723
03724
03725 int
03726 rt_dsp_import5(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip, struct resource *resp, const int minor_type)
03727 {
03728 struct rt_dsp_internal *dsp_ip;
03729 unsigned char *cp;
03730
03731 if (RT_G_DEBUG & DEBUG_HF)
03732 bu_log("rt_dsp_import_v5()\n");
03733
03734
03735
03736 BU_CK_EXTERNAL( ep );
03737
03738 BU_ASSERT_LONG( ep->ext_nbytes, >, 141 );
03739
03740 RT_CK_DB_INTERNAL( ip );
03741
03742 ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
03743 ip->idb_type = ID_DSP;
03744 ip->idb_meth = &rt_functab[ID_DSP];
03745 dsp_ip = ip->idb_ptr = bu_malloc( sizeof(struct rt_dsp_internal), "rt_dsp_internal");
03746 memset(dsp_ip, 0, sizeof(*dsp_ip));
03747
03748 dsp_ip->magic = RT_DSP_INTERNAL_MAGIC;
03749
03750
03751 cp = (unsigned char *)ep->ext_buf;
03752
03753 dsp_ip->dsp_xcnt = (unsigned) bu_glong( cp );
03754 cp += SIZEOF_NETWORK_LONG;
03755 if (dsp_ip->dsp_xcnt < 2) {
03756 bu_log("%s:%d DSP X dimension (%d) < 2 \n",
03757 __FILE__, __LINE__,
03758 dsp_ip->dsp_xcnt);
03759 }
03760
03761
03762 dsp_ip->dsp_ycnt = (unsigned) bu_glong( cp );
03763 cp += SIZEOF_NETWORK_LONG;
03764 if (dsp_ip->dsp_ycnt < 2) {
03765 bu_log("%s:%d DSP X dimension (%d) < 2 \n",
03766 __FILE__, __LINE__,
03767 dsp_ip->dsp_ycnt);
03768 }
03769
03770
03771 ntohd((unsigned char *)dsp_ip->dsp_stom, cp, 16);
03772 cp += SIZEOF_NETWORK_DOUBLE * 16;
03773 bn_mat_inv(dsp_ip->dsp_mtos, dsp_ip->dsp_stom);
03774
03775
03776 dsp_ip->dsp_smooth = bu_gshort( cp );
03777 cp += SIZEOF_NETWORK_SHORT;
03778
03779 dsp_ip->dsp_datasrc = *cp;
03780 cp++;
03781 switch (dsp_ip->dsp_datasrc) {
03782 case RT_DSP_SRC_V4_FILE:
03783 case RT_DSP_SRC_FILE:
03784 case RT_DSP_SRC_OBJ:
03785 break;
03786 default:
03787 bu_log("%s:%d bogus DSP datasrc '%c' (%d)\n",
03788 __FILE__, __LINE__,
03789 dsp_ip->dsp_datasrc, dsp_ip->dsp_datasrc);
03790 break;
03791 }
03792
03793
03794 dsp_ip->dsp_cuttype = *cp;
03795 cp++;
03796 switch (dsp_ip->dsp_cuttype) {
03797 case DSP_CUT_DIR_ADAPT:
03798 case DSP_CUT_DIR_llUR:
03799 case DSP_CUT_DIR_ULlr:
03800 break;
03801 default:
03802 bu_log("%s:%d bogus DSP cut type '%c' (%d)\n",
03803 __FILE__, __LINE__,
03804 dsp_ip->dsp_cuttype, dsp_ip->dsp_cuttype);
03805 break;
03806 }
03807
03808
03809
03810 bu_vls_init( &dsp_ip->dsp_name );
03811 bu_vls_strncpy( &dsp_ip->dsp_name, (char *)cp,
03812 ep->ext_nbytes - (cp - (unsigned char *)ep->ext_buf) );
03813
03814 if (dsp_get_data(dsp_ip, ip, ep, mat, dbip)!=0) {
03815 IMPORT_FAIL("unable to load displacement map data");
03816 }
03817
03818 return 0;
03819 }
03820
03821
03822
03823
03824
03825
03826 int
03827 rt_dsp_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip, struct resource *resp, const int minor_type)
03828 {
03829 struct rt_dsp_internal *dsp_ip;
03830 unsigned long name_len;
03831 unsigned char *cp;
03832
03833 RT_CK_DB_INTERNAL(ip);
03834 if (ip->idb_type != ID_DSP ) return(-1);
03835 dsp_ip = (struct rt_dsp_internal *)ip->idb_ptr;
03836 RT_DSP_CK_MAGIC(dsp_ip);
03837
03838 if (RT_G_DEBUG & DEBUG_HF)
03839 bu_log("rt_dsp_export_v5()\n");
03840
03841 name_len = bu_vls_strlen(&dsp_ip->dsp_name) + 1;
03842
03843 BU_CK_EXTERNAL(ep);
03844
03845 ep->ext_nbytes =
03846 SIZEOF_NETWORK_LONG * 2 +
03847 SIZEOF_NETWORK_DOUBLE * ELEMENTS_PER_MAT +
03848 SIZEOF_NETWORK_SHORT +
03849 2 + name_len;
03850
03851 ep->ext_buf = bu_malloc( ep->ext_nbytes, "dsp external");
03852 cp = (unsigned char *)ep->ext_buf;
03853
03854 memset(ep->ext_buf, 0, ep->ext_nbytes);
03855
03856
03857
03858
03859
03860 bu_plong( cp, (unsigned long)dsp_ip->dsp_xcnt );
03861 cp += SIZEOF_NETWORK_LONG;
03862
03863 bu_plong( cp, (unsigned long)dsp_ip->dsp_ycnt );
03864 cp += SIZEOF_NETWORK_LONG;
03865
03866
03867
03868
03869
03870 dsp_ip->dsp_stom[15] *= local2mm;
03871
03872 htond(cp, (unsigned char *)dsp_ip->dsp_stom, 16);
03873 cp += SIZEOF_NETWORK_DOUBLE * 16;
03874
03875 bu_pshort( cp, (int)dsp_ip->dsp_smooth );
03876 cp += SIZEOF_NETWORK_SHORT;
03877
03878 switch(dsp_ip->dsp_datasrc) {
03879 case RT_DSP_SRC_V4_FILE:
03880 case RT_DSP_SRC_FILE:
03881 case RT_DSP_SRC_OBJ:
03882 *cp = dsp_ip->dsp_datasrc;
03883 break;
03884 default:
03885 *cp = RT_DSP_SRC_FILE;
03886 break;
03887 }
03888 cp++;
03889
03890 switch(dsp_ip->dsp_cuttype) {
03891 case DSP_CUT_DIR_ADAPT:
03892 case DSP_CUT_DIR_llUR:
03893 case DSP_CUT_DIR_ULlr:
03894 *cp = dsp_ip->dsp_cuttype;
03895 break;
03896 default:
03897 *cp = DSP_CUT_DIR_ADAPT;
03898 break;
03899 }
03900 cp++;
03901
03902 strcpy((char *)cp, bu_vls_addr(&dsp_ip->dsp_name));
03903
03904 return 0;
03905 }
03906
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917 int
03918 rt_dsp_describe(struct bu_vls *str,
03919 const struct rt_db_internal *ip,
03920 int verbose,
03921 double mm2local,
03922 struct resource *resp,
03923 struct db_i *db_ip)
03924 {
03925 register struct rt_dsp_internal *dsp_ip =
03926 (struct rt_dsp_internal *)ip->idb_ptr;
03927 struct bu_vls vls;
03928
03929 RT_CK_DBI(db_ip);
03930
03931 bu_vls_init( &vls );
03932
03933 if (RT_G_DEBUG & DEBUG_HF)
03934 bu_log("rt_dsp_describe()\n");
03935
03936 RT_DSP_CK_MAGIC(dsp_ip);
03937
03938 switch (db_ip->dbi_version) {
03939 case 4:
03940 dsp_print_v4(&vls, dsp_ip );
03941 break;
03942 case 5:
03943 dsp_print_v5(&vls, dsp_ip );
03944 break;
03945 }
03946
03947 bu_vls_vlscat( str, &vls );
03948
03949 if (BU_VLS_IS_INITIALIZED( &vls )) bu_vls_free( &vls );
03950
03951 return(0);
03952 }
03953
03954
03955
03956
03957
03958
03959 void
03960 rt_dsp_ifree(struct rt_db_internal *ip)
03961 {
03962 register struct rt_dsp_internal *dsp_ip;
03963
03964 if (RT_G_DEBUG & DEBUG_HF)
03965 bu_log("rt_dsp_ifree()\n");
03966
03967 RT_CK_DB_INTERNAL(ip);
03968 dsp_ip = (struct rt_dsp_internal *)ip->idb_ptr;
03969 RT_DSP_CK_MAGIC(dsp_ip);
03970
03971 if (dsp_ip->dsp_mp) {
03972 BU_CK_MAPPED_FILE(dsp_ip->dsp_mp);
03973 bu_close_mapped_file(dsp_ip->dsp_mp);
03974 }
03975
03976 if (dsp_ip->dsp_bip) {
03977 rt_binunif_ifree( (struct rt_db_internal *) dsp_ip->dsp_bip);
03978 }
03979
03980 dsp_ip->magic = 0;
03981 dsp_ip->dsp_mp = (struct bu_mapped_file *)0;
03982
03983 if (BU_VLS_IS_INITIALIZED(&dsp_ip->dsp_name))
03984 bu_vls_free( &dsp_ip->dsp_name );
03985 else
03986 bu_log("Freeing Bogus DSP, VLS string not initialized\n");
03987
03988
03989 bu_free( (char *)dsp_ip, "dsp ifree" );
03990 ip->idb_ptr = GENPTR_NULL;
03991 }
03992
03993 static void
03994 hook_verify(const struct bu_structparse *ip,
03995 const char *sp_name,
03996 genptr_t base,
03997 char *p)
03998 {
03999 struct rt_dsp_internal *dsp_ip = (struct rt_dsp_internal *)base;
04000
04001 if (!strcmp(sp_name, "src")) {
04002 switch (dsp_ip->dsp_datasrc) {
04003 case RT_DSP_SRC_V4_FILE:
04004 case RT_DSP_SRC_FILE:
04005 case RT_DSP_SRC_OBJ:
04006 break;
04007 default:
04008 bu_log("Error in DSP data source field s/b one of [%c%c%c]\n",
04009 RT_DSP_SRC_V4_FILE,
04010 RT_DSP_SRC_FILE,
04011 RT_DSP_SRC_OBJ);
04012 break;
04013 }
04014
04015 } else if (!strcmp(sp_name, "w")) {
04016 if (dsp_ip->dsp_xcnt == 0)
04017 bu_log("Error in DSP width dimension (0)\n");
04018 } else if (!strcmp(sp_name, "n")) {
04019 if (dsp_ip->dsp_ycnt == 0)
04020 bu_log("Error in DSP width dimension (0)\n");
04021 } else if (!strcmp(sp_name, "cut")) {
04022 switch (dsp_ip->dsp_cuttype) {
04023 case DSP_CUT_DIR_ADAPT:
04024 case DSP_CUT_DIR_llUR:
04025 case DSP_CUT_DIR_ULlr:
04026 break;
04027 default:
04028 bu_log("Error in DSP cut type: %c s/b one of [%c%c%c]\n",
04029 dsp_ip->dsp_cuttype,
04030 DSP_CUT_DIR_ADAPT,
04031 DSP_CUT_DIR_llUR,
04032 DSP_CUT_DIR_ULlr);
04033 break;
04034 }
04035 }
04036 }
04037
04038
04039
04040 const struct bu_structparse fake_dsp_printab[] = {
04041 {"%c", 1, "src", DSP_O(dsp_datasrc), hook_verify },
04042 {"%S", 1, "name", DSP_O(dsp_name), BU_STRUCTPARSE_FUNC_NULL },
04043 {"%d", 1, "w", DSP_O(dsp_xcnt), hook_verify },
04044 {"%d", 1, "n", DSP_O(dsp_ycnt), hook_verify },
04045 {"%i", 1, "sm", DSP_O(dsp_smooth), BU_STRUCTPARSE_FUNC_NULL },
04046 {"%c", 1, "cut", DSP_O(dsp_cuttype), hook_verify },
04047 {"%f", 16, "stom", DSP_AO(dsp_stom), hook_verify },
04048 {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL }
04049 };
04050
04051
04052
04053
04054
04055
04056
04057
04058
04059
04060
04061
04062 int
04063 rt_dsp_tclget(Tcl_Interp *interp, const struct rt_db_internal *intern, const char *attr)
04064 {
04065 register const struct bu_structparse *sp = NULL;
04066 const struct rt_dsp_internal *dsp_ip;
04067 int status;
04068 Tcl_DString ds;
04069 struct bu_vls str;
04070
04071
04072
04073
04074
04075
04076
04077 RT_CK_DB_INTERNAL( intern );
04078 dsp_ip = (struct rt_dsp_internal *)intern->idb_ptr;
04079
04080 bu_vls_init( &str );
04081 Tcl_DStringInit( &ds );
04082
04083 if( attr == (char *)0 ) {
04084
04085
04086 Tcl_DStringAppendElement( &ds, "dsp" );
04087
04088
04089
04090 switch (dsp_ip->dsp_datasrc) {
04091 case RT_DSP_SRC_V4_FILE:
04092 sp = rt_dsp_ptab;
04093 break;
04094 case RT_DSP_SRC_FILE:
04095 case RT_DSP_SRC_OBJ:
04096 sp = fake_dsp_printab;
04097 break;
04098 }
04099
04100 while( sp && sp->sp_name != NULL ) {
04101 Tcl_DStringAppendElement( &ds, sp->sp_name );
04102 bu_vls_trunc( &str, 0 );
04103 bu_vls_struct_item(&str,sp,(char *)dsp_ip,' ');
04104 Tcl_DStringAppendElement( &ds, bu_vls_addr(&str) );
04105 ++sp;
04106 }
04107 status = TCL_OK;
04108
04109 } else {
04110 switch (dsp_ip->dsp_datasrc) {
04111 case RT_DSP_SRC_V4_FILE:
04112 sp = rt_dsp_ptab;
04113 case RT_DSP_SRC_FILE:
04114 case RT_DSP_SRC_OBJ:
04115 sp = fake_dsp_printab;
04116 break;
04117 }
04118
04119 if( bu_vls_struct_item_named( &str, sp, attr,
04120 (char *)dsp_ip, ' ') < 0 ) {
04121 bu_vls_printf(&str,
04122 "Objects of type %s do not have a %s attribute.",
04123 "dsp", attr);
04124 status = TCL_ERROR;
04125 } else {
04126 status = TCL_OK;
04127 }
04128 Tcl_DStringAppendElement( &ds, bu_vls_addr(&str) );
04129 }
04130
04131 Tcl_DStringResult( interp, &ds );
04132 Tcl_DStringFree( &ds );
04133 bu_vls_free( &str );
04134
04135 return status;
04136 }
04137
04138
04139
04140
04141
04142
04143
04144 int
04145 rt_dsp_tcladjust(Tcl_Interp *interp, struct rt_db_internal *intern, int argc, char **argv)
04146 {
04147 register const struct bu_structparse *sp = NULL;
04148 const struct rt_dsp_internal *dsp_ip;
04149
04150
04151 RT_CK_DB_INTERNAL(intern);
04152 dsp_ip = (struct rt_dsp_internal *)intern->idb_ptr;
04153 RT_DSP_CK_MAGIC(dsp_ip);
04154 BU_CK_VLS(&dsp_ip->dsp_name);
04155
04156 switch (dsp_ip->dsp_datasrc) {
04157 case RT_DSP_SRC_V4_FILE:
04158 sp = rt_dsp_ptab;
04159 case RT_DSP_SRC_FILE:
04160 case RT_DSP_SRC_OBJ:
04161 sp = fake_dsp_printab;
04162 break;
04163 }
04164
04165 if (! sp) return TCL_ERROR;
04166
04167 return bu_structparse_argv(interp, argc, argv, sp,
04168 (char *)intern->idb_ptr );
04169 }
04170
04171 void
04172 rt_dsp_make(const struct rt_functab *ftp, struct rt_db_internal *intern, double diameter)
04173 {
04174 struct rt_dsp_internal *dsp;
04175
04176 intern->idb_major_type = DB5_MAJORTYPE_BRLCAD;
04177 intern->idb_type = ID_DSP;
04178
04179 BU_ASSERT(&rt_functab[intern->idb_type] == ftp);
04180 intern->idb_meth = ftp;
04181
04182 dsp =(struct rt_dsp_internal *)bu_calloc(sizeof(struct rt_dsp_internal),1, "rt_dsp_internal");
04183
04184 intern->idb_ptr = (genptr_t)dsp;
04185 dsp->magic = RT_DSP_INTERNAL_MAGIC;
04186 bu_vls_init(&dsp->dsp_name);
04187 bu_vls_strcpy(&dsp->dsp_name, "/dev/null");
04188 dsp->dsp_cuttype = DSP_CUT_DIR_ADAPT;
04189 MAT_IDN( dsp->dsp_mtos );
04190 MAT_IDN( dsp->dsp_stom );
04191 dsp->dsp_datasrc = RT_DSP_SRC_FILE;
04192
04193 }
04194
04195
04196
04197
04198 static int
04199 swap_cell_pts(int A[3],
04200 int B[3],
04201 int C[3],
04202 int D[3],
04203 struct dsp_specific *dsp)
04204
04205 {
04206 switch (dsp->dsp_i.dsp_cuttype) {
04207 case DSP_CUT_DIR_llUR:
04208 return 0;
04209 break;
04210
04211 case DSP_CUT_DIR_ADAPT: {
04212 int lo[2], hi[2];
04213 double h1, h2, h3, h4;
04214 double cAD, cBC;
04215
04216
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230
04231
04232
04233
04234
04235 lo[X] = A[X] - 1;
04236 lo[Y] = A[Y] - 1;
04237 hi[X] = D[X] + 1;
04238 hi[Y] = D[Y] + 1;
04239
04240
04241 if (lo[X] < 0) lo[X] = 0;
04242 if (lo[Y] < 0) lo[Y] = 0;
04243 if (hi[X] > dsp->xsiz)
04244 hi[X] = dsp->xsiz;
04245
04246 if (hi[Y] > dsp->ysiz)
04247 hi[Y] = dsp->ysiz;
04248
04249
04250 h1 = DSP(&dsp->dsp_i, lo[X], lo[Y]);
04251 h2 = A[Z];
04252 h3 = D[Z];
04253 h4 = DSP(&dsp->dsp_i, hi[X], hi[Y]);
04254
04255 cAD = fabs(h3 + h1 - 2*h2 ) + fabs( h4 + h2 - 2*h3 );
04256
04257
04258
04259 h1 = DSP(&dsp->dsp_i, hi[X], lo[Y]);
04260 h2 = B[Z];
04261 h3 = C[Z];
04262 h4 = DSP(&dsp->dsp_i, lo[X], hi[Y]);
04263
04264 cBC = fabs(h3 + h1 - 2*h2 ) + fabs( h4 + h2 - 2*h3 );
04265
04266 if ( cAD < cBC ) {
04267
04268 if (RT_G_DEBUG & DEBUG_HF)
04269 bu_log("A-D cut (no swap)\n");
04270
04271 return 0;
04272 }
04273
04274
04275
04276 }
04277 case DSP_CUT_DIR_ULlr:
04278 {
04279
04280 int tmp[3];
04281
04282 VMOVE(tmp, A);
04283 VMOVE(A, B);
04284 VMOVE(B, tmp);
04285
04286 VMOVE(tmp, D);
04287 VMOVE(D, C);
04288 VMOVE(C, tmp);
04289
04290 if (RT_G_DEBUG & DEBUG_HF)
04291 bu_log("B-C cut (swap)\n");
04292 }
04293 return 0;
04294 break;
04295 }
04296 bu_log("%s:%d Unknown DSP cut direction: %d\n",
04297 __FILE__, __LINE__, dsp->dsp_i.dsp_cuttype);
04298 bu_bomb("");
04299
04300 return -1;
04301 }
04302
04303
04304
04305
04306
04307
04308
04309
04310
04311
04312
04313
04314
04315 int
04316 project_pt(point_t out,
04317 int A[3],
04318 int B[3],
04319 int C[3],
04320 point_t pt)
04321 {
04322 int dx, dy;
04323 double alpha, beta, x, y;
04324 vect_t AB, AC;
04325
04326 if (RT_G_DEBUG & DEBUG_HF) {
04327 bu_log(" pt %g %g %g\n", V3ARGS(pt));
04328 bu_log(" origin %d %d %d\n", V3ARGS(A));
04329 bu_log(" Bpt %d %d %d\n", V3ARGS(B));
04330 bu_log(" Cpt %d %d %d\n", V3ARGS(C));
04331 }
04332 if ((B[X] - A[X]) < 0) dx = -1;
04333 else dx = 1;
04334 if ((C[Y] - A[Y]) < 0) dy = -1;
04335 else dy = 1;
04336
04337 x = pt[X] - A[X];
04338 y = pt[Y] - A[Y];
04339
04340 alpha = x * dx;
04341 beta = y * dy;
04342 if (RT_G_DEBUG & DEBUG_HF) {
04343 bu_log("alpha:%g beta:%g\n", alpha, beta);
04344 }
04345 if (alpha < -SMALL_FASTF) {
04346 bu_log ("Alpha negative: %g x:%g dx:%d\n", alpha, x, dx);
04347 }
04348 if (beta < -SMALL_FASTF) {
04349 bu_log ("Beta negative: %g x:%g dx:%d\n", beta, y, dy);
04350 }
04351 CLAMP(alpha, 0.0, 1.0);
04352 CLAMP(beta, 0.0, 1.0);
04353
04354 if (RT_G_DEBUG & DEBUG_HF) {
04355 bu_log("x:%g y:%g dx:%d dy:%d alpha:%g beta:%g\n",
04356 x, y, dx, dy, alpha, beta);
04357 }
04358 if ((alpha+beta) > (1.0+SMALL_FASTF)) {
04359 if (RT_G_DEBUG & DEBUG_HF) bu_log("Not this triangle\n");
04360 return 1;
04361 }
04362
04363 VSUB2(AB, B, A);
04364 VSUB2(AC, C, A);
04365
04366 VJOIN2(out, A, alpha, AB, beta, AC);
04367 if (RT_G_DEBUG & DEBUG_HF) bu_log("out: %g %g %g\n", V3ARGS(out));
04368
04369 return 0;
04370 }
04371
04372
04373
04374
04375
04376
04377
04378
04379 int
04380 dsp_pos(point_t out,
04381 struct soltab *stp,
04382 point_t p)
04383 {
04384 struct dsp_specific *dsp;
04385 point_t pt, tri_pt;
04386 int x, y;
04387 int A[3], B[3], C[3], D[3];
04388
04389 struct dsp_rpp dsp_rpp;
04390
04391 RT_CK_SOLTAB(stp);
04392
04393 if (stp->st_id != ID_DSP) return 1;
04394
04395 dsp = (struct dsp_specific *)stp->st_specific;
04396
04397 MAT4X3PNT(pt, dsp->dsp_i.dsp_mtos, p);
04398
04399
04400 if (RT_G_DEBUG & DEBUG_HF) {
04401 VPRINT("user_point", p);
04402 VPRINT("dsp_point", pt);
04403 }
04404 x = pt[X];
04405 y = pt[Y];
04406
04407 CLAMP(x, 0, XSIZ(dsp)-1);
04408 CLAMP(y, 0, YSIZ(dsp)-1);
04409
04410 if (RT_G_DEBUG & DEBUG_HF)
04411 bu_log("x:%d y:%d\n", x, y);
04412
04413 VSET(dsp_rpp.dsp_min, x, y, 0);
04414 VSET(dsp_rpp.dsp_max, x+1, y+1, 0);
04415
04416 VSET(A, x, y, DSP(&dsp->dsp_i, x, y) );
04417 x += 1;
04418 VSET(B, x, y, DSP(&dsp->dsp_i, x, y) );
04419 y += 1;
04420 VSET(D, x, y, DSP(&dsp->dsp_i, x, y) );
04421 x -= 1;
04422 VSET(C, x, y, DSP(&dsp->dsp_i, x, y) );
04423 y -= 1;
04424
04425 if (RT_G_DEBUG & DEBUG_HF) {
04426 bu_log(" A: %d %d %d\n", V3ARGS(A));
04427 bu_log(" B: %d %d %d\n", V3ARGS(B));
04428 bu_log(" C: %d %d %d\n", V3ARGS(C));
04429 bu_log(" D: %d %d %d\n", V3ARGS(D));
04430 }
04431
04432 swap_cell_pts(A, B, C, D, dsp);
04433 if (RT_G_DEBUG & DEBUG_HF) {
04434 bu_log(" A: %d %d %d\n", V3ARGS(A));
04435 bu_log(" B: %d %d %d\n", V3ARGS(B));
04436 bu_log(" C: %d %d %d\n", V3ARGS(C));
04437 bu_log(" D: %d %d %d\n", V3ARGS(D));
04438 }
04439
04440 if (project_pt(tri_pt, B, A, D, pt)) {
04441 if (project_pt(tri_pt, C, D, A, pt)) {
04442 bu_log("Now what???\n");
04443 }
04444 }
04445
04446 MAT4X3PNT(out, dsp->dsp_i.dsp_stom, tri_pt);
04447 if (RT_G_DEBUG & DEBUG_HF) {
04448 VPRINT("user_pt", p);
04449 VPRINT("tri_pt", tri_pt);
04450 VPRINT("model_space", out);
04451 bu_log("X: %d Y:%d\n",x, y);
04452 }
04453
04454 return 0;
04455 }
04456
04457
04458
04459 #undef dlog
04460 #undef XMIN
04461 #undef XMAX
04462 #undef YMIN
04463 #undef YMAX
04464 #undef ZMIN
04465 #undef ZMAX
04466 #undef ZMID
04467 #undef DSP
04468 #undef XCNT
04469 #undef YCNT
04470 #undef XSIZ
04471 #undef YSIZ
04472
04473
04474
04475
04476
04477
04478
04479
04480
04481
04482