/* * B R D F _ S E T U P */ HIDDEN int brdf_setup(register struct region *rp, struct bu_vls *matparm, char **dpp, struct mfuncs *mfp, struct rt_i *rtip) { register struct brdf_specific *pp; BU_CK_VLS( matparm ); BU_GETSTRUCT( pp, brdf_specific ); *dpp = (char *)pp; pp->magic = BRDF_MAGIC; pp->specular_refl = 0.7; pp->diffuse_refl = 0.3; pp->transmit = 0.0; pp->reflect = 0.0; pp->refrac_index = RI_AIR; pp->extinction = 0.0; pp->rms_slope = 0.05; if (bu_struct_parse( matparm, brdf_parse, (char *)pp ) < 0 ) { bu_free( (char *)pp, "brdf_specific" ); return(-1); } pp->rms_sq = pp->rms_slope * pp->rms_slope; pp->denom = 4.0 * bn_pi * pp->rms_sq; return(1); }
/* * Returns - * <0 failed * >0 success */ HIDDEN int spm_setup(register struct region *UNUSED(rp), struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *UNUSED(rtip)) /* New since 4.4 release */ { register struct spm_specific *spp; BU_CK_VLS(matparm); BU_GET(spp, struct spm_specific); *dpp = spp; spp->sp_file[0] = '\0'; spp->sp_w = -1; if (bu_struct_parse(matparm, spm_parse, (char *)spp) < 0) { BU_PUT(spp, struct spm_specific); return -1; } if (spp->sp_w < 0) spp->sp_w = 512; if (spp->sp_file[0] == '\0') goto fail; if ((spp->sp_map = bn_spm_init(spp->sp_w, sizeof(RGBpixel))) == BN_SPM_MAP_NULL) goto fail; if (bn_spm_load(spp->sp_map, spp->sp_file) < 0) goto fail; return 1; fail: spm_mfree((void *)spp); return -1; }
HIDDEN int phong_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *UNUSED(rtip)) { register struct phong_specific *pp; BU_CK_VLS(matparm); BU_GET(pp, struct phong_specific); *dpp = pp; pp->magic = PL_MAGIC; pp->shine = 10; pp->wgt_specular = 0.7; pp->wgt_diffuse = 0.3; pp->transmit = 0.0; pp->reflect = 0.0; pp->refrac_index = RI_AIR; pp->extinction = 0.0; pp->mfp = mfp; if (bu_struct_parse(matparm, phong_parse, (char *)pp) < 0) { BU_PUT(pp, struct phong_specific); return -1; } if (pp->transmit > 0) rp->reg_transmit = 1; return 1; }
/* * This routine is called (at prep time) * once for each region which uses this shader. * Any shader-specific initialization should be done here. * * Returns: * 1 success * 0 success, but delete region * -1 failure */ HIDDEN int toon_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *rtip) /* pointer to reg_udata in *rp */ /* New since 4.4 release */ { register struct toon_specific *toon_sp; /* check the arguments */ RT_CHECK_RTI(rtip); BU_CK_VLS(matparm); RT_CK_REGION(rp); if (rdebug&RDEBUG_SHADE) bu_log("toon_setup(%s)\n", rp->reg_name); /* Get memory for the shader parameters and shader-specific data */ BU_GET(toon_sp, struct toon_specific); *dpp = toon_sp; /* initialize the default values for the shader */ memcpy(toon_sp, &toon_defaults, sizeof(struct toon_specific)); /* parse the user's arguments for this use of the shader. */ if (bu_struct_parse(matparm, toon_parse_tab, (char *)toon_sp, NULL) < 0) return -1; if (rdebug&RDEBUG_SHADE) { bu_struct_print(" Parameters:", toon_print_tab, (char *)toon_sp); } return 1; }
static int X_dm(int argc, char *argv[]) { if (!strcmp(argv[0], "set")) { struct bu_vls vls; bu_vls_init(&vls); if (argc < 2) { /* Bare set command, print out current settings */ bu_vls_struct_print2(&vls, "dm_X internal variables", X_vparse, (const char *)dmp ); } else if (argc == 2) { bu_vls_struct_item_named(&vls, X_vparse, argv[1], (const char *)dmp, ','); } else { struct bu_vls tmp_vls; bu_vls_init(&tmp_vls); bu_vls_printf(&tmp_vls, "%s=\"", argv[1]); bu_vls_from_argv(&tmp_vls, argc-2, (const char **)argv+2); bu_vls_putc(&tmp_vls, '\"'); bu_struct_parse(&tmp_vls, X_vparse, (char *)dmp); bu_vls_free(&tmp_vls); } Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL); bu_vls_free(&vls); return TCL_OK; } return common_dm(argc, argv); }
HIDDEN int txt_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip) { register struct txt_specific *tp; int pixelbytes = 3; BU_CK_VLS(matparm); BU_GET(tp, struct txt_specific); *dpp = tp; bu_vls_init(&tp->tx_name); /* defaults */ tp->tx_w = tp->tx_n = -1; tp->tx_trans_valid = 0; tp->tx_scale[X] = 1.0; tp->tx_scale[Y] = 1.0; tp->tx_mirror = 0; tp->tx_datasrc = 0; /* source is auto-located by default */ tp->tx_binunifp = NULL; tp->tx_mp = NULL; /* load given values */ if (bu_struct_parse(matparm, txt_parse, (char *)tp) < 0) { BU_PUT(tp, struct txt_specific); return -1; } /* validate values */ if (tp->tx_w < 0) tp->tx_w = 512; if (tp->tx_n < 0) tp->tx_n = tp->tx_w; if (tp->tx_trans_valid) rp->reg_transmit = 1; BU_CK_VLS(&tp->tx_name); if (bu_vls_strlen(&tp->tx_name) <= 0) return -1; /* !?! if (tp->tx_name[0] == '\0') return -1; */ /* FAIL, no file */ if (BU_STR_EQUAL(mfp->mf_name, "bwtexture")) pixelbytes = 1; /* load the texture from its datasource */ if (txt_load_datasource(tp, rtip->rti_dbip, tp->tx_w * tp->tx_n * pixelbytes)<0) { bu_log("\nERROR: txt_setup() %s %s could not be loaded [source was %s]\n", rp->reg_name, bu_vls_addr(&tp->tx_name), tp->tx_datasrc==TXT_SRC_OBJECT?"object":tp->tx_datasrc==TXT_SRC_FILE?"file":"auto"); return -1; } if (rdebug & RDEBUG_SHADE) { bu_log("txt_setup: texture loaded! type=%s name=%s\n", tp->tx_datasrc==TXT_SRC_AUTO?"auto":tp->tx_datasrc==TXT_SRC_OBJECT?"object":tp->tx_datasrc==TXT_SRC_FILE?"file":"unknown", bu_vls_addr(&tp->tx_name)); bu_struct_print("texture", txt_parse, (char *)tp); } return 1; /* OK */ }
/* * O G L _ D M * * Implement display-manager specific commands, from MGED "dm" command. */ static int Ogl_dm(int argc, const char *argv[]) { if (BU_STR_EQUAL(argv[0], "set")) { struct bu_vls vls = BU_VLS_INIT_ZERO; if (argc < 2) { /* Bare set command, print out current settings */ bu_vls_struct_print2(&vls, "dm_ogl internal variables", Ogl_vparse, (const char *)&((struct ogl_vars *)dmp->dm_vars.priv_vars)->mvars); } else if (argc == 2) { bu_vls_struct_item_named(&vls, Ogl_vparse, argv[1], (const char *)&((struct ogl_vars *)dmp->dm_vars.priv_vars)->mvars, COMMA); } else { struct bu_vls tmp_vls = BU_VLS_INIT_ZERO; int ret; bu_vls_printf(&tmp_vls, "%s=\"", argv[1]); bu_vls_from_argv(&tmp_vls, argc-2, (const char **)argv+2); bu_vls_putc(&tmp_vls, '\"'); ret = bu_struct_parse(&tmp_vls, Ogl_vparse, (char *)&((struct ogl_vars *)dmp->dm_vars.priv_vars)->mvars); bu_vls_free(&tmp_vls); if (ret < 0) { bu_vls_free(&vls); return TCL_ERROR; } } Tcl_AppendResult(INTERP, bu_vls_addr(&vls), (char *)NULL); bu_vls_free(&vls); return TCL_OK; } return common_dm(argc, argv); }
/* * This routine is called (at prep time) once for each region which uses this * shader. The shader specific flat_specific structure is allocated and * default values are set. Then any user-given values override. */ HIDDEN int flat_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *rtip) { register struct flat_specific *flat_sp; /* check the arguments */ RT_CHECK_RTI(rtip); BU_CK_VLS(matparm); RT_CK_REGION(rp); if (rdebug&RDEBUG_SHADE) bu_log("flat_setup(%s)\n", rp->reg_name); /* Get memory for the shader parameters and shader-specific data */ BU_GET(flat_sp, struct flat_specific); *dpp = flat_sp; /* color priority: * * priority goes first to the flat shader's color parameter * second priority is to the material color value * third priority is to the flat shader's default color (white) */ /* initialize the default values for the shader */ memcpy(flat_sp, &flat_defaults, sizeof(struct flat_specific)); /* load the material color if it was set */ if (rp->reg_mater.ma_color_valid) { VMOVE(flat_sp->color, rp->reg_mater.ma_color); } /* parse the user's arguments for this use of the shader. */ if (bu_struct_parse(matparm, flat_parse_tab, (char *)flat_sp) < 0) return -1; if (rdebug&RDEBUG_SHADE) { bu_struct_print(" Parameters:", flat_parse_tab, (char *)flat_sp); } return 1; }
void mged_vls_struct_parse_old( struct bu_vls *vls, const char *title, struct bu_structparse *how_to_parse, char *structp, int argc, const char *argv[]) { if (argc < 2) { /* Bare set command, print out current settings */ bu_vls_struct_print2(vls, title, how_to_parse, structp); } else if (argc == 2) { struct bu_vls tmp_vls = BU_VLS_INIT_ZERO; bu_vls_strcpy(&tmp_vls, argv[1]); if (bu_struct_parse(&tmp_vls, how_to_parse, structp) < 0) bu_log("Warning - bu_struct_parse failure, mged_vls_struct_parse_old.\n"); bu_vls_free(&tmp_vls); } }
/* * F B M _ S E T U P */ HIDDEN int fbm_setup(register struct region *rp, struct bu_vls *matparm, char **dpp) { register struct fbm_specific *fbm; BU_CK_VLS( matparm ); BU_GETSTRUCT( fbm, fbm_specific ); *dpp = (char *)fbm; memcpy(fbm, &fbm_defaults, sizeof(struct fbm_specific)); if (rdebug&RDEBUG_SHADE) bu_log("fbm_setup\n"); if (bu_struct_parse( matparm, fbm_parse, (char *)fbm ) < 0 ) return(-1); if (rdebug&RDEBUG_SHADE) bu_struct_print( rp->reg_name, fbm_parse, (char *)fbm ); return(1); }
void mged_vls_struct_parse(struct bu_vls *vls, const char *title, struct bu_structparse *how_to_parse, const char *structp, int argc, const char *argv[]) { if (argc < 2) { /* Bare set command, print out current settings */ bu_vls_struct_print2(vls, title, how_to_parse, structp); } else if (argc == 2) { bu_vls_struct_item_named(vls, how_to_parse, argv[1], structp, ' '); } else { struct bu_vls tmp_vls = BU_VLS_INIT_ZERO; bu_vls_printf(&tmp_vls, "%s=\"", argv[1]); bu_vls_from_argv(&tmp_vls, argc-2, (const char **)argv+2); bu_vls_putc(&tmp_vls, '\"'); if (bu_struct_parse(&tmp_vls, how_to_parse, structp) < 0) bu_log("Warning - bu_struct_parse failure, mged_vls_struct_parse.\n"); bu_vls_free(&tmp_vls); } }
HIDDEN int ckr_setup(register struct region *UNUSED(rp), struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *UNUSED(rtip)) /* New since 4.4 release */ { register struct ckr_specific *ckp; /* Default will be white and black checkers */ BU_GET(ckp, struct ckr_specific); *dpp = ckp; ckp->ckr_a[0] = ckp->ckr_a[1] = ckp->ckr_a[2] = 255; ckp->ckr_b[0] = ckp->ckr_b[1] = ckp->ckr_b[2] = 0; ckp->ckr_scale = 2.0; if (bu_struct_parse(matparm, ckr_parse, (char *)ckp) < 0) { BU_PUT(ckp, struct ckr_specific); return -1; } ckp->ckr_a[0] &= 0x0ff; ckp->ckr_a[1] &= 0x0ff; ckp->ckr_a[2] &= 0x0ff; ckp->ckr_b[0] &= 0x0ff; ckp->ckr_b[1] &= 0x0ff; ckp->ckr_b[2] &= 0x0ff; return 1; }
HIDDEN int wood_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *UNUSED(rtip)) /* New since 4.4 release */ { register int i; register struct wood_specific *wd; register struct resource *resp = &rt_uniresource; /* * Get the impure storage for the control block */ BU_CK_VLS(matparm); BU_GET(wd, struct wood_specific); *dpp = wd; /* * Load the default values */ if (rp->reg_mater.ma_color_valid) { VSCALE(wd->lt_rgb, rp->reg_mater.ma_color, 255); } else { wd->lt_rgb[0] = 255; /* Light yellow */ wd->lt_rgb[1] = 255; wd->lt_rgb[2] = 224; } wd->dk_rgb[0] = 191; /* Brownish-red */ wd->dk_rgb[1] = 97; wd->dk_rgb[2] = 0; wd->ident = 0; wd->forw = WOOD_NULL; wd->rp = rp; wd->flags = 0; wd->overlay = 0; /* Draw only one ring */ wd->ns = 10; wd->jitter = 0.0; wd->scale = 1.0; wd->spacing = 5; /* 5mm space between rings */ wd->dd = 0.0; /* no dither of vertex */ wd->dz = 0.0; /* nor of Z-axis */ wd->qd = 0; wd->qp = 0; wd->phase = 5; wd->depth = 0; wd->dither[0] = bn_rand0to1(resp->re_randptr); wd->dither[1] = bn_rand0to1(resp->re_randptr); wd->dither[2] = bn_rand0to1(resp->re_randptr); VSETALL(wd->rot, 0); VSETALL(wd->vertex, 0); VSETALL(wd->D, 0); VSETALL(wd->V, 0); /* * Parse the MATPARM field */ if (bu_struct_parse(matparm, wood_parse, (char *)wd) < 0) { BU_PUT(wd, struct wood_specific); return -1; } /* * Do some sundry range and misc. checking */ for (i = 0; i < 3; i++) { if (wd->dither[i] < 0 || wd->dither[i] > 1.0) { bu_log("wood_setup(%s): dither is out of range.\n", rp->reg_name); return -1; } } if (wd->flags == EXPLICIT_VERTEX) { bu_log("wood_setup(%s): Explicit vertex specified without direction\n", rp->reg_name); return -1; } if (wd->flags == EXPLICIT_DIRECTION) { bu_log("wood_setup(%s): Explicit direction specified without vertex\n", rp->reg_name); return -1; } /* * Get the bounding RPP */ if (rt_bound_tree(rp->reg_treetop, wd->b_min, wd->b_max) < 0) return -1; /* * Add it to the wood chain */ wd->forw = Wood_Chain; Wood_Chain = wd; /* * See if the user has flagged this region as a member of a larger * combination. If so, go ahead and process it */ if (wd->ident == 0) wood_setup_2(wd); else { register struct wood_specific *wc; vect_t c_min, c_max; /* * First, process the accumulated chain of wood regions and * process all regions which have the specified ident field. */ VSETALL(c_min, 0); VSETALL(c_max, 0); for (wc = Wood_Chain; wc != WOOD_NULL; wc = wc->forw) { if (wc->ident == wd->ident) { VMIN(c_min, wc->b_min); VMAX(c_max, wc->b_max); } } /* * Now, loop through the chain again this time updating the * regions' min/max fields with the new values */ for (wc = Wood_Chain; wc != WOOD_NULL; wc = wc->forw) { if (wc->ident == wd->ident) { VMOVE(wc->b_min, c_min); VMOVE(wc->b_max, c_max); wood_setup_2(wc); } } /* * End of multi-region processing loop */ } /* * Normalize the RGB colors */ for (i = 0; i < 3; i++) { wd->lt_rgb[i] /= 255.0; wd->dk_rgb[i] /= 255.0; } /* * Return to the caller */ return 1; }
/* * This routine is called (at prep time) * once for each region which uses this shader. * Any shader-specific initialization should be done here. * * Returns: * 1 success * 0 success, but delete region * -1 failure */ HIDDEN int bbd_setup(struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip) { register struct bbd_specific *bbd_sp; struct rt_db_internal intern; struct rt_tgc_internal *tgc; int s; mat_t mat; struct bbd_img *bi; double angle; vect_t vtmp; int img_num; vect_t vv; /* check the arguments */ RT_CHECK_RTI(rtip); BU_CK_VLS(matparm); RT_CK_REGION(rp); if (rdebug&RDEBUG_SHADE) bu_log("bbd_setup(%s)\n", rp->reg_name); RT_CK_TREE(rp->reg_treetop); if (rp->reg_treetop->tr_a.tu_op != OP_SOLID) { bu_log("--- Warning: Region %s shader %s", rp->reg_name, mfp->mf_name); bu_bomb("Shader should be used on region of single (rec/rcc) primitive\n"); } RT_CK_SOLTAB(rp->reg_treetop->tr_a.tu_stp); if (rp->reg_treetop->tr_a.tu_stp->st_id != ID_REC) { bu_log("--- Warning: Region %s shader %s", rp->reg_name, mfp->mf_name); bu_log("Shader should be used on region of single REC/RCC primitive %d\n", rp->reg_treetop->tr_a.tu_stp->st_id); bu_bomb("oops\n"); } /* Get memory for the shader parameters and shader-specific data */ BU_GET(bbd_sp, struct bbd_specific); *dpp = bbd_sp; /* initialize the default values for the shader */ memcpy(bbd_sp, &bbd_defaults, sizeof(struct bbd_specific)); bu_vls_init(&bbd_sp->img_filename); BU_LIST_INIT(&bbd_sp->imgs); bbd_sp->rtip = rtip; /* because new_image() needs this */ bbd_sp->img_count = 0; /* parse the user's arguments for this use of the shader. */ if (bu_struct_parse(matparm, bbd_parse_tab, (char *)bbd_sp, NULL) < 0) return -1; if (bbd_sp->img_count > MAX_IMAGES) { bu_log("too many images (%zu) in shader for %s sb < %d\n", bbd_sp->img_count, rp->reg_name, MAX_IMAGES); bu_bomb("excessive image count\n"); } MAT_IDN(mat); RT_DB_INTERNAL_INIT(&intern); s = rt_db_get_internal(&intern, rp->reg_treetop->tr_a.tu_stp->st_dp, rtip->rti_dbip, mat, &rt_uniresource); if (intern.idb_minor_type != ID_TGC && intern.idb_minor_type != ID_REC) { bu_log("What did I get? %d\n", intern.idb_minor_type); } if (s < 0) { bu_log("%s:%d didn't get internal", __FILE__, __LINE__); bu_bomb(""); } tgc = (struct rt_tgc_internal *)intern.idb_ptr; RT_TGC_CK_MAGIC(tgc); angle = M_PI / (double)bbd_sp->img_count; img_num = 0; VMOVE(vv, tgc->h); VUNITIZE(vv); for (BU_LIST_FOR(bi, bbd_img, &bbd_sp->imgs)) { static const point_t o = VINIT_ZERO; bn_mat_arb_rot(mat, o, vv, angle*img_num); /* compute plane equation */ MAT4X3VEC(bi->img_plane, mat, tgc->a); VUNITIZE(bi->img_plane); bi->img_plane[H] = VDOT(tgc->v, bi->img_plane); MAT4X3VEC(vtmp, mat, tgc->b); VADD2(bi->img_origin, tgc->v, vtmp); /* image origin in 3d space */ /* calculate image u vector */ VREVERSE(bi->img_x, vtmp); VUNITIZE(bi->img_x); bi->img_xlen = MAGNITUDE(vtmp) * 2; /* calculate image v vector */ VMOVE(bi->img_y, tgc->h); VUNITIZE(bi->img_y); bi->img_ylen = MAGNITUDE(tgc->h); if (rdebug&RDEBUG_SHADE) { HPRINT("\nimg_plane", bi->img_plane); VPRINT("vtmp", vtmp); VPRINT("img_origin", bi->img_origin); bu_log("img_xlen:%g ", bi->img_xlen); VPRINT("img_x", bi->img_x); bu_log("img_ylen:%g ", bi->img_ylen); VPRINT("img_y", bi->img_y); } img_num++; } rt_db_free_internal(&intern); if (rdebug&RDEBUG_SHADE) { bu_struct_print(" Parameters:", bbd_print_tab, (char *)bbd_sp); } return 1; }
/* T R E E T H E R M _ S E T U P * * This routine is called (at prep time) * once for each region which uses this shader. * Any shader-specific initialization should be done here. */ HIDDEN int tthrm_setup(register struct region *rp, struct bu_vls *matparm, genptr_t *dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *rtip) /* pointer to reg_udata in *rp */ /* New since 4.4 release */ { register struct tthrm_specific *tthrm_sp; struct bu_mapped_file *tt_file; char *tt_data; long cyl_tot = 0; long tseg; float *fp; float fv[4]; double min_temp; double max_temp; point_t center; point_t pt; vect_t dir; static const double inv_nodes = 1.0/8.0; int node; int i; int long_size = 0; size_t file_size_long; size_t file_size_int; /* check the arguments */ RT_CHECK_RTI(rtip); BU_CK_VLS(matparm); RT_CK_REGION(rp); if (rdebug&RDEBUG_SHADE) bu_log("tthrm_setup(Region:\"%s\", tthrm(%s))\n", rp->reg_name, bu_vls_addr(matparm)); /* Get memory for the shader parameters and shader-specific data */ BU_GET(tthrm_sp, struct tthrm_specific); *dpp = tthrm_sp; tthrm_sp->magic = tthrm_MAGIC; tthrm_sp->tt_name[0] = '\0'; tthrm_sp->tt_min_temp = tthrm_sp->tt_max_temp = 0.0; if (rdebug&RDEBUG_SHADE) bu_log("Parsing: (%s)\n", bu_vls_addr(matparm)); if (bu_struct_parse(matparm, tthrm_parse, (char *)tthrm_sp) < 0) { bu_bomb(__FILE__); } if (tthrm_sp->tt_name[0] == '\0') { bu_log("Must specify file for tthrm shader on %s (got \"%s\"\n", rp->reg_name, bu_vls_addr(matparm)); bu_bomb(__FILE__); } tt_file = bu_open_mapped_file(tthrm_sp->tt_name, (char *)NULL); if (!tt_file) { bu_log("Error mapping \"%s\"\n", tthrm_sp->tt_name); bu_bomb("shader tthrm: can't get thermal data"); } tt_data = tt_file->buf; if (rdebug&RDEBUG_SHADE) bu_log("tthrm_setup() data: %p total\n", (void *)tt_data); /* Compute how big the file should be, so that we can guess * at the size of the integer at the front of the file */ file_size_int = sizeof(int) + *((int *)tt_data) * (sizeof(short) + sizeof(float) * 4 * NUM_NODES); file_size_long = sizeof(long) + *((long *)tt_data) * (sizeof(short) + sizeof(float) * 4 * NUM_NODES); switch (sizeof(long)) { case 8: if (tt_file->buflen == file_size_long) { /* 64bit data on 64bit host */ long_size = sizeof(long); tthrm_sp->tt_max_seg = cyl_tot = *((long *)tt_data); } else if (tt_file->buflen == file_size_int) { /* 32bit data on 32bit host */ long_size = sizeof(int); tthrm_sp->tt_max_seg = cyl_tot = *((int *)tt_data); } break; case 4: if (tt_file->buflen == file_size_long) { /* 32bit data on 32bit host */ long_size = sizeof(long); tthrm_sp->tt_max_seg = cyl_tot = *((long *)tt_data); } else if (tt_file->buflen == (file_size_long+4)) { /* 64bit data on 32bit host */ cyl_tot = *((int *)tt_data); if (cyl_tot != 0) { bu_log("%s:%d thermal data written on 64bit machine with more that 2^32 segs\n", __FILE__, __LINE__); bu_bomb(""); } long_size = sizeof(long) + 4; tthrm_sp->tt_max_seg = cyl_tot = ((int *)tt_data)[1]; } break; default: bu_log("a long int is %d bytes on this machine\n", sizeof(long)); bu_bomb("I can only handle 4 or 8 byte longs\n"); break; } if (rdebug&RDEBUG_SHADE) bu_log("cyl_tot = %ld\n", cyl_tot); tthrm_sp->tt_segs = (struct thrm_seg *) bu_calloc(cyl_tot, sizeof(struct thrm_seg), "thermal segs"); min_temp = MAX_FASTF; max_temp = -MAX_FASTF; #define CYL_DATA(_n) ((float *) (&tt_data[ \ long_size + \ (_n) * (sizeof(short) + sizeof(float) * 4 * NUM_NODES) + \ sizeof(short) \ ])) for (tseg = 0; tseg < cyl_tot; tseg++) { /* compute centerpoint, min/max temperature values */ fp = CYL_DATA(tseg); VSETALL(center, 0.0); for (node=0; node < NUM_NODES; node++, fp+=4) { /* this is necessary to assure that all float * values are aligned on 4-byte boundaries */ memcpy(fv, fp, sizeof(float)*4); if (rdebug&RDEBUG_SHADE) bu_log("tthrm_setup() node %d (%g %g %g) %g\n", node, fv[0], fv[1], fv[2], fv[3]); /* make sure we don't have any "infinity" values */ for (i=0; i < 4; i++) { if (fv[i] > MAX_FASTF || fv[i] < -MAX_FASTF) { bu_log("%s:%d seg %ld node %d coord %d out of bounds: %g\n", __FILE__, __LINE__, tseg, node, i, fv[i]); bu_bomb("choke, gasp, *croak*\n"); } } /* copy the values to the segment list, converting * from Meters to Millimeters in the process */ VSCALE(tthrm_sp->tt_segs[tseg].node[node], fv, 1000.0); tthrm_sp->tt_segs[tseg].temperature[node] = fv[3]; VADD2(center, center, fv); if (fv[3] > max_temp) max_temp = fv[3]; if (fv[3] < min_temp) min_temp = fv[3]; } VSCALE(center, center, 1000.0); VSCALE(tthrm_sp->tt_segs[tseg].pt, center, inv_nodes); if (rdebug&RDEBUG_SHADE) { bu_log("Center: (%g %g %g) (now in mm, not m)\n", V3ARGS(tthrm_sp->tt_segs[tseg].pt)); } /* compute vectors from center pt for each node */ fp = CYL_DATA(tseg); for (node=0; node < NUM_NODES; node++, fp+=4) { /* this is necessary to assure that all float * values are aligned on 4-byte boundaries */ memcpy(fv, fp, sizeof(float)*4); VSCALE(pt, fv, 1000.0); VSUB2(tthrm_sp->tt_segs[tseg].vect[node], pt, tthrm_sp->tt_segs[tseg].pt ); } /* compute a direction vector for the thermal segment */ VCROSS(dir, tthrm_sp->tt_segs[tseg].vect[0], tthrm_sp->tt_segs[tseg].vect[2]); VUNITIZE(dir); VMOVE(tthrm_sp->tt_segs[tseg].dir, dir); tthrm_sp->tt_segs[tseg].magic = THRM_SEG_MAGIC; } bu_close_mapped_file(tt_file); if (ZERO(tthrm_sp->tt_min_temp) && EQUAL(tthrm_sp->tt_max_temp, SMALL_FASTF)) { tthrm_sp->tt_min_temp = min_temp; tthrm_sp->tt_max_temp = max_temp; bu_log("computed temp min/max on %s: %g/%g\n", rp->reg_name, min_temp, max_temp); } else { min_temp =tthrm_sp->tt_min_temp; max_temp = tthrm_sp->tt_max_temp; bu_log("taking user specified on %s: min/max %g/%g\n", rp->reg_name, min_temp, max_temp); } if (!EQUAL(max_temp, min_temp)) { tthrm_sp->tt_temp_scale = 1.0 / (max_temp - min_temp); } else { /* min and max are equal, maybe zero */ if (ZERO(max_temp)) tthrm_sp->tt_temp_scale = 0.0; else tthrm_sp->tt_temp_scale = 255.0/max_temp; } /* The shader needs to operate in a coordinate system which stays * fixed on the region when the region is moved (as in animation) * we need to get a matrix to perform the appropriate transform(s). * * Shading is done in "region coordinates": */ db_region_mat(tthrm_sp->tthrm_m_to_sh, rtip->rti_dbip, rp->reg_name, &rt_uniresource); if (rdebug&RDEBUG_SHADE) { bu_log("min_temp: %17.14e max_temp %17.14e temp_scale: %17.14e\n", tthrm_sp->tt_min_temp, tthrm_sp->tt_max_temp, tthrm_sp->tt_temp_scale); bu_log("tthrm_setup(%s, %s)done\n", rp->reg_name, bu_vls_addr(matparm)); tthrm_print(rp, *dpp); } return 1; }
/* * This routine is called (at prep time) * once for each region which uses this shader. * Any shader-specific initialization should be done here. */ HIDDEN int gauss_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *rtip) /* pointer to reg_udata in *rp */ /* New since 4.4 release */ { register struct gauss_specific *gauss_sp; struct tree_bark tb; /* check the arguments */ RT_CHECK_RTI(rtip); BU_CK_VLS(matparm); RT_CK_REGION(rp); if (rdebug&RDEBUG_SHADE) bu_log("gauss_setup(%s)\n", rp->reg_name); if (! rtip->useair) bu_bomb("gauss shader used and useair not set\n"); /* Get memory for the shader parameters and shader-specific data */ BU_GET(gauss_sp, struct gauss_specific); *dpp = gauss_sp; /* initialize the default values for the shader */ memcpy(gauss_sp, &gauss_defaults, sizeof(struct gauss_specific)); /* parse the user's arguments for this use of the shader. */ if (bu_struct_parse(matparm, gauss_parse_tab, (char *)gauss_sp, NULL) < 0) return -1; /* We have to pick up the parameters for the gaussian puff now. * They won't be available later. So what we do is sneak a peak * inside the region, make sure the first item in it is an ellipsoid * solid, and if it is go steal a peek at its balls ... er ... make * that definition/parameters. */ BU_LIST_INIT(&gauss_sp->dbil); tb.l = &gauss_sp->dbil; tb.dbip = rtip->rti_dbip; tb.name = rp->reg_name; tb.gs = gauss_sp; tree_solids (rp->reg_treetop, &tb, OP_UNION, &rt_uniresource); /* XXX If this puppy isn't axis-aligned, we should come up with a * matrix to rotate it into alignment. We're going to have to do * computation in the space defined by this ellipsoid. */ if (rdebug&RDEBUG_SHADE) { bu_struct_print(" Parameters:", gauss_print_tab, (char *)gauss_sp); bn_mat_print("m_to_sh", gauss_sp->gauss_m_to_sh); } return 1; }
HIDDEN int scloud_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip) /* pointer to reg_udata in *rp */ { register struct scloud_specific *scloud; struct db_full_path full_path; mat_t region_to_model; mat_t model_to_region; mat_t tmp; BU_CK_VLS(matparm); BU_GET(scloud, struct scloud_specific); *dpp = scloud; if (rp->reg_aircode == 0) { bu_log("WARNING(%s): air shader '%s' applied to non-air region.\n%s\n", rp->reg_name, mfp->mf_name, " Set air flag with \"edcodes\" in mged"); bu_bomb(""); } memcpy(scloud, &scloud_defaults, sizeof(struct scloud_specific)); if (rdebug&RDEBUG_SHADE) bu_log("scloud_setup\n"); if (bu_struct_parse(matparm, scloud_parse, (char *)scloud) < 0) return -1; if (rdebug&RDEBUG_SHADE) (void)bu_struct_print(rp->reg_name, scloud_parse, (char *)scloud); /* get transformation between world and "region" coordinates */ if (db_string_to_path(&full_path, rtip->rti_dbip, rp->reg_name)) { /* bad thing */ bu_bomb("db_string_to_path() error"); } if (! db_path_to_mat(rtip->rti_dbip, &full_path, region_to_model, 0, &rt_uniresource)) { /* bad thing */ bu_bomb("db_path_to_mat() error"); } /* get matrix to map points from model space to "region" space */ bn_mat_inv(model_to_region, region_to_model); /* add the noise-space scaling */ MAT_IDN(tmp); if (!EQUAL(scloud->scale, 1.0)) { tmp[0] = tmp[5] = tmp[10] = 1.0 / scloud->scale; } else { tmp[0] = 1.0 / (scloud->vscale[0]); tmp[5] = 1.0 / (scloud->vscale[1]); tmp[10] = 1.0 / (scloud->vscale[2]); } bn_mat_mul(scloud->mtos, tmp, model_to_region); /* add the translation within noise space */ MAT_IDN(tmp); tmp[MDX] = scloud->delta[0]; tmp[MDY] = scloud->delta[1]; tmp[MDZ] = scloud->delta[2]; bn_mat_mul2(tmp, scloud->mtos); bn_mat_inv(scloud->stom, scloud->mtos); return 1; }
void nmg_2_vrml(struct db_tree_state *tsp, const struct db_full_path *pathp, struct model *m) { struct mater_info *mater = &tsp->ts_mater; const struct bn_tol *tol2 = tsp->ts_tol; struct nmgregion *reg; struct bu_ptbl verts; struct vrml_mat mat; struct bu_vls vls = BU_VLS_INIT_ZERO; char *tok; int i; int first = 1; int is_light = 0; point_t ave_pt = VINIT_ZERO; struct bu_vls shape_name = BU_VLS_INIT_ZERO; char *full_path; /* There may be a better way to capture the region_id, than * getting the rt_comb_internal structure, (and may be a better * way to capture the rt_comb_internal struct), but for now I just * copied the method used in select_lights/select_non_lights above, * could have used a global variable but I noticed none other were * used, so I didn't want to be the first */ struct directory *dp; struct rt_db_internal intern; struct rt_comb_internal *comb; int id; /* static due to libbu exception handling */ static float r, g, b; NMG_CK_MODEL(m); full_path = db_path_to_string(pathp); RT_CK_FULL_PATH(pathp); dp = DB_FULL_PATH_CUR_DIR(pathp); if (!(dp->d_flags & RT_DIR_COMB)) { return; } id = rt_db_get_internal(&intern, dp, dbip, (matp_t)NULL, &rt_uniresource); if (id < 0) { bu_log("Cannot internal form of %s\n", dp->d_namep); return; } if (id != ID_COMBINATION) { bu_log("Directory/database mismatch!\n\t is '%s' a combination or not?\n", dp->d_namep); return; } comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); if (mater->ma_color_valid) { r = mater->ma_color[0]; g = mater->ma_color[1]; b = mater->ma_color[2]; } else { r = g = b = 0.5; } if (mater->ma_shader) { tok = strtok(mater->ma_shader, tok_sep); bu_strlcpy(mat.shader, tok, TXT_NAME_SIZE); } else { mat.shader[0] = '\0'; } mat.shininess = -1; mat.transparency = -1.0; mat.lt_fraction = -1.0; VSETALL(mat.lt_dir, 0.0); mat.lt_angle = -1.0; mat.tx_file[0] = '\0'; mat.tx_w = -1; mat.tx_n = -1; bu_vls_strcpy(&vls, &mater->ma_shader[strlen(mat.shader)]); (void)bu_struct_parse(&vls, vrml_mat_parse, (char *)&mat, NULL); if (bu_strncmp("light", mat.shader, 5) == 0) { /* this is a light source */ is_light = 1; } else { path_2_vrml_id(&shape_name, full_path); fprintf(fp_out, "\t\tDEF %s Shape {\n", bu_vls_addr(&shape_name)); fprintf(fp_out, "\t\t\t# Component_ID: %ld %s\n", comb->region_id, full_path); fprintf(fp_out, "\t\t\tappearance Appearance {\n"); if (bu_strncmp("plastic", mat.shader, 7) == 0) { if (mat.shininess < 0) { mat.shininess = 10; } if (mat.transparency < SMALL_FASTF) { mat.transparency = 0.0; } fprintf(fp_out, "\t\t\t\tmaterial Material {\n"); fprintf(fp_out, "\t\t\t\t\tdiffuseColor %g %g %g \n", r, g, b); fprintf(fp_out, "\t\t\t\t\tshininess %g\n", 1.0-exp(-(double)mat.shininess/20.0)); if (mat.transparency > SMALL_FASTF) { fprintf(fp_out, "\t\t\t\t\ttransparency %g\n", mat.transparency); } fprintf(fp_out, "\t\t\t\t\tspecularColor %g %g %g \n\t\t\t\t}\n", 1.0, 1.0, 1.0); } else if (bu_strncmp("glass", mat.shader, 5) == 0) { if (mat.shininess < 0) { mat.shininess = 4; } if (mat.transparency < SMALL_FASTF) { mat.transparency = 0.8; } fprintf(fp_out, "\t\t\t\tmaterial Material {\n"); fprintf(fp_out, "\t\t\t\t\tdiffuseColor %g %g %g \n", r, g, b); fprintf(fp_out, "\t\t\t\t\tshininess %g\n", 1.0-exp(-(double)mat.shininess/20.0)); if (mat.transparency > SMALL_FASTF) { fprintf(fp_out, "\t\t\t\t\ttransparency %g\n", mat.transparency); } fprintf(fp_out, "\t\t\t\t\tspecularColor %g %g %g \n\t\t\t\t}\n", 1.0, 1.0, 1.0); } else if (bu_strncmp("texture", mat.shader, 7) == 0) { if (mat.tx_w < 0) { mat.tx_w = 512; } if (mat.tx_n < 0) { mat.tx_n = 512; } if (strlen(mat.tx_file)) { int tex_fd; unsigned char tex_buf[TXT_BUF_LEN * 3]; if ((tex_fd = open(mat.tx_file, O_RDONLY | O_BINARY)) == (-1)) { bu_log("Cannot open texture file (%s)\n", mat.tx_file); perror("g-vrml: "); } else { long tex_len; long bytes_read = 0; long bytes_to_go = 0; /* Johns note - need to check (test) the texture stuff */ fprintf(fp_out, "\t\t\t\ttextureTransform TextureTransform {\n"); fprintf(fp_out, "\t\t\t\t\tscale 1.33333 1.33333\n\t\t\t\t}\n"); fprintf(fp_out, "\t\t\t\ttexture PixelTexture {\n"); fprintf(fp_out, "\t\t\t\t\trepeatS TRUE\n"); fprintf(fp_out, "\t\t\t\t\trepeatT TRUE\n"); fprintf(fp_out, "\t\t\t\t\timage %d %d %d\n", mat.tx_w, mat.tx_n, 3); tex_len = mat.tx_w*mat.tx_n * 3; while (bytes_read < tex_len) { int nbytes; long readval; bytes_to_go = tex_len - bytes_read; CLAMP(bytes_to_go, 0, TXT_BUF_LEN * 3); nbytes = 0; while (nbytes < bytes_to_go) { readval = read(tex_fd, &tex_buf[nbytes], bytes_to_go-nbytes); if (readval < 0) { perror("READ ERROR"); break; } else { nbytes += readval; } } bytes_read += nbytes; for (i = 0; i < nbytes; i += 3) { fprintf(fp_out, "\t\t\t0x%02x%02x%02x\n", tex_buf[i], tex_buf[i+1], tex_buf[i+2]); } } fprintf(fp_out, "\t\t\t\t}\n"); close(tex_fd); } } } else if (mater->ma_color_valid) { /* no shader specified, but a color is assigned */ fprintf(fp_out, "\t\t\t\tmaterial Material {\n"); fprintf(fp_out, "\t\t\t\t\tdiffuseColor %g %g %g }\n", r, g, b); } else { /* If no color was defined set the colors according to the thousands groups */ int thou = comb->region_id / 1000; thou == 0 ? fprintf(fp_out, "\t\t\tmaterial USE Material_999\n") : thou == 1 ? fprintf(fp_out, "\t\t\tmaterial USE Material_1999\n") : thou == 2 ? fprintf(fp_out, "\t\t\tmaterial USE Material_2999\n") : thou == 3 ? fprintf(fp_out, "\t\t\tmaterial USE Material_3999\n") : thou == 4 ? fprintf(fp_out, "\t\t\tmaterial USE Material_4999\n") : thou == 5 ? fprintf(fp_out, "\t\t\tmaterial USE Material_5999\n") : thou == 6 ? fprintf(fp_out, "\t\t\tmaterial USE Material_6999\n") : thou == 7 ? fprintf(fp_out, "\t\t\tmaterial USE Material_7999\n") : thou == 8 ? fprintf(fp_out, "\t\t\tmaterial USE Material_8999\n") : fprintf(fp_out, "\t\t\tmaterial USE Material_9999\n"); } } if (!is_light) { nmg_triangulate_model(m, tol2); fprintf(fp_out, "\t\t\t}\n"); fprintf(fp_out, "\t\t\tgeometry IndexedFaceSet {\n"); fprintf(fp_out, "\t\t\t\tcoord Coordinate {\n"); } /* get list of vertices */ nmg_vertex_tabulate(&verts, &m->magic); if (!is_light) { fprintf(fp_out, "\t\t\t\t\tpoint ["); } else { VSETALL(ave_pt, 0.0); } for (i = 0; i < BU_PTBL_END(&verts); i++) { struct vertex *v; struct vertex_g *vg; point_t pt_meters; v = (struct vertex *)BU_PTBL_GET(&verts, i); NMG_CK_VERTEX(v); vg = v->vg_p; NMG_CK_VERTEX_G(vg); /* convert to desired units */ VSCALE(pt_meters, vg->coord, scale_factor); if (is_light) { VADD2(ave_pt, ave_pt, pt_meters); } if (first) { if (!is_light) { fprintf(fp_out, " %10.10e %10.10e %10.10e, # point %d\n", V3ARGS(pt_meters), i); } first = 0; } else if (!is_light) { fprintf(fp_out, "\t\t\t\t\t%10.10e %10.10e %10.10e, # point %d\n", V3ARGS(pt_meters), i); } } if (!is_light) { fprintf(fp_out, "\t\t\t\t\t]\n\t\t\t\t}\n"); } else { fastf_t one_over_count; one_over_count = 1.0/(fastf_t)BU_PTBL_END(&verts); VSCALE(ave_pt, ave_pt, one_over_count); } first = 1; if (!is_light) { fprintf(fp_out, "\t\t\t\tcoordIndex [\n"); for (BU_LIST_FOR(reg, nmgregion, &m->r_hd)) { struct shell *s; NMG_CK_REGION(reg); for (BU_LIST_FOR(s, shell, ®->s_hd)) { struct faceuse *fu; NMG_CK_SHELL(s); for (BU_LIST_FOR(fu, faceuse, &s->fu_hd)) { struct loopuse *lu; NMG_CK_FACEUSE(fu); if (fu->orientation != OT_SAME) { continue; } for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) { struct edgeuse *eu; NMG_CK_LOOPUSE(lu); if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC) { continue; } if (!first) { fprintf(fp_out, ",\n"); } else { first = 0; } fprintf(fp_out, "\t\t\t\t\t"); for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) { struct vertex *v; NMG_CK_EDGEUSE(eu); v = eu->vu_p->v_p; NMG_CK_VERTEX(v); fprintf(fp_out, " %d,", bu_ptbl_locate(&verts, (long *)v)); } fprintf(fp_out, "-1"); } } } } fprintf(fp_out, "\n\t\t\t\t]\n\t\t\t\tnormalPerVertex FALSE\n"); fprintf(fp_out, "\t\t\t\tconvex FALSE\n"); fprintf(fp_out, "\t\t\t\tcreaseAngle 0.5\n"); fprintf(fp_out, "\t\t\t}\n\t\t}\n"); } else {
void nmg_2_vrml(FILE *fp, const struct db_full_path *pathp, struct model *m, struct mater_info *mater) { struct nmgregion *reg; struct bu_ptbl verts; struct vrml_mat mat; struct bu_vls vls = BU_VLS_INIT_ZERO; char *tok; int i; int first=1; int is_light=0; float r, g, b; point_t ave_pt; char *full_path; /*There may be a better way to capture the region_id, than getting the rt_comb_internal structure, * (and may be a better way to capture the rt_comb_internal struct), but for now I just copied the * method used in select_lights/select_non_lights above, could have used a global variable but I noticed * none other were used, so I didn't want to be the first */ struct directory *dp; struct rt_db_internal intern; struct rt_comb_internal *comb; int id; NMG_CK_MODEL( m ); BARRIER_CHECK; full_path = db_path_to_string( pathp ); /* replace all occurrences of '.' with '_' */ char_replace(full_path, '.', '_'); RT_CK_FULL_PATH( pathp ); dp = DB_FULL_PATH_CUR_DIR( pathp ); if ( !(dp->d_flags & RT_DIR_COMB) ) return; id = rt_db_get_internal( &intern, dp, dbip, (matp_t)NULL, &rt_uniresource ); if ( id < 0 ) { bu_log( "Cannot internal form of %s\n", dp->d_namep ); return; } if ( id != ID_COMBINATION ) { bu_log( "Directory/database mismatch!\n\t is '%s' a combination or not?\n", dp->d_namep ); return; } comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB( comb ); if ( mater->ma_color_valid ) { r = mater->ma_color[0]; g = mater->ma_color[1]; b = mater->ma_color[2]; } else { r = g = b = 0.5; } if ( mater->ma_shader ) { tok = strtok( mater->ma_shader, tok_sep ); bu_strlcpy( mat.shader, tok, TXT_NAME_SIZE ); } else mat.shader[0] = '\0'; mat.shininess = -1; mat.transparency = -1.0; mat.lt_fraction = -1.0; VSETALL( mat.lt_dir, 0.0 ); mat.lt_angle = -1.0; mat.tx_file[0] = '\0'; mat.tx_w = -1; mat.tx_n = -1; bu_vls_strcpy( &vls, &mater->ma_shader[strlen(mat.shader)] ); (void)bu_struct_parse( &vls, vrml_mat_parse, (char *)&mat, NULL); if ( bu_strncmp( "light", mat.shader, 5 ) == 0 ) { /* this is a light source */ is_light = 1; } else { fprintf( fp, "\t<Shape DEF=\"%s\">\n", full_path); fprintf( fp, "\t\t<Appearance>\n"); if ( bu_strncmp( "plastic", mat.shader, 7 ) == 0 ) { if ( mat.shininess < 0 ) mat.shininess = 10; V_MAX(mat.transparency, 0.0); fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\" shininess=\"%g\" transparency=\"%g\" specularColor=\"%g %g %g\"/>\n", r, g, b, 1.0-exp(-(double)mat.shininess/20.0), mat.transparency, 1.0, 1.0, 1.0); } else if ( bu_strncmp( "glass", mat.shader, 5 ) == 0 ) { if ( mat.shininess < 0 ) mat.shininess = 4; if ( mat.transparency < 0.0 ) mat.transparency = 0.8; fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\" shininess=\"%g\" transparency=\"%g\" specularColor=\"%g %g %g\"/>\n", r, g, b, 1.0-exp(-(double)mat.shininess/20.0), mat.transparency, 1.0, 1.0, 1.0); } else if ( mater->ma_color_valid ) { fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\"/>\n", r, g, b); } else { /* If no color was defined set the colors according to the thousands groups */ int thou = comb->region_id/1000; thou == 0 ? fprintf( fp, "\t\t\t<Material USE=\"Material_999\"/>\n") : thou == 1 ? fprintf( fp, "\t\t\t<Material USE=\"Material_1999\"/>\n") : thou == 2 ? fprintf( fp, "\t\t\t<Material USE=\"Material_2999\"/>\n") : thou == 3 ? fprintf( fp, "\t\t\t<Material USE=\"Material_3999\"/>\n") : thou == 4 ? fprintf( fp, "\t\t\t<Material USE=\"Material_4999\"/>\n") : thou == 5 ? fprintf( fp, "\t\t\t<Material USE=\"Material_5999\"/>\n") : thou == 6 ? fprintf( fp, "\t\t\t<Material USE=\"Material_6999\"/>\n") : thou == 7 ? fprintf( fp, "\t\t\t<Material USE=\"Material_7999\"/>\n") : thou == 8 ? fprintf( fp, "\t\t\t<Material USE=\"Material_8999\"/>\n") : fprintf( fp, "\t\t\t<Material USE=\"Material_9999\"/>\n"); } } if ( !is_light ) { process_non_light(m); fprintf( fp, "\t\t</Appearance>\n"); } /* FIXME: need code to handle light */ /* get list of vertices */ nmg_vertex_tabulate( &verts, &m->magic ); fprintf( fp, "\t\t<IndexedFaceSet coordIndex=\"\n"); first = 1; if ( !is_light ) { for ( BU_LIST_FOR( reg, nmgregion, &m->r_hd ) ) { struct shell *s; NMG_CK_REGION( reg ); for ( BU_LIST_FOR( s, shell, ®->s_hd ) ) { struct faceuse *fu; NMG_CK_SHELL( s ); for ( BU_LIST_FOR( fu, faceuse, &s->fu_hd ) ) { struct loopuse *lu; NMG_CK_FACEUSE( fu ); if ( fu->orientation != OT_SAME ) continue; for ( BU_LIST_FOR( lu, loopuse, &fu->lu_hd ) ) { struct edgeuse *eu; NMG_CK_LOOPUSE( lu ); if ( BU_LIST_FIRST_MAGIC( &lu->down_hd ) != NMG_EDGEUSE_MAGIC ) continue; if ( !first ) fprintf( fp, ",\n" ); else first = 0; fprintf( fp, "\t\t\t\t" ); for ( BU_LIST_FOR( eu, edgeuse, &lu->down_hd ) ) { struct vertex *v; NMG_CK_EDGEUSE( eu ); v = eu->vu_p->v_p; NMG_CK_VERTEX( v ); fprintf( fp, " %d,", bu_ptbl_locate( &verts, (long *)v ) ); } fprintf( fp, "-1" ); } } } } /* close coordIndex */ fprintf( fp, "\" "); fprintf( fp, "normalPerVertex=\"false\" "); fprintf( fp, "convex=\"false\" "); fprintf( fp, "creaseAngle=\"0.5\" "); /* close IndexedFaceSet open tag */ fprintf( fp, ">\n"); } fprintf( fp, "\t\t\t<Coordinate point=\""); for ( i=0; i<BU_PTBL_END( &verts ); i++ ) { struct vertex *v; struct vertex_g *vg; point_t pt_meters; v = (struct vertex *)BU_PTBL_GET( &verts, i ); NMG_CK_VERTEX( v ); vg = v->vg_p; NMG_CK_VERTEX_G( vg ); /* convert to desired units */ VSCALE( pt_meters, vg->coord, scale_factor ); if ( is_light ) VADD2( ave_pt, ave_pt, pt_meters ); if ( first ) { if ( !is_light ) fprintf( fp, " %10.10e %10.10e %10.10e, ", V3ARGS(pt_meters)); first = 0; } else if ( !is_light ) fprintf( fp, "%10.10e %10.10e %10.10e, ", V3ARGS( pt_meters )); } /* close point */ fprintf(fp, "\""); /* close Coordinate */ fprintf(fp, "/>\n"); /* IndexedFaceSet end tag */ fprintf( fp, "\t\t</IndexedFaceSet>\n"); /* Shape end tag */ fprintf( fp, "\t</Shape>\n"); BARRIER_CHECK; }
/* F I R E _ S E T U P * * This routine is called (at prep time) * once for each region which uses this shader. * Any shader-specific initialization should be done here. */ HIDDEN int fire_setup(register struct region *rp, struct bu_vls *matparm, char **dpp, struct mfuncs *mfp, struct rt_i *rtip) /* pointer to reg_udata in *rp */ /* New since 4.4 release */ { register struct fire_specific *fire_sp; /* check the arguments */ RT_CHECK_RTI(rtip); BU_CK_VLS( matparm ); RT_CK_REGION(rp); if (rdebug&RDEBUG_SHADE) bu_log("fire_setup(%s)\n", rp->reg_name); /* Get memory for the shader parameters and shader-specific data */ BU_GETSTRUCT( fire_sp, fire_specific ); *dpp = (char *)fire_sp; /* initialize the default values for the shader */ memcpy(fire_sp, &fire_defaults, sizeof(struct fire_specific)); /* parse the user's arguments for this use of the shader. */ if (bu_struct_parse( matparm, fire_parse_tab, (char *)fire_sp ) < 0 ) return(-1); if (fire_sp->noise_size != -1.0) { VSETALL(fire_sp->noise_vscale, fire_sp->noise_size); } /* * The shader needs to operate in a coordinate system which stays * fixed on the region when the region is moved (as in animation). * We need to get a matrix to perform the appropriate transform(s). */ db_shader_mat(fire_sp->fire_m_to_sh, rtip, rp, fire_sp->fire_min, fire_sp->fire_max, &rt_uniresource); /* Build matrix to map shader space to noise space. * XXX If only we could get the frametime at this point * we could factor the flicker of flames into this matrix * rather than having to recompute it on a pixel-by-pixel basis. */ MAT_IDN(fire_sp->fire_sh_to_noise); MAT_DELTAS_VEC(fire_sp->fire_sh_to_noise, fire_sp->noise_delta); MAT_SCALE_VEC(fire_sp->fire_sh_to_noise, fire_sp->noise_vscale); /* get matrix for performing spline of fire colors */ rt_dspline_matrix(fire_sp->fire_colorspline_mat, "Catmull", 0.5, 0.0); if (rdebug&RDEBUG_SHADE || fire_sp->fire_debug ) { bu_struct_print( " FIRE Parameters:", fire_print_tab, (char *)fire_sp ); bn_mat_print( "m_to_sh", fire_sp->fire_m_to_sh ); bn_mat_print( "sh_to_noise", fire_sp->fire_sh_to_noise ); bn_mat_print( "colorspline", fire_sp->fire_colorspline_mat ); } return(1); }