int ged_v2m_point(struct ged *gedp, int argc, const char *argv[]) { point_t view; point_t model; static const char *usage = "x y z"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_VIEW(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 2 && argc != 4) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if (argc == 2) { if (bn_decode_vect(view, argv[1]) != 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } } else { double scan[3]; if (sscanf(argv[1], "%lf", &scan[X]) != 1) { bu_vls_printf(gedp->ged_result_str, "ged_m2v_point: bad X value - %s\n", argv[1]); return GED_ERROR; } if (sscanf(argv[2], "%lf", &scan[Y]) != 1) { bu_vls_printf(gedp->ged_result_str, "ged_m2v_point: bad Y value - %s\n", argv[2]); return GED_ERROR; } if (sscanf(argv[3], "%lf", &scan[Z]) != 1) { bu_vls_printf(gedp->ged_result_str, "ged_m2v_point: bad Z value - %s\n", argv[3]); return GED_ERROR; } /* convert from double to fastf_t */ VMOVE(view, scan); } /* Convert the incoming view point to a model point */ MAT4X3PNT(model, gedp->ged_gvp->gv_view2model, view); bn_encode_vect(gedp->ged_result_str, model); return GED_OK; }
/* * Phase 2 setup routine */ HIDDEN void wood_setup_2(struct wood_specific *wd) { mat_t xlate; int i; vect_t a_vertex, a_dir; register struct resource *resp = &rt_uniresource; /* * See if the user specified absolute coordinates for the vertex and * direction. If so, use those instead of the RPP. */ bn_mat_angles(xlate, V3ARGS(wd->rot)); if (wd->flags & EXPLICIT_VERTEX) { MAT4X3PNT(wd->vertex, xlate, wd->V); MAT4X3PNT(wd->dir, xlate, wd->D); } else { if (wd->dz > 0.0) { for (i = 0; i < 2; i++) { a_vertex[i] = wd->b_min[i]; a_dir[i] = wd->b_max[i]; } /* Z component is [2] */ a_vertex[2] = ((wd->b_max[2] - wd->b_min[2]) * (bn_rand0to1(resp->re_randptr) * wd->dz)) + wd->b_min[2]; a_dir[2] = ((wd->b_max[2] - wd->b_min[2]) * (bn_rand0to1(resp->re_randptr) * wd->dz)) + wd->b_min[2]; } else { for (i = 0; i < 3; i++) { a_vertex[i] = ((wd->b_max[i] - wd->b_min[i]) * (bn_rand0to1(resp->re_randptr) * wd->dd)) + wd->b_min[i]; a_dir[i] = ((wd->b_max[i] - wd->b_min[i]) * (bn_rand0to1(resp->re_randptr) * wd->dd)) + wd->b_max[i]; } } MAT4X3PNT(wd->vertex, xlate, a_vertex); MAT4X3PNT(wd->dir, xlate, a_dir); } VSUB2(wd->dir, wd->dir, wd->vertex); VUNITIZE(wd->dir); }
int ged_model2grid_lu(struct ged *gedp, int argc, const char *argv[]) { fastf_t f; point_t view_pt; point_t model_pt; point_t mo_view_pt; /* model origin in view space */ point_t diff; double scan[3]; static const char *usage = "x y z"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_VIEW(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); if (argc != 4) goto bad; VSETALL(model_pt, 0.0); MAT4X3PNT(mo_view_pt, gedp->ged_gvp->gv_model2view, model_pt); if (sscanf(argv[1], "%lf", &scan[X]) != 1 || sscanf(argv[2], "%lf", &scan[Y]) != 1 || sscanf(argv[3], "%lf", &scan[Z]) != 1) goto bad; VSCALE(model_pt, scan, gedp->ged_wdbp->dbip->dbi_local2base); MAT4X3PNT(view_pt, gedp->ged_gvp->gv_model2view, model_pt); VSUB2(diff, view_pt, mo_view_pt); f = gedp->ged_gvp->gv_scale * gedp->ged_wdbp->dbip->dbi_base2local; VSCALE(diff, diff, f); bu_vls_printf(gedp->ged_result_str, "%.15e %.15e", diff[X], diff[Y]); return GED_OK; bad: bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; }
int _ged_do_slew(struct ged *gedp, vect_t svec) { point_t model_center; MAT4X3PNT(model_center, gedp->ged_gvp->gv_view2model, svec); MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, model_center); ged_view_update(gedp->ged_gvp); return GED_OK; }
int main(int argc, char *argv[]) { int val; fastf_t yaw, pitch, roll; vect_t temp, point, zero; mat_t mat; /* intentionally double for scan */ double time; double scan[3]; VSETALL(temp, 0.0); VSETALL(point, 0.0); VSETALL(zero, 0.0); (void) get_args(argc, argv); while (1) { /*read line from table */ val = scanf("%lf%*[^-0123456789]", &time); /*read time, ignore garbage*/ if (val < 1) { break; } val = scanf("%lf %lf %lf", &scan[0], &scan[1], &scan[2]); if (val < 3) { break; } /* double to fastf_t */ VMOVE(point, scan); val = scanf("%lf %lf %lf", &scan[0], &scan[1], &scan[2]); if (val < 3) { break; } /* double to fastf_t */ yaw = scan[0]; pitch = scan[1]; roll = scan[2]; anim_dy_p_r2mat(mat, yaw, pitch, roll); anim_add_trans(mat, point, zero); MAT4X3PNT(temp, mat, offset); printf("%.10g\t%.10g\t%.10g\t%.10g", time, temp[0], temp[1], temp[2]); if (full_print) printf("\t%.10g\t%.10g\t%.10g", yaw, pitch, roll); printf("\n"); } return 0; }
void draw_e_axes() { point_t v_ap1; /* axes position in view coordinates */ point_t v_ap2; /* axes position in view coordinates */ mat_t rot_mat; struct ged_axes_state gas; if (STATE == ST_S_EDIT) { MAT4X3PNT(v_ap1, view_state->vs_gvp->gv_model2view, e_axes_pos); MAT4X3PNT(v_ap2, view_state->vs_gvp->gv_model2view, curr_e_axes_pos); } else if (STATE == ST_O_EDIT) { point_t m_ap2; MAT4X3PNT(v_ap1, view_state->vs_gvp->gv_model2view, es_keypoint); MAT4X3PNT(m_ap2, modelchanges, es_keypoint); MAT4X3PNT(v_ap2, view_state->vs_gvp->gv_model2view, m_ap2); } else return; memset(&gas, 0, sizeof(struct ged_axes_state)); VMOVE(gas.gas_axes_pos, v_ap1); gas.gas_axes_size = axes_state->ax_edit_size1 * INV_GED; VMOVE(gas.gas_axes_color, color_scheme->cs_edit_axes1); VMOVE(gas.gas_label_color, color_scheme->cs_edit_axes_label1); gas.gas_line_width = axes_state->ax_edit_linewidth1; dm_draw_axes(dmp, view_state->vs_gvp->gv_size, view_state->vs_gvp->gv_rotation, &gas); memset(&gas, 0, sizeof(struct ged_axes_state)); VMOVE(gas.gas_axes_pos, v_ap2); gas.gas_axes_size = axes_state->ax_edit_size2 * INV_GED; VMOVE(gas.gas_axes_color, color_scheme->cs_edit_axes2); VMOVE(gas.gas_label_color, color_scheme->cs_edit_axes_label2); gas.gas_line_width = axes_state->ax_edit_linewidth2; bn_mat_mul(rot_mat, view_state->vs_gvp->gv_rotation, acc_rot_sol); dm_draw_axes(dmp, view_state->vs_gvp->gv_size, rot_mat, &gas); }
/* beginning of a frame */ void view_2init( struct application *ap ) { extern fastf_t azimuth, elevation; fastf_t elvang, aziang; vect_t temp, aimpt; fastf_t backoff; if ( numreflect > MAXREFLECT ) { bu_log("Warning: maxreflect too large (%d), using %d\n", numreflect, MAXREFLECT ); numreflect = MAXREFLECT; } elvang = elevation * DEG2RAD; aziang = azimuth * DEG2RAD; uhoriz[0] = (fastf_t) sin(aziang); uhoriz[1] = (fastf_t) -cos(aziang); uhoriz[3] = (fastf_t) 0.0; VUNITIZE( uhoriz ); unorml[0] = (fastf_t) cos(elvang) * uhoriz[1]; unorml[1] = (fastf_t) -cos(elvang) * uhoriz[0]; unorml[2] = (fastf_t) -sin(elvang); VUNITIZE( unorml ); /* this doesn't seem to be quite right emanat.f */ uvertp[0] = uhoriz[1] * unorml[2] - unorml[1]* uhoriz[2]; uvertp[1] = uhoriz[2] * unorml[0] - unorml[2]* uhoriz[0]; uvertp[2] = uhoriz[0] * unorml[1] - unorml[0]* uhoriz[1]; VUNITIZE( uvertp ); VPRINT("uhoriz", uhoriz); VPRINT("unorml", unorml); VPRINT("uvertp", uvertp); totali = 0.0; totalq = 0.0; VSET(temp, 0.0, 0.0, -M_SQRT2); MAT4X3PNT( aimpt, view2model, temp); bu_log("aim point %f %f %f\n", aimpt[0], aimpt[1], aimpt[2]); bu_log("viewsize %f\n", viewsize); backoff = M_SQRT1_2*viewsize; bu_log("backoff %f\n", backoff); #ifdef SAR sar_2init( ap ); #endif }
void three_dcoord_out(FILE *fp, fastf_t *m) { unsigned char buf[3*8]; double p1[3]; double p2[3]; fread( buf, 1, 3*8, fp ); ntohd( (unsigned char *)p1, buf, 3 ); MAT4X3PNT( p2, m, p1 ); htond( buf, (unsigned char *)p2, 3 ); fwrite( buf, 1, 3*8, stdout ); }
void two_dcoord_out(FILE *fp, fastf_t *m) { unsigned char buf[2*8]; double p1[3]; double p2[3]; fread( buf, 1, 2*8, fp ); ntohd( (unsigned char *)p1, buf, 2 ); p1[2] = 0; /* no Z */ MAT4X3PNT( p2, m, p1 ); htond( buf, (unsigned char *)p2, 3 ); fwrite( buf, 1, 3*8, stdout ); }
void three_coord_out(FILE *fp, fastf_t *m) { point_t p1; short p2[3]; p1[0] = getshort(fp); /* get X */ p1[1] = getshort(fp); /* and Y */ p1[2] = getshort(fp); /* and Z */ MAT4X3PNT( p2, m, p1 ); putsi(p2[0]); /* put X */ putsi(p2[1]); /* and Y */ putsi(p2[2]); /* and Z */ }
/* beginning of a frame */ void view_2init(struct application *ap) { extern double azimuth, elevation; vect_t temp, aimpt; union radrec r; if ( numreflect > MAXREFLECT ) { bu_log("Warning: maxreflect too large (%d), using %d\n", numreflect, MAXREFLECT ); numreflect = MAXREFLECT; } bu_log( "Ray Spacing: %f rays/cm\n", 10.0*(width/viewsize) ); /* Header Record */ memset((char *)&r, 0, sizeof(r)); /*XXX*/ r.h.head[0] = 'h'; r.h.head[1] = 'e'; r.h.head[2] = 'a'; r.h.head[3] = 'd'; r.h.id = 1; r.h.iview = 1; r.h.miview = - r.h.iview; VSET( temp, 0.0, 0.0, -1.414 ); /* Point we are looking at */ MAT4X3PNT( aimpt, view2model, temp ); r.h.cx = aimpt[0]; /* aimpoint */ r.h.cy = aimpt[1]; r.h.cz = aimpt[2]; r.h.back = 1.414*viewsize/2.0; /* backoff */ r.h.e = elevation; r.h.a = azimuth; r.h.vert = viewsize; r.h.horz = viewsize; r.h.nvert = height; r.h.nhorz = width; r.h.maxrfl = numreflect; writerec( &r, outfp ); /* XXX - write extra header records */ memset((char *)&r, 0, sizeof(r)); writerec( &r, outfp ); writerec( &r, outfp ); }
/** * Import an superellipsoid/sphere from the database format to the * internal structure. Apply modeling transformations as wsuperell. */ int rt_superell_import4(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip) { struct rt_superell_internal *eip; union record *rp; fastf_t vec[3*4 + 2]; if (dbip) RT_CK_DBI(dbip); BU_CK_EXTERNAL(ep); rp = (union record *)ep->ext_buf; /* Check record type */ if (rp->u_id != ID_SOLID) { bu_log("rt_superell_import4(): defective record\n"); return -1; } RT_CK_DB_INTERNAL(ip); ip->idb_major_type = DB5_MAJORTYPE_BRLCAD; ip->idb_type = ID_SUPERELL; ip->idb_meth = &OBJ[ID_SUPERELL]; BU_ALLOC(ip->idb_ptr, struct rt_superell_internal); eip = (struct rt_superell_internal *)ip->idb_ptr; eip->magic = RT_SUPERELL_INTERNAL_MAGIC; /* Convert from database to internal format */ flip_fastf_float(vec, rp->s.s_values, 4, dbip->dbi_version < 0 ? 1 : 0); /* Apply modeling transformations */ if (mat == NULL) mat = bn_mat_identity; MAT4X3PNT(eip->v, mat, &vec[0*3]); MAT4X3VEC(eip->a, mat, &vec[1*3]); MAT4X3VEC(eip->b, mat, &vec[2*3]); MAT4X3VEC(eip->c, mat, &vec[3*3]); if (dbip->dbi_version < 0) { eip->n = flip_dbfloat(rp->s.s_values[12]); eip->e = flip_dbfloat(rp->s.s_values[13]); } else { eip->n = rp->s.s_values[12]; eip->e = rp->s.s_values[13]; } return 0; /* OK */ }
int ged_savekey(struct ged *gedp, int argc, const char *argv[]) { FILE *fp; fastf_t timearg; vect_t eye_model; vect_t temp; static const char *usage = "file [time]"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_VIEW(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc < 2 || 3 < argc) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if ((fp = fopen(argv[1], "a")) == NULL) { perror(argv[1]); return TCL_ERROR; } if (argc > 2) { timearg = atof(argv[2]); fprintf(fp, "%f\n", timearg); } /* * Eye is in conventional place. */ VSET(temp, 0.0, 0.0, 1.0); MAT4X3PNT(eye_model, gedp->ged_gvp->gv_view2model, temp); savekey_rt_oldwrite(gedp, fp, eye_model); (void)fclose(fp); return GED_OK; }
/** * Import an metaball/sphere from the database format to the internal * structure. Apply modeling transformations as well. */ int rt_metaball_import5(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip) { struct wdb_metaballpt *mbpt; struct rt_metaball_internal *mb; int metaball_count = 0, i; /* must be double for import and export */ double *buf; if (dbip) RT_CK_DBI(dbip); BU_CK_EXTERNAL(ep); metaball_count = ntohl(*(uint32_t *)ep->ext_buf); buf = (double *)bu_malloc((metaball_count*5+1)*SIZEOF_NETWORK_DOUBLE, "rt_metaball_import5: buf"); bu_cv_ntohd((unsigned char *)buf, (unsigned char *)ep->ext_buf+2*SIZEOF_NETWORK_LONG, metaball_count*5+1); RT_CK_DB_INTERNAL(ip); ip->idb_major_type = DB5_MAJORTYPE_BRLCAD; ip->idb_type = ID_METABALL; ip->idb_meth = &OBJ[ID_METABALL]; BU_ALLOC(ip->idb_ptr, struct rt_metaball_internal); mb = (struct rt_metaball_internal *)ip->idb_ptr; mb->magic = RT_METABALL_INTERNAL_MAGIC; mb->method = ntohl(*(uint32_t *)(ep->ext_buf + SIZEOF_NETWORK_LONG)); mb->threshold = buf[0]; BU_LIST_INIT(&mb->metaball_ctrl_head); if (mat == NULL) mat = bn_mat_identity; for (i = 1; i <= metaball_count * 5; i += 5) { /* Apply modeling transformations */ BU_GET(mbpt, struct wdb_metaballpt); mbpt->l.magic = WDB_METABALLPT_MAGIC; MAT4X3PNT(mbpt->coord, mat, &buf[i]); mbpt->fldstr = buf[i+3] / mat[15]; mbpt->sweat = buf[i+4]; BU_LIST_INSERT(&mb->metaball_ctrl_head, &mbpt->l); } bu_free((void *)buf, "rt_metaball_import5: buf"); return 0; /* OK */ }
void draw_m_axes() { point_t m_ap; /* axes position in model coordinates, mm */ point_t v_ap; /* axes position in view coordinates */ struct ged_axes_state gas; VSCALE(m_ap, axes_state->ax_model_pos, local2base); MAT4X3PNT(v_ap, view_state->vs_gvp->gv_model2view, m_ap); memset(&gas, 0, sizeof(struct ged_axes_state)); VMOVE(gas.gas_axes_pos, v_ap); gas.gas_axes_size = axes_state->ax_model_size * INV_GED; VMOVE(gas.gas_axes_color, color_scheme->cs_model_axes); VMOVE(gas.gas_label_color, color_scheme->cs_model_axes_label); gas.gas_line_width = axes_state->ax_model_linewidth; dm_draw_axes(dmp, view_state->vs_gvp->gv_size, view_state->vs_gvp->gv_rotation, &gas); }
void three_dcoord_out(FILE *fp, fastf_t *m) { unsigned char buf[3*8]; double p1[3]; double p2[3]; size_t ret; ret = fread(buf, 1, 3*8, fp); if (ret < 3*8) perror("fread"); bu_cv_ntohd((unsigned char *)p1, buf, 3); MAT4X3PNT(p2, m, p1); bu_cv_htond(buf, (unsigned char *)p2, 3); ret = fwrite(buf, 1, 3*8, stdout); if (ret < 3*8) perror("fwrite"); }
int ged_view2model_lu(struct ged *gedp, int argc, const char *argv[]) { fastf_t sf; point_t view_pt; point_t model_pt; double scan[3]; static const char *usage = "x y z"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_VIEW(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); if (argc != 4) goto bad; if (sscanf(argv[1], "%lf", &scan[X]) != 1 || sscanf(argv[2], "%lf", &scan[Y]) != 1 || sscanf(argv[3], "%lf", &scan[Z]) != 1) goto bad; /* convert from double to fastf_t */ VMOVE(view_pt, scan); sf = 1.0 / (gedp->ged_gvp->gv_scale * gedp->ged_wdbp->dbip->dbi_base2local); VSCALE(view_pt, view_pt, sf); MAT4X3PNT(model_pt, gedp->ged_gvp->gv_view2model, view_pt); VSCALE(model_pt, model_pt, gedp->ged_wdbp->dbip->dbi_base2local); bn_encode_vect(gedp->ged_result_str, model_pt); return GED_OK; bad: bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; }
/** * Given a point in model space coordinates (in mm) convert it to view * (screen) coordinates which must be scaled to correspond to actual * screen coordinates. If no input coordinates are supplied, the * model2view matrix is displayed. */ int ged_model2view(struct ged *gedp, int argc, const char *argv[]) { point_t view_pt; double model_pt[3]; /* intentionally double for scan */ static const char *usage = "[x y z]"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_VIEW(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* get the model2view matrix */ if (argc == 1) { bn_encode_mat(gedp->ged_result_str, gedp->ged_gvp->gv_model2view); return GED_OK; } if (argc != 4) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if (sscanf(argv[1], "%lf", &model_pt[X]) != 1 || sscanf(argv[2], "%lf", &model_pt[Y]) != 1 || sscanf(argv[3], "%lf", &model_pt[Z]) != 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } MAT4X3PNT(view_pt, gedp->ged_gvp->gv_model2view, model_pt); bn_encode_vect(gedp->ged_result_str, view_pt); return GED_OK; }
/** * Import an superellipsoid/sphere from the database format to the * internal structure. Apply modeling transformations as wsuperell. */ int rt_superell_import5(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip) { struct rt_superell_internal *eip; /* must be double for import and export */ double vec[ELEMENTS_PER_VECT*4 + 2]; if (dbip) RT_CK_DBI(dbip); RT_CK_DB_INTERNAL(ip); BU_CK_EXTERNAL(ep); BU_ASSERT_LONG(ep->ext_nbytes, ==, SIZEOF_NETWORK_DOUBLE * (ELEMENTS_PER_VECT*4 + 2)); ip->idb_major_type = DB5_MAJORTYPE_BRLCAD; ip->idb_type = ID_SUPERELL; ip->idb_meth = &OBJ[ID_SUPERELL]; BU_ALLOC(ip->idb_ptr, struct rt_superell_internal); eip = (struct rt_superell_internal *)ip->idb_ptr; eip->magic = RT_SUPERELL_INTERNAL_MAGIC; /* Convert from database (network) to internal (host) format */ bu_cv_ntohd((unsigned char *)vec, ep->ext_buf, ELEMENTS_PER_VECT*4 + 2); /* Apply modeling transformations */ if (mat == NULL) mat = bn_mat_identity; MAT4X3PNT(eip->v, mat, &vec[0*ELEMENTS_PER_VECT]); MAT4X3VEC(eip->a, mat, &vec[1*ELEMENTS_PER_VECT]); MAT4X3VEC(eip->b, mat, &vec[2*ELEMENTS_PER_VECT]); MAT4X3VEC(eip->c, mat, &vec[3*ELEMENTS_PER_VECT]); eip->n = vec[4*ELEMENTS_PER_VECT]; eip->e = vec[4*ELEMENTS_PER_VECT + 1]; return 0; /* OK */ }
int ged_view2model_vec(struct ged *gedp, int argc, const char *argv[]) { point_t model_vec; point_t view_vec; mat_t inv_Viewrot; double scan[3]; static const char *usage = "x y z"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_VIEW(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); if (argc != 4) goto bad; if (sscanf(argv[1], "%lf", &scan[X]) != 1 || sscanf(argv[2], "%lf", &scan[Y]) != 1 || sscanf(argv[3], "%lf", &scan[Z]) != 1) goto bad; /* convert from double to fastf_t */ VMOVE(view_vec, scan); bn_mat_inv(inv_Viewrot, gedp->ged_gvp->gv_rotation); MAT4X3PNT(model_vec, inv_Viewrot, view_vec); bn_encode_vect(gedp->ged_result_str, model_vec); return GED_OK; bad: bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; }
struct edge_g_cnurb * Get_cnurb_curve(int curve_de, int *linear) { int i; int curve; struct edge_g_cnurb *crv; *linear = 0; curve = (curve_de - 1)/2; if (curve >= dirarraylen) { bu_log("Get_cnurb_curve: DE=%d is too large, dirarraylen = %d\n", curve_de, dirarraylen); return (struct edge_g_cnurb *)NULL; } switch (dir[curve]->type) { case 110: { /* line */ int pt_type; int type; point_t pt1; point_t start_pt, end_pt; Readrec(dir[curve]->param); Readint(&type, ""); if (type != dir[curve]->type) { bu_log("Error in Get_cnurb_curve, looking for curve type %d, found %d\n" , dir[curve]->type, type); return (struct edge_g_cnurb *)NULL; } /* Read first point */ for (i = 0; i < 3; i++) Readcnv(&pt1[i], ""); MAT4X3PNT(start_pt, *dir[curve]->rot, pt1); /* Read second point */ for (i = 0; i < 3; i++) Readcnv(&pt1[i], ""); MAT4X3PNT(end_pt, *dir[curve]->rot, pt1); /* pt_type for rational UVW coords */ pt_type = RT_NURB_MAKE_PT_TYPE(3, 3, 1); /* make a linear edge_g_cnurb (order=2) */ crv = rt_nurb_new_cnurb(2, 4, 2, pt_type); /* insert control mesh */ VMOVE(crv->ctl_points, start_pt); VMOVE(&crv->ctl_points[3], end_pt); /* insert knot values */ crv->k.knots[0] = 0.0; crv->k.knots[1] = 0.0; crv->k.knots[2] = 1.0; crv->k.knots[3] = 1.0; *linear = 1; return crv; } case 126: /* B-spline */ crv = Get_cnurb(curve); if (crv->order < 3) *linear = 1; return crv; default: bu_log("Not yet handling curves of type: %s\n", iges_type(dir[curve]->type)); break; } return (struct edge_g_cnurb *)NULL; }
static void log_Run(void) { time_t clock_time; mat_t model2hv; /* model to h, v matrix */ mat_t hv2model; /* h, v tp model matrix */ quat_t orient; /* orientation */ point_t hv_eye; /* eye position in h, v coords */ point_t m_eye; /* eye position in model coords */ fastf_t hv_viewsize; /* size of view in h, v coords */ fastf_t m_viewsize; /* size of view in model coords. */ /* Current date and time get printed in header comment */ (void) time(&clock_time); (void) printf("# Log information produced by cell-fb %s\n", ctime(&clock_time)); (void) printf("az_el: %f %f\n", az, el); (void) printf("view_extrema: %f %f %f %f\n", SCRX2H(0), SCRX2H(fb_width), SCRY2V(0), SCRY2V(fb_height)); (void) printf("fb_size: %d %d\n", fb_width, fb_height); /* Produce the orientation, the model eye_pos, and the model * view size for input into rtregis. * First use the azimuth and elevation to produce the model2hv * matrix and use that to find the orientation. */ MAT_IDN(model2hv); MAT_IDN(hv2model); /* Print out the "view" just to keep rtregis from belly-aching */ printf("View: %g azimuth, %g elevation\n", az, el); /** mat_ae(model2hv, az, el); **/ /* Formula from rt/do.c */ bn_mat_angles(model2hv, 270.0+el, 0.0, 270.0-az); model2hv[15] = 25.4; /* input is in inches */ bn_mat_inv(hv2model, model2hv); quat_mat2quat(orient, model2hv); printf("Orientation: %.6f, %.6f, %.6f, %.6f\n", V4ARGS(orient)); /* Now find the eye position in h, v space. Note that the eye * is located at the center of the image; in this case, the center * of the screen space, i.e., the framebuffer.) * Also find the hv_viewsize at this time. */ hv_viewsize = SCRX2H((double)fb_width) - SCRX2H(0.0); hv_eye[0] = SCRX2H((double)fb_width/2); hv_eye[1] = SCRY2V((double)fb_height/2); hv_eye[2] = hv_viewsize/2; /* Debugging */ printf("hv_viewsize= %g\n", hv_viewsize); printf("hv_eye= %.6f, %.6f, %.6f\n", V3ARGS(hv_eye)); /* Now find the model eye_position and report on that */ MAT4X3PNT(m_eye, hv2model, hv_eye); printf("Eye_pos: %.6f, %.6f, %.6f\n", V3ARGS(m_eye)); /* * Find the view size in model coordinates and print that as well. * Important: Don't use %g format, it may round to nearest integer! */ m_viewsize = hv_viewsize/hv2model[15]; printf("Size: %.6f\n", m_viewsize); }
/* * F _ H I D E L I N E */ int f_hideline(ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { FILE *plotfp; char visible; int i, numobjs; char *objname[MAXOBJECTS], title[1]; fastf_t len, u, step; float ratio; vect_t last_move; struct rt_i *rtip; struct resource resource; struct application a; vect_t temp; vect_t last, dir; register struct bn_vlist *vp; CHECK_DBI_NULL; if (argc < 2 || 4 < argc) { struct bu_vls vls; bu_vls_init(&vls); bu_vls_printf(&vls, "help H"); Tcl_Eval(interp, bu_vls_addr(&vls)); bu_vls_free(&vls); return TCL_ERROR; } if ((plotfp = fopen(argv[1], "w")) == NULL) { Tcl_AppendResult(interp, "f_hideline: unable to open \"", argv[1], "\" for writing.\n", (char *)NULL); return TCL_ERROR; } pl_space(plotfp, (int)GED_MIN, (int)GED_MIN, (int)GED_MAX, (int)GED_MAX); /* Build list of objects being viewed */ numobjs = 0; FOR_ALL_SOLIDS(sp) { for (i = 0; i < numobjs; i++) { if ( objname[i] == FIRST_SOLID(sp)->d_namep ) break; } if (i == numobjs) objname[numobjs++] = FIRST_SOLID(sp)->d_namep; } Tcl_AppendResult(interp, "Generating hidden-line drawing of the following regions:\n", (char *)NULL); for (i = 0; i < numobjs; i++) Tcl_AppendResult(interp, "\t", objname[i], "\n", (char *)NULL); /* Initialization for librt */ if ((rtip = rt_dirbuild(dbip->dbi_filename, title, 0)) == RTI_NULL) { Tcl_AppendResult(interp, "f_hideline: unable to open model file \"", dbip->dbi_filename, "\"\n", (char *)NULL); return TCL_ERROR; } a.a_hit = hit_headon; a.a_miss = hit_tangent; a.a_overlap = hit_overlap; a.a_rt_i = rtip; a.a_resource = &resource; a.a_level = 0; a.a_onehit = 1; a.a_diverge = 0; a.a_rbeam = 0; if (argc > 2) { sscanf(argv[2], "%f", &step); step = view_state->vs_Viewscale/step; sscanf(argv[3], "%f", &epsilon); epsilon *= view_state->vs_Viewscale/100; } else { step = view_state->vs_Viewscale/256; epsilon = 0.1*view_state->vs_Viewscale; } for (i = 0; i < numobjs; i++) if (rt_gettree(rtip, objname[i]) == -1) Tcl_AppendResult(interp, "f_hideline: rt_gettree failed on \"", objname[i], "\"\n", (char *)NULL); /* Crawl along the vectors raytracing as we go */ VSET(temp, 0.0, 0.0, -1.0); /* looking at model */ MAT4X3VEC(a.a_ray.r_dir, view_state->vs_view2model, temp); VUNITIZE(a.a_ray.r_dir); FOR_ALL_SOLIDS(sp) { ratio = sp->s_size / VIEWSIZE; /* ignore if small or big */ if (ratio >= dmp->dmr_bound || ratio < 0.001) continue; Tcl_AppendResult(interp, "Primitive\n", (char *)NULL); for ( BU_LIST_FOR( vp, bn_vlist, &(sp->s_vlist) ) ) { register int i; register int nused = vp->nused; register int *cmd = vp->cmd; register point_t *pt = vp->pt; for ( i = 0; i < nused; i++, cmd++, pt++ ) { Tcl_AppendResult(interp, "\tVector\n", (char *)NULL); switch ( *cmd ) { case BN_VLIST_POLY_START: case BN_VLIST_POLY_VERTNORM: break; case BN_VLIST_POLY_MOVE: case BN_VLIST_LINE_MOVE: /* move */ VMOVE(last, *pt); MOVE(last); break; case BN_VLIST_POLY_DRAW: case BN_VLIST_POLY_END: case BN_VLIST_LINE_DRAW: /* setup direction && length */ VSUB2(dir, *pt, last); len = MAGNITUDE(dir); VUNITIZE(dir); visible = FALSE; { struct bu_vls tmp_vls; bu_vls_init(&tmp_vls); bu_vls_printf(&tmp_vls, "\t\tDraw 0 -> %g, step %g\n", len, step); Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL); bu_vls_free(&tmp_vls); } for (u = 0; u <= len; u += step) { VJOIN1(aim_point, last, u, dir); MAT4X3PNT(temp, view_state->vs_model2view, aim_point); temp[Z] = 100; /* parallel project */ MAT4X3PNT(a.a_ray.r_pt, view_state->vs_view2model, temp); if (rt_shootray(&a)) { if (!visible) { visible = TRUE; MOVE(aim_point); } } else { if (visible) { visible = FALSE; DRAW(aim_point); } } } if (visible) DRAW(aim_point); VMOVE(last, *pt); /* new last vertex */ } } } } fclose(plotfp); return TCL_OK; }
int main (int argc, char **argv) { int val; fastf_t time, yaw1, pitch1, roll1, yaw2, pitch2, roll2; vect_t cen1, cen2, cen_ans, ang_ans, rad_ang_ans, rotated; mat_t m_rot1, m_rot2, m_ans; int one_time, read_cen1, read_cen2, read_rot1, read_rot2; read_cen1 = read_cen2 = read_rot1 = read_rot2 = 1; if (!get_args(argc, argv)) fprintf(stderr, "anim_cascade: Argument error."); switch (output_mode) { case CASCADE_A: if (cmd_fcen) { VMOVE(cen1, fcenter); read_cen1 = 0; } if (cmd_rcen) { VMOVE(cen2, rcenter); read_cen2 = 0; } if (cmd_fypr) { anim_dy_p_r2mat(m_rot1, fypr[0], fypr[1], fypr[2]); read_rot1 = 0; } if (cmd_rypr) { anim_dy_p_r2mat(m_rot2, rypr[0], rypr[1], rypr[2]); read_rot2 = 0; } break; case CASCADE_R: if (cmd_fcen) { VMOVE(cen1, fcenter); read_cen1 = 0; } if (cmd_acen) { VMOVE(cen2, acenter); read_cen2 = 0; } if (cmd_fypr) { anim_dy_p_r2mat(m_rot1, fypr[0], fypr[1], fypr[2]); read_rot1 = 0; } if (cmd_aypr) { anim_dy_p_r2mat(m_rot2, aypr[0], aypr[1], aypr[2]); read_rot2 = 0; } break; case CASCADE_F: if (cmd_acen) { VMOVE(cen1, acenter); read_cen1 = 0; } if (cmd_rcen) { VMOVE(cen2, rcenter); read_cen2 = 0; } if (cmd_aypr) { anim_dy_p_r2mat(m_rot1, aypr[0], aypr[1], aypr[2]); read_rot1 = 0; } if (cmd_rypr) { anim_dy_p_r2mat(m_rot2, rypr[0], rypr[1], rypr[2]); read_rot2 = 0; } break; default: break; } one_time = (!(read_cen1||read_cen2||read_rot1||read_rot2)); read_time = one_time ? 0 : print_time; time = 0.0; val = 3; while (1) { if (read_time) { val=scanf("%lf", &time); if (val < 1) break; } if (read_cen1) val =scanf("%lf %lf %lf", cen1, cen1+1, cen1+2); if (read_rot1) { val=scanf("%lf %lf %lf", &yaw1, &pitch1, &roll1); anim_dy_p_r2mat(m_rot1, yaw1, pitch1, roll1); } if (read_cen2) { val=scanf("%lf %lf %lf", cen2, cen2+1, cen2+2); } if (read_rot2) { val=scanf("%lf %lf %lf", &yaw2, &pitch2, &roll2); anim_dy_p_r2mat(m_rot2, yaw2, pitch2, roll2); } if (val<3) break; if (output_mode==CASCADE_R) { anim_tran(m_rot1); VSUB2(rotated, cen2, cen1); MAT4X3PNT(cen_ans, m_rot1, rotated); bn_mat_mul(m_ans, m_rot1, m_rot2); } else if (output_mode==CASCADE_F) { anim_tran(m_rot2); bn_mat_mul(m_ans, m_rot1, m_rot2); MAT4X3PNT(rotated, m_ans, cen2); VSUB2(cen_ans, cen1, rotated); } else { MAT4X3PNT(rotated, m_rot1, cen2); VADD2(cen_ans, rotated, cen1); bn_mat_mul(m_ans, m_rot1, m_rot2); } anim_mat2ypr(rad_ang_ans, m_ans); VSCALE(ang_ans, rad_ang_ans, RTOD); if (print_time) { printf("%g", time); } printf("\t%.12g\t%.12g\t%.12g", cen_ans[0], cen_ans[1], cen_ans[2]); printf("\t%.12g\t%.12g\t%.12g", ang_ans[0], ang_ans[1], ang_ans[2]); printf("\n"); if (one_time) break; } return( 0 ); }
int common_dm(int argc, const char *argv[]) { int status; struct bu_vls vls = BU_VLS_INIT_ZERO; if (dbip == DBI_NULL) return TCL_OK; if (BU_STR_EQUAL(argv[0], "idle")) { /* redraw after scaling */ if (gedp && gedp->ged_gvp && gedp->ged_gvp->gv_adaptive_plot && gedp->ged_gvp->gv_redraw_on_zoom && (am_mode == AMM_SCALE || am_mode == AMM_CON_SCALE_X || am_mode == AMM_CON_SCALE_Y || am_mode == AMM_CON_SCALE_Z)) { if (redraw_visible_objects() == TCL_ERROR) { return TCL_ERROR; } } am_mode = AMM_IDLE; scroll_active = 0; if (rubber_band->rb_active) { rubber_band->rb_active = 0; if (mged_variables->mv_mouse_behavior == 'p') rb_set_dirty_flag(); else if (mged_variables->mv_mouse_behavior == 'r') rt_rect_area(); else if (mged_variables->mv_mouse_behavior == 'z') zoom_rect_area(); } return TCL_OK; } if (BU_STR_EQUAL(argv[0], "m")) { int x; int y; int old_orig_gui; int stolen = 0; fastf_t fx, fy; if (argc < 3) { Tcl_AppendResult(INTERP, "dm m: need more parameters\n", "dm m xpos ypos\n", (char *)NULL); return TCL_ERROR; } old_orig_gui = mged_variables->mv_orig_gui; fx = dm_Xx2Normal(dmp, atoi(argv[1])); fy = dm_Xy2Normal(dmp, atoi(argv[2]), 0); x = fx * GED_MAX; y = fy * GED_MAX; if (mged_variables->mv_faceplate && mged_variables->mv_orig_gui) { #define MENUXLIM (-1250) if (x >= MENUXLIM && scroll_select(x, y, 0)) { stolen = 1; goto end; } if (x < MENUXLIM && mmenu_select(y, 0)) { stolen = 1; goto end; } } mged_variables->mv_orig_gui = 0; fy = dm_Xy2Normal(dmp, atoi(argv[2]), 1); y = fy * GED_MAX; end: if (mged_variables->mv_mouse_behavior == 'q' && !stolen) { point_t view_pt; point_t model_pt; if (grid_state->gr_snap) snap_to_grid(&fx, &fy); if (mged_variables->mv_perspective_mode) VSET(view_pt, fx, fy, 0.0); else VSET(view_pt, fx, fy, 1.0); MAT4X3PNT(model_pt, view_state->vs_gvp->gv_view2model, view_pt); VSCALE(model_pt, model_pt, base2local); if (dmp->dm_zclip) bu_vls_printf(&vls, "qray_nirt %lf %lf %lf", model_pt[X], model_pt[Y], model_pt[Z]); else bu_vls_printf(&vls, "qray_nirt -b %lf %lf %lf", model_pt[X], model_pt[Y], model_pt[Z]); } else if ((mged_variables->mv_mouse_behavior == 'p' || mged_variables->mv_mouse_behavior == 'r' || mged_variables->mv_mouse_behavior == 'z') && !stolen) { if (grid_state->gr_snap) snap_to_grid(&fx, &fy); rubber_band->rb_active = 1; rubber_band->rb_x = fx; rubber_band->rb_y = fy; rubber_band->rb_width = 0.0; rubber_band->rb_height = 0.0; rect_view2image(); rb_set_dirty_flag(); } else if (mged_variables->mv_mouse_behavior == 's' && !stolen) { #if 0 if (grid_state->gr_snap) { snap_to_grid(&fx, &fy); x = fx * GED_MAX; y = fy * GED_MAX; } #endif bu_vls_printf(&vls, "mouse_solid_edit_select %d %d", x, y); } else if (mged_variables->mv_mouse_behavior == 'm' && !stolen) { #if 0 if (grid_state->gr_snap) { snap_to_grid(&fx, &fy); x = fx * GED_MAX; y = fy * GED_MAX; } #endif bu_vls_printf(&vls, "mouse_matrix_edit_select %d %d", x, y); } else if (mged_variables->mv_mouse_behavior == 'c' && !stolen) { #if 0 if (grid_state->gr_snap) { snap_to_grid(&fx, &fy); x = fx * GED_MAX; y = fy * GED_MAX; } #endif bu_vls_printf(&vls, "mouse_comb_edit_select %d %d", x, y); } else if (mged_variables->mv_mouse_behavior == 'o' && !stolen) { #if 0 if (grid_state->gr_snap) { snap_to_grid(&fx, &fy); x = fx * GED_MAX; y = fy * GED_MAX; } #endif bu_vls_printf(&vls, "mouse_rt_obj_select %d %d", x, y); } else if (adc_state->adc_draw && mged_variables->mv_transform == 'a' && !stolen) { point_t model_pt; point_t view_pt; if (grid_state->gr_snap) snap_to_grid(&fx, &fy); VSET(view_pt, fx, fy, 1.0); MAT4X3PNT(model_pt, view_state->vs_gvp->gv_view2model, view_pt); VSCALE(model_pt, model_pt, base2local); bu_vls_printf(&vls, "adc xyz %lf %lf %lf\n", model_pt[X], model_pt[Y], model_pt[Z]); } else if (grid_state->gr_snap && !stolen && SEDIT_TRAN && mged_variables->mv_transform == 'e') { point_t view_pt; point_t model_pt; snap_to_grid(&fx, &fy); MAT4X3PNT(view_pt, view_state->vs_gvp->gv_model2view, curr_e_axes_pos); view_pt[X] = fx; view_pt[Y] = fy; MAT4X3PNT(model_pt, view_state->vs_gvp->gv_view2model, view_pt); VSCALE(model_pt, model_pt, base2local); bu_vls_printf(&vls, "p %lf %lf %lf", model_pt[X], model_pt[Y], model_pt[Z]); } else if (grid_state->gr_snap && !stolen && OEDIT_TRAN && mged_variables->mv_transform == 'e') { point_t view_pt; point_t model_pt; snap_to_grid(&fx, &fy); MAT4X3PNT(view_pt, view_state->vs_gvp->gv_model2view, curr_e_axes_pos); view_pt[X] = fx; view_pt[Y] = fy; MAT4X3PNT(model_pt, view_state->vs_gvp->gv_view2model, view_pt); VSCALE(model_pt, model_pt, base2local); bu_vls_printf(&vls, "translate %lf %lf %lf", model_pt[X], model_pt[Y], model_pt[Z]); } else if (grid_state->gr_snap && !stolen && STATE != ST_S_PICK && STATE != ST_O_PICK && STATE != ST_O_PATH && !SEDIT_PICK && !EDIT_SCALE) { point_t view_pt; point_t model_pt; point_t vcenter; snap_to_grid(&fx, &fy); MAT_DELTAS_GET_NEG(vcenter, view_state->vs_gvp->gv_center); MAT4X3PNT(view_pt, view_state->vs_gvp->gv_model2view, vcenter); view_pt[X] = fx; view_pt[Y] = fy; MAT4X3PNT(model_pt, view_state->vs_gvp->gv_view2model, view_pt); VSCALE(model_pt, model_pt, base2local); bu_vls_printf(&vls, "center %lf %lf %lf", model_pt[X], model_pt[Y], model_pt[Z]); } else bu_vls_printf(&vls, "M 1 %d %d\n", x, y); status = Tcl_Eval(INTERP, bu_vls_addr(&vls)); mged_variables->mv_orig_gui = old_orig_gui; bu_vls_free(&vls); return status; } if (BU_STR_EQUAL(argv[0], "am")) { if (argc < 4) { Tcl_AppendResult(INTERP, "dm am: need more parameters\n", "dm am <r|t|s> xpos ypos\n", (char *)NULL); return TCL_ERROR; } dml_omx = atoi(argv[2]); dml_omy = atoi(argv[3]); switch (*argv[1]) { case 'r': am_mode = AMM_ROT; break; case 't': am_mode = AMM_TRAN; if (grid_state->gr_snap) { int save_edflag; if ((STATE == ST_S_EDIT || STATE == ST_O_EDIT) && mged_variables->mv_transform == 'e') { if (STATE == ST_S_EDIT) { save_edflag = es_edflag; if (!SEDIT_TRAN) es_edflag = STRANS; } else { save_edflag = edobj; edobj = BE_O_XY; } snap_keypoint_to_grid(); if (STATE == ST_S_EDIT) es_edflag = save_edflag; else edobj = save_edflag; } else snap_view_center_to_grid(); } break; case 's': if (STATE == ST_S_EDIT && mged_variables->mv_transform == 'e' && ZERO(acc_sc_sol)) acc_sc_sol = 1.0; else if (STATE == ST_O_EDIT && mged_variables->mv_transform == 'e') { edit_absolute_scale = acc_sc_obj - 1.0; if (edit_absolute_scale > 0.0) edit_absolute_scale /= 3.0; } am_mode = AMM_SCALE; break; default: Tcl_AppendResult(INTERP, "dm am: need more parameters\n", "dm am <r|t|s> xpos ypos\n", (char *)NULL); return TCL_ERROR; } return TCL_OK; } if (BU_STR_EQUAL(argv[0], "adc")) { fastf_t fx, fy; fastf_t td; /* tick distance */ if (argc < 4) { Tcl_AppendResult(INTERP, "dm adc: need more parameters\n", "dm adc 1|2|t|d xpos ypos\n", (char *)NULL); return TCL_ERROR; } dml_omx = atoi(argv[2]); dml_omy = atoi(argv[3]); switch (*argv[1]) { case '1': fx = dm_Xx2Normal(dmp, dml_omx) * GED_MAX - adc_state->adc_dv_x; fy = dm_Xy2Normal(dmp, dml_omy, 1) * GED_MAX - adc_state->adc_dv_y; bu_vls_printf(&vls, "adc a1 %lf\n", RAD2DEG*atan2(fy, fx)); Tcl_Eval(INTERP, bu_vls_addr(&vls)); bu_vls_free(&vls); am_mode = AMM_ADC_ANG1; break; case '2': fx = dm_Xx2Normal(dmp, dml_omx) * GED_MAX - adc_state->adc_dv_x; fy = dm_Xy2Normal(dmp, dml_omy, 1) * GED_MAX - adc_state->adc_dv_y; bu_vls_printf(&vls, "adc a2 %lf\n", RAD2DEG*atan2(fy, fx)); Tcl_Eval(INTERP, bu_vls_addr(&vls)); bu_vls_free(&vls); am_mode = AMM_ADC_ANG2; break; case 't': { point_t model_pt; point_t view_pt; VSET(view_pt, dm_Xx2Normal(dmp, dml_omx), dm_Xy2Normal(dmp, dml_omy, 1), 0.0); if (grid_state->gr_snap) snap_to_grid(&view_pt[X], &view_pt[Y]); MAT4X3PNT(model_pt, view_state->vs_gvp->gv_view2model, view_pt); VSCALE(model_pt, model_pt, base2local); bu_vls_printf(&vls, "adc xyz %lf %lf %lf\n", model_pt[X], model_pt[Y], model_pt[Z]); Tcl_Eval(INTERP, bu_vls_addr(&vls)); bu_vls_free(&vls); am_mode = AMM_ADC_TRAN; } break; case 'd': fx = (dm_Xx2Normal(dmp, dml_omx) * GED_MAX - adc_state->adc_dv_x) * view_state->vs_gvp->gv_scale * base2local * INV_GED; fy = (dm_Xy2Normal(dmp, dml_omy, 1) * GED_MAX - adc_state->adc_dv_y) * view_state->vs_gvp->gv_scale * base2local * INV_GED; td = sqrt(fx * fx + fy * fy); bu_vls_printf(&vls, "adc dst %lf\n", td); Tcl_Eval(INTERP, bu_vls_addr(&vls)); bu_vls_free(&vls); am_mode = AMM_ADC_DIST; break; default: Tcl_AppendResult(INTERP, "dm adc: unrecognized parameter - ", argv[1], "\ndm adc 1|2|t|d xpos ypos\n", (char *)NULL); return TCL_ERROR; } return TCL_OK; } if (BU_STR_EQUAL(argv[0], "con")) { if (argc < 5) { Tcl_AppendResult(INTERP, "dm con: need more parameters\n", "dm con r|t|s x|y|z xpos ypos\n", "dm con a x|y|1|2|d xpos ypos\n", (char *)NULL); return TCL_ERROR; } dml_omx = atoi(argv[3]); dml_omy = atoi(argv[4]); switch (*argv[1]) { case 'a': switch (*argv[2]) { case 'x': am_mode = AMM_CON_XADC; break; case 'y': am_mode = AMM_CON_YADC; break; case '1': am_mode = AMM_CON_ANG1; break; case '2': am_mode = AMM_CON_ANG2; break; case 'd': am_mode = AMM_CON_DIST; break; default: Tcl_AppendResult(INTERP, "dm con: unrecognized parameter - ", argv[2], "\ndm con a x|y|1|2|d xpos ypos\n", (char *)NULL); } break; case 'r': switch (*argv[2]) { case 'x': am_mode = AMM_CON_ROT_X; break; case 'y': am_mode = AMM_CON_ROT_Y; break; case 'z': am_mode = AMM_CON_ROT_Z; break; default: Tcl_AppendResult(INTERP, "dm con: unrecognized parameter - ", argv[2], "\ndm con r|t|s x|y|z xpos ypos\n", (char *)NULL); return TCL_ERROR; } break; case 't': switch (*argv[2]) { case 'x': am_mode = AMM_CON_TRAN_X; break; case 'y': am_mode = AMM_CON_TRAN_Y; break; case 'z': am_mode = AMM_CON_TRAN_Z; break; default: Tcl_AppendResult(INTERP, "dm con: unrecognized parameter - ", argv[2], "\ndm con r|t|s x|y|z xpos ypos\n", (char *)NULL); return TCL_ERROR; } break; case 's': switch (*argv[2]) { case 'x': if (STATE == ST_S_EDIT && mged_variables->mv_transform == 'e' && ZERO(acc_sc_sol)) acc_sc_sol = 1.0; else if (STATE == ST_O_EDIT && mged_variables->mv_transform == 'e') { edit_absolute_scale = acc_sc[0] - 1.0; if (edit_absolute_scale > 0.0) edit_absolute_scale /= 3.0; } am_mode = AMM_CON_SCALE_X; break; case 'y': if (STATE == ST_S_EDIT && mged_variables->mv_transform == 'e' && ZERO(acc_sc_sol)) acc_sc_sol = 1.0; else if (STATE == ST_O_EDIT && mged_variables->mv_transform == 'e') { edit_absolute_scale = acc_sc[1] - 1.0; if (edit_absolute_scale > 0.0) edit_absolute_scale /= 3.0; } am_mode = AMM_CON_SCALE_Y; break; case 'z': if (STATE == ST_S_EDIT && mged_variables->mv_transform == 'e' && ZERO(acc_sc_sol)) acc_sc_sol = 1.0; else if (STATE == ST_O_EDIT && mged_variables->mv_transform == 'e') { edit_absolute_scale = acc_sc[2] - 1.0; if (edit_absolute_scale > 0.0) edit_absolute_scale /= 3.0; } am_mode = AMM_CON_SCALE_Z; break; default: Tcl_AppendResult(INTERP, "dm con: unrecognized parameter - ", argv[2], "\ndm con r|t|s x|y|z xpos ypos\n", (char *)NULL); return TCL_ERROR; } break; default: Tcl_AppendResult(INTERP, "dm con: unrecognized parameter - ", argv[1], "\ndm con r|t|s x|y|z xpos ypos\n", (char *)NULL); return TCL_ERROR; } return TCL_OK; } if (BU_STR_EQUAL(argv[0], "size")) { int width, height; /* get the window size */ if (argc == 1) { bu_vls_printf(&vls, "%d %d", dmp->dm_width, dmp->dm_height); Tcl_AppendResult(INTERP, bu_vls_addr(&vls), (char *)NULL); bu_vls_free(&vls); return TCL_OK; } /* set the window size */ if (argc == 3) { width = atoi(argv[1]); height = atoi(argv[2]); dmp->dm_width = width; dmp->dm_height = height; #if defined(DM_X) || defined(DM_TK) || defined(DM_OGL) || defined(DM_WGL) # if 0 Tk_ResizeWindow(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin, width, height); # else #if defined(HAVE_TK) Tk_GeometryRequest(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin, width, height); #endif # endif #endif return TCL_OK; } Tcl_AppendResult(INTERP, "Usage: dm size [width height]\n", (char *)NULL); return TCL_ERROR; } #if defined(DM_X) || defined(DM_TK) || defined(DM_OGL) || defined(DM_WGL) if (BU_STR_EQUAL(argv[0], "getx")) { if (argc == 1) { struct bu_vls tmp_vls = BU_VLS_INIT_ZERO; /* Bare set command, print out current settings */ bu_vls_struct_print2(&tmp_vls, "dm internal X variables", dm_xvars_vparse, (const char *)dmp->dm_vars.pub_vars); Tcl_AppendResult(INTERP, bu_vls_addr(&tmp_vls), (char *)NULL); bu_vls_free(&tmp_vls); } else if (argc == 2) { bu_vls_struct_item_named(&vls, dm_xvars_vparse, argv[1], (const char *)dmp->dm_vars.pub_vars, COMMA); Tcl_AppendResult(INTERP, bu_vls_addr(&vls), (char *)NULL); bu_vls_free(&vls); } return TCL_OK; } #endif if (BU_STR_EQUAL(argv[0], "bg")) { int r, g, b; if (argc != 1 && argc != 4) { bu_vls_printf(&vls, "Usage: dm bg [r g b]"); Tcl_AppendResult(INTERP, bu_vls_addr(&vls), (char *)NULL); bu_vls_free(&vls); return TCL_ERROR; } /* return background color of current display manager */ if (argc == 1) { bu_vls_printf(&vls, "%d %d %d", dmp->dm_bg[0], dmp->dm_bg[1], dmp->dm_bg[2]); Tcl_AppendResult(INTERP, bu_vls_addr(&vls), (char *)NULL); bu_vls_free(&vls); return TCL_OK; } if (sscanf(argv[1], "%d", &r) != 1 || sscanf(argv[2], "%d", &g) != 1 || sscanf(argv[3], "%d", &b) != 1) { bu_vls_printf(&vls, "Usage: dm bg r g b"); Tcl_AppendResult(INTERP, bu_vls_addr(&vls), (char *)NULL); bu_vls_free(&vls); return TCL_ERROR; } dirty = 1; return DM_SET_BGCOLOR(dmp, r, g, b); } Tcl_AppendResult(INTERP, "dm: bad command - ", argv[0], "\n", (char *)NULL); return TCL_ERROR; }
int scloud_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp) { register struct scloud_specific *scloud_sp = (struct scloud_specific *)dp; point_t in_pt; /* point where ray enters scloud solid */ point_t out_pt; /* point where ray leaves scloud solid */ point_t pt; vect_t v_cloud;/* vector representing ray/solid intersection */ double thickness; /* magnitude of v_cloud (distance through solid) */ int steps; /* # of samples along ray/solid intersection */ double step_delta;/* distance between sample points, texture space */ int i; double val; double trans; point_t incident_light = VINIT_ZERO; double delta_dpmm; double density; struct shadework sub_sw; struct light_specific *lp; RT_CHECK_PT(pp); RT_AP_CHECK(ap); RT_CK_REGION(pp->pt_regionp); /* compute the ray/solid in and out points, * and transform them into "shader space" coordinates */ VJOIN1(pt, ap->a_ray.r_pt, pp->pt_inhit->hit_dist, ap->a_ray.r_dir); MAT4X3PNT(in_pt, scloud_sp->mtos, pt); VJOIN1(pt, ap->a_ray.r_pt, pp->pt_outhit->hit_dist, ap->a_ray.r_dir); MAT4X3PNT(out_pt, scloud_sp->mtos, pt); /* get ray/solid intersection vector (in noise space) * and compute thickness of solid (in noise space) along ray path */ VSUB2(v_cloud, out_pt, in_pt); thickness = MAGNITUDE(v_cloud); /* The noise field used by the bn_noise_turb and bn_noise_fbm routines * has a maximum frequency of about 1 cycle per integer step in * noise space. Each octave increases this frequency by the * "lacunarity" factor. To sample this space adequately we need * * 4 samples per integer step for the first octave, * lacunarity * 4 samples/step for the second octave, * lacunarity^2 * 4 samples/step for the third octave, * lacunarity^3 * 4 samples/step for the forth octave, * * so for a computation with 4 octaves we need something on the * order of lacunarity^3 * 4 samples per integer step in noise space. */ steps = pow(scloud_sp->lacunarity, scloud_sp->octaves-1) * 4; step_delta = thickness / (double)steps; if (rdebug&RDEBUG_SHADE) bu_log("steps=%d delta=%g thickness=%g\n", steps, step_delta, thickness); VUNITIZE(v_cloud); VMOVE(pt, in_pt); trans = 1.0; delta_dpmm = scloud_sp->max_d_p_mm - scloud_sp->min_d_p_mm; sub_sw = *swp; /* struct copy */ sub_sw.sw_inputs = MFI_HIT; for (i=0; i < steps; i++) { /* compute the next point in the cloud space */ VJOIN1(pt, in_pt, i*step_delta, v_cloud); /* get turbulence value (0 .. 1) */ val = bn_noise_turb(pt, scloud_sp->h_val, scloud_sp->lacunarity, scloud_sp->octaves); density = scloud_sp->min_d_p_mm + val * delta_dpmm; val = exp(- density * step_delta); trans *= val; if (swp->sw_xmitonly) continue; /* need to set the hit in our fake shadework structure */ MAT4X3PNT(sub_sw.sw_hit.hit_point, scloud_sp->stom, pt); sub_sw.sw_transmit = trans; sub_sw.sw_inputs = MFI_HIT; light_obs(ap, &sub_sw, swp->sw_inputs); /* now we know how much light has arrived from each * light source to this point */ for (i=ap->a_rt_i->rti_nlights-1; i >= 0; i--) { lp = (struct light_specific *)swp->sw_visible[i]; if (lp == LIGHT_NULL) continue; /* compute how much light has arrived at * this location */ incident_light[0] += sub_sw.sw_intensity[3*i+0] * lp->lt_color[0] * sub_sw.sw_lightfract[i]; incident_light[1] += sub_sw.sw_intensity[3*i+1] * lp->lt_color[1] * sub_sw.sw_lightfract[i]; incident_light[2] += sub_sw.sw_intensity[3*i+2] * lp->lt_color[2] * sub_sw.sw_lightfract[i]; } VSCALE(incident_light, incident_light, trans); } /* scloud is basically a white object with partial transparency */ swp->sw_transmit = trans; if (swp->sw_xmitonly) return 1; /* * At the point of maximum opacity, check light visibility * for light color and cloud shadowing. * OOPS: Don't use an interior point, or light_visibility() * will see an attenuated light source. */ swp->sw_hit.hit_dist = pp->pt_inhit->hit_dist; VJOIN1(swp->sw_hit.hit_point, ap->a_ray.r_pt, swp->sw_hit.hit_dist, ap->a_ray.r_dir); VREVERSE(swp->sw_hit.hit_normal, ap->a_ray.r_dir); swp->sw_inputs |= MFI_HIT | MFI_NORMAL; light_obs(ap, swp, swp->sw_inputs); VSETALL(incident_light, 0); for (i=ap->a_rt_i->rti_nlights-1; i>=0; i--) { struct light_specific *lp2; if ((lp2 = (struct light_specific *)swp->sw_visible[i]) == LIGHT_NULL) continue; /* XXX don't have a macro for this */ incident_light[0] += swp->sw_intensity[3*i+0] * lp2->lt_color[0]; incident_light[1] += swp->sw_intensity[3*i+1] * lp2->lt_color[1]; incident_light[2] += swp->sw_intensity[3*i+2] * lp2->lt_color[2]; } VELMUL(swp->sw_color, swp->sw_color, incident_light); if (rdebug&RDEBUG_SHADE) { pr_shadework("scloud: after light vis, before rr_render", swp); } if (swp->sw_reflect > 0 || swp->sw_transmit > 0) (void)rr_render(ap, pp, swp); return 1; }
/* * T P _ 3 S Y M B O L */ void tp_3symbol(FILE *fp, char *string, fastf_t *origin, fastf_t *rot, double scale) /* string of chars to be plotted */ /* lower left corner of 1st char */ /* Transform matrix (WARNING: may xlate) */ /* scale factor to change 1x1 char sz */ { register unsigned char *cp; double offset; /* offset of char from given x, y */ int ysign; /* sign of y motion, either +1 or -1 */ vect_t temp; vect_t loc; mat_t xlate_to_origin; mat_t mat; if ( string == NULL || *string == '\0' ) return; /* done before begun! */ /* * The point "origin" will be the center of the axis rotation. * The text is located in a local coordinate system with the * lower left corner of the first character at (0, 0, 0), with * the text proceeding onward towards +X. * We need to rotate the text around its local (0, 0, 0), * and then translate to the user's designated "origin". * If the user provided translation or * scaling in his matrix, it will *also* be applied. */ MAT_IDN( xlate_to_origin ); MAT_DELTAS_VEC( xlate_to_origin, origin ); bn_mat_mul( mat, xlate_to_origin, rot ); /* Check to see if initialization is needed */ if ( tp_cindex[040] == 0 ) tp_setup(); /* Draw each character in the input string */ offset = 0; for ( cp = (unsigned char *)string; *cp; cp++, offset += scale ) { register int *p; /* pointer to stroke table */ register int stroke; VSET( temp, offset, 0, 0 ); MAT4X3PNT( loc, mat, temp ); pdv_3move( fp, loc ); for ( p = tp_cindex[*cp]; (stroke= *p) != LAST; p++ ) { int draw; if ( stroke==NEGY ) { ysign = (-1); stroke = *++p; } else ysign = 1; /* Detect & process pen control */ if ( stroke < 0 ) { stroke = -stroke; draw = 0; } else draw = 1; /* stroke co-ordinates in string coord system */ VSET( temp, (stroke/11) * 0.1 * scale + offset, (ysign * (stroke%11)) * 0.1 * scale, 0 ); MAT4X3PNT( loc, mat, temp ); if ( draw ) pdv_3cont( fp, loc ); else pdv_3move( fp, loc ); } } }
/* * R A Y H I T * * Rayhit() is called by rt_shootray() when the ray hits one or more objects. * A per-shotline header record is written, followed by information about * each object hit. * * Note that the GIFT-3 format uses a different convention for the "zero" * distance along the ray. RT has zero at the ray origin (emanation plain), * while GIFT has zero at the screen plain translated so that it contains * the model origin. This difference is compensated for by adding the * 'dcorrection' distance correction factor. * * Also note that the GIFT-3 format requires information about the start * point of the ray in two formats. First, the h, v coordinates of the * grid cell CENTERS (in screen space coordinates) are needed. * Second, the ACTUAL h, v coordinates fired from are needed. * * An optional rtg3.pl UnixPlot file is written, permitting a * color vector display of ray-model intersections. */ int rayhit(struct application *ap, register struct partition *PartHeadp, struct seg *segp) { register struct partition *pp = PartHeadp->pt_forw; int comp_count; /* component count */ fastf_t dfirst, dlast; /* ray distances */ static fastf_t dcorrection = 0; /* RT to GIFT dist corr */ int card_count; /* # comp. on this card */ const char *fmt; /* printf() format string */ struct bu_vls str; char buf[128]; /* temp. sprintf() buffer */ point_t hv; /* GIFT h, v coords, in inches */ point_t hvcen; int prev_id=-1; point_t first_hit; int first; if ( pp == PartHeadp ) return(0); /* nothing was actually hit?? */ if ( ap->a_rt_i->rti_save_overlaps ) rt_rebuild_overlaps( PartHeadp, ap, 1 ); part_compact(ap, PartHeadp, TOL); /* count components in partitions */ comp_count = 0; for ( pp=PartHeadp->pt_forw; pp!=PartHeadp; pp=pp->pt_forw ) { if ( pp->pt_regionp->reg_regionid > 0 ) { prev_id = pp->pt_regionp->reg_regionid; comp_count++; } else if ( prev_id <= 0 ) { /* normally air would be output along with a solid partition, but this will require a '111' partition */ prev_id = pp->pt_regionp->reg_regionid; comp_count++; } else prev_id = pp->pt_regionp->reg_regionid; } pp = PartHeadp->pt_back; if ( pp!=PartHeadp && pp->pt_regionp->reg_regionid <= 0 ) comp_count++; /* a trailing '111' ident */ if ( comp_count == 0 ) return( 0 ); /* Set up variable length string, to buffer this shotline in. * Note that there is one component per card, and that each card * (line) is 80 characters long. Hence the parameters given to * rt-vls-extend(). */ bu_vls_init( &str ); bu_vls_extend( &str, 80 * (comp_count+1) ); /* * Find the H, V coordinates of the grid cell center. * RT uses the lower left corner of each cell. */ { point_t center; fastf_t dx; fastf_t dy; dx = ap->a_x + 0.5; dy = ap->a_y + 0.5; VJOIN2( center, viewbase_model, dx, dx_model, dy, dy_model ); MAT4X3PNT( hvcen, model2hv, center ); } /* * Find exact h, v coordinates of actual ray start by * projecting start point into GIFT h, v coordinates. */ MAT4X3PNT( hv, model2hv, ap->a_ray.r_pt ); /* * In RT, rays are launched from the plane of the screen, * and ray distances are relative to the start point. * In GIFT-3 output files, ray distances are relative to * the (H, V) plane translated so that it contains the origin. * A distance correction is required to convert between the two. * Since this really should be computed only once, not every time, * the trip_count flag was added. */ { static int trip_count; vect_t tmp; vect_t viewZdir; if ( trip_count == 0) { VSET( tmp, 0, 0, -1 ); /* viewing direction */ MAT4X3VEC( viewZdir, view2model, tmp ); VUNITIZE( viewZdir ); /* dcorrection will typically be negative */ dcorrection = VDOT( ap->a_ray.r_pt, viewZdir ); trip_count = 1; } } /* This code is for diagnostics. * bu_log("dcorrection=%g\n", dcorrection); */ /* dfirst and dlast have been made negative to account for GIFT looking * in the opposite direction of RT. */ dfirst = -(PartHeadp->pt_forw->pt_inhit->hit_dist + dcorrection); dlast = -(PartHeadp->pt_back->pt_outhit->hit_dist + dcorrection); #if 0 /* This code is to note any occurances of negative distances. */ if ( PartHeadp->pt_forw->pt_inhit->hit_dist < 0) { bu_log("ERROR: dfirst=%g at partition x%x\n", dfirst, PartHeadp->pt_forw ); bu_log("\tdcorrection = %f\n", dcorrection ); bu_log("\tray start point is ( %f %f %f ) in direction ( %f %f %f )\n", V3ARGS( ap->a_ray.r_pt ), V3ARGS( ap->a_ray.r_dir ) ); VJOIN1( PartHeadp->pt_forw->pt_inhit->hit_point, ap->a_ray.r_pt, PartHeadp->pt_forw->pt_inhit->hit_dist, ap->a_ray.r_dir ); VJOIN1( PartHeadp->pt_back->pt_outhit->hit_point, ap->a_ray.r_pt, PartHeadp->pt_forw->pt_outhit->hit_dist, ap->a_ray.r_dir ); rt_pr_partitions(ap->a_rt_i, PartHeadp, "Defective partion:"); } /* End of bug trap. */ #endif /* * Output the ray header. The GIFT statements that * would have generated this are: * 410 write(1, 411) hcen, vcen, h, v, ncomp, dfirst, dlast, a, e * 411 format(2f7.1, 2f9.3, i3, 2f8.2,' A', f6.1,' E', f6.1) */ #define SHOT_FMT "%7.1f%7.1f%9.3f%9.3f%3d%8.2f%8.2f A%6.1f E%6.1f" if ( rt_perspective > 0 ) { bn_ae_vec( &azimuth, &elevation, ap->a_ray.r_dir ); } bu_vls_printf( &str, SHOT_FMT, hvcen[0], hvcen[1], hv[0], hv[1], comp_count, dfirst * MM2IN, dlast * MM2IN, azimuth, elevation ); /* * As an aid to debugging, take advantage of the fact that * there are more than 80 columns on UNIX "cards", and * add debugging information to the end of the line to * allow this shotline to be reproduced offline. * -b gives the shotline x, y coordinates when re-running RTG3, * -p and -d are used with RTSHOT * The easy way to activate this is with the harmless -!1 option * when running RTG3. */ if ( R_DEBUG || bu_debug || RT_G_DEBUG ) { bu_vls_printf( &str, " -b%d,%d -p %26.20e %26.20e %26.20e -d %26.20e %26.20e %26.20e\n", ap->a_x, ap->a_y, V3ARGS(ap->a_ray.r_pt), V3ARGS(ap->a_ray.r_dir) ); } else { bu_vls_putc( &str, '\n' ); } /* loop here to deal with individual components */ card_count = 0; prev_id = -1; first = 1; for ( pp=PartHeadp->pt_forw; pp!=PartHeadp; pp=pp->pt_forw ) { /* * The GIFT statements that would have produced * this output are: * do 632 i=icomp, iend * if (clos(icomp).gt.999.99.or.slos(i).gt.999.9) goto 635 * 632 continue * write(1, 633)(item(i), clos(i), cangi(i), cango(i), * & kspac(i), slos(i), i=icomp, iend) * 633 format(1x, 3(i4, f6.2, 2f5.1, i1, f5.1)) * goto 670 * 635 write(1, 636)(item(i), clos(i), cangi(i), cango(i), * & kspac(i), slos(i), i=icomp, iend) * 636 format(1x, 3(i4, f6.1, 2f5.1, i1, f5.0)) */ fastf_t comp_thickness; /* component line of sight thickness */ fastf_t in_obliq; /* in obliquity angle */ fastf_t out_obliq; /* out obliquity angle */ int region_id; /* solid region's id */ int air_id; /* air id */ fastf_t dot_prod; /* dot product of normal and ray dir */ fastf_t air_thickness; /* air line of sight thickness */ vect_t normal; /* surface normal */ register struct partition *nextpp = pp->pt_forw; region_id = pp->pt_regionp->reg_regionid; if ( region_id <= 0 && prev_id > 0 ) { /* air region output with previous partition */ prev_id = region_id; continue; } comp_thickness = pp->pt_outhit->hit_dist - pp->pt_inhit->hit_dist; /* The below code is meant to catch components with zero or * negative thicknesses. This is not supposed to be possible, * but the condition has been seen. */ #if 0 if ( comp_thickness <= 0 ) { VJOIN1( pp->pt_inhit->hit_point, ap->a_ray.r_pt, pp->pt_inhit->hit_dist, ap->a_ray.r_dir ); VJOIN1( pp->pt_outhit->hit_point, ap->a_ray.r_pt, pp->pt_outhit->hit_dist, ap->a_ray.r_dir ); bu_log("ERROR: comp_thickness=%g for region id = %d at h=%g, v=%g (x=%d, y=%d), partition at x%x\n", comp_thickness, region_id, hv[0], hv[1], ap->a_x, ap->a_y, pp ); rt_pr_partitions(ap->a_rt_i, PartHeadp, "Defective partion:"); bu_log("Send this output to the BRL-CAD Developers ([email protected])\n"); if ( ! (RT_G_DEBUG & DEBUG_ARB8)) { rt_g.debug |= DEBUG_ARB8; rt_shootray(ap); rt_g.debug &= ~DEBUG_ARB8; } } #endif if ( nextpp == PartHeadp ) { if ( region_id <= 0 ) { /* last partition is air, need a 111 'phantom armor' before AND after */ bu_log( "WARNING: adding 'phantom armor' (id=111) with zero thickness before and after air region %s\n", pp->pt_regionp->reg_name ); region_id = 111; air_id = pp->pt_regionp->reg_aircode; air_thickness = comp_thickness; comp_thickness = 0.0; } else { /* Last partition, no air follows, use code 9 */ air_id = 9; air_thickness = 0.0; } } else if ( region_id <= 0 ) { /* air region, need a 111 'phantom armor' */ bu_log( "WARNING: adding 'phantom armor' (id=111) with zero thickness before air region %s\n", pp->pt_regionp->reg_name ); prev_id = region_id; region_id = 111; air_id = pp->pt_regionp->reg_aircode; air_thickness = comp_thickness; comp_thickness = 0.0; } else if ( nextpp->pt_regionp->reg_regionid <= 0 && nextpp->pt_regionp->reg_aircode != 0 ) { /* Next partition is air region */ air_id = nextpp->pt_regionp->reg_aircode; air_thickness = nextpp->pt_outhit->hit_dist - nextpp->pt_inhit->hit_dist; prev_id = air_id; } else { /* 2 solid regions, maybe with gap */ air_id = 0; air_thickness = nextpp->pt_inhit->hit_dist - pp->pt_outhit->hit_dist; if ( air_thickness < 0.0 ) air_thickness = 0.0; if ( !NEAR_ZERO( air_thickness, 0.1 ) ) { air_id = 1; /* air gap */ if ( R_DEBUG & RDEBUG_HITS ) bu_log("air gap added\n"); } else { air_thickness = 0.0; } prev_id = region_id; } /* * Compute the obliquity angles in degrees, ie, * the "declension" angle down off the normal vector. * RT normals always point outwards; * the "inhit" normal points opposite the ray direction, * the "outhit" normal points along the ray direction. * Hence the one sign change. * XXX this should probably be done with atan2() */ if ( first ) { first = 0; VJOIN1( first_hit, ap->a_ray.r_pt, pp->pt_inhit->hit_dist, ap->a_ray.r_dir ); } out: RT_HIT_NORMAL( normal, pp->pt_inhit, pp->pt_inseg->seg_stp, &(ap->a_ray), pp->pt_inflip ); dot_prod = VDOT( ap->a_ray.r_dir, normal ); if ( dot_prod > 1.0 ) dot_prod = 1.0; if ( dot_prod < -1.0 ) dot_prod = (-1.0); in_obliq = acos( -dot_prod ) * bn_radtodeg; RT_HIT_NORMAL( normal, pp->pt_outhit, pp->pt_outseg->seg_stp, &(ap->a_ray), pp->pt_outflip ); dot_prod = VDOT( ap->a_ray.r_dir, normal ); if ( dot_prod > 1.0 ) dot_prod = 1.0; if ( dot_prod < -1.0 ) dot_prod = (-1.0); out_obliq = acos( dot_prod ) * bn_radtodeg; /* Check for exit obliquties greater than 90 degrees. */ #if 0 if ( in_obliq > 90 || in_obliq < 0 ) { bu_log("ERROR: in_obliquity=%g\n", in_obliq); rt_pr_partitions(ap->a_rt_i, PartHeadp, "Defective partion:"); } if ( out_obliq > 90 || out_obliq < 0 ) { bu_log("ERROR: out_obliquity=%g\n", out_obliq); VPRINT(" r_dir", ap->a_ray.r_dir); VPRINT("normal", normal); bu_log("dot=%g, acos(dot)=%g\n", VDOT( ap->a_ray.r_dir, normal ), acos( VDOT( ap->a_ray.r_dir, normal ) ) ); /* Print the defective one */ rt_pr_pt( ap->a_rt_i, pp ); /* Print the whole ray's partition list */ rt_pr_partitions(ap->a_rt_i, PartHeadp, "Defective partion:"); } #endif if ( in_obliq > 90.0 ) in_obliq = 90.0; if ( in_obliq < 0.0 ) in_obliq = 0.0; if ( out_obliq > 90.0 ) out_obliq = 90.0; if ( out_obliq < 0.0 ) out_obliq = 0.0; /* * Handle 3-components per card output format, with * a leading space in front of the first component. */ if ( card_count == 0 ) { bu_vls_strcat( &str, " " ); } comp_thickness *= MM2IN; /* Check thickness fields for format overflow */ if ( comp_thickness > 999.99 || air_thickness*MM2IN > 999.9 ) fmt = "%4d%6.1f%5.1f%5.1f%1d%5.0f"; else fmt = "%4d%6.2f%5.1f%5.1f%1d%5.1f"; #ifdef SPRINTF_NOT_PARALLEL bu_semaphore_acquire( BU_SEM_SYSCALL ); #endif snprintf(buf, 128, fmt, region_id, comp_thickness, in_obliq, out_obliq, air_id, air_thickness*MM2IN ); #ifdef SPRINTF_NOT_PARALLEL bu_semaphore_release( BU_SEM_SYSCALL ); #endif bu_vls_strcat( &str, buf ); card_count++; if ( card_count >= 3 ) { bu_vls_strcat( &str, "\n" ); card_count = 0; } /* A color rtg3.pl UnixPlot file of output commands * is generated. This is processed by plot(1) * plotting filters such as pl-fb or pl-sgi. * Portions of a ray passing through air within the * model are represented in blue, while portions * passing through a solid are assigned green. * This will always be done single CPU, * to prevent output garbling. (See view_init). */ if (R_DEBUG & RDEBUG_RAYPLOT) { vect_t inpt; vect_t outpt; VJOIN1(inpt, ap->a_ray.r_pt, pp->pt_inhit->hit_dist, ap->a_ray.r_dir); VJOIN1(outpt, ap->a_ray.r_pt, pp->pt_outhit->hit_dist, ap->a_ray.r_dir); pl_color(plotfp, 0, 255, 0); /* green */ pdv_3line(plotfp, inpt, outpt); if (air_thickness > 0) { vect_t air_end; VJOIN1(air_end, ap->a_ray.r_pt, pp->pt_outhit->hit_dist + air_thickness, ap->a_ray.r_dir); pl_color(plotfp, 0, 0, 255); /* blue */ pdv_3cont(plotfp, air_end); } } if ( nextpp == PartHeadp && air_id != 9 ) { /* need to output a 111 'phantom armor' at end of shotline */ air_id = 9; air_thickness = 0.0; region_id = 111; comp_thickness = 0.0; goto out; } } /* If partway through building the line, add a newline */ if ( card_count > 0 ) { /* * Note that GIFT zero-fills the unused component slots, * but neither COVART II nor COVART III require it, * so just end the line here. */ bu_vls_strcat( &str, "\n" ); } /* Single-thread through file output. * COVART will accept non-sequential ray data provided the * ray header and its associated data are not separated. CAVEAT: * COVART will not accept headers out of sequence. */ bu_semaphore_acquire( BU_SEM_SYSCALL ); fputs( bu_vls_addr( &str ), outfp ); if ( shot_fp ) { fprintf( shot_fp, "%.5f %.5f %.5f %.5f %.5f %.5f %.5f %.5f %ld %.5f %.5f %.5f\n", azimuth, elevation, V3ARGS( ap->a_ray.r_pt ), V3ARGS( ap->a_ray.r_dir ), line_num, V3ARGS( first_hit) ); line_num += 1 + (comp_count / 3 ); if ( comp_count % 3 ) line_num++; } /* End of single-thread region */ bu_semaphore_release( BU_SEM_SYSCALL ); /* Release vls storage */ bu_vls_free( &str ); return(0); }
/* * Default keypoint in model space is established in "pt". Returns * GED_ERROR if unable to determine a keypoint, otherwise returns * GED_OK. */ int _ged_get_solid_keypoint(struct ged *const gedp, fastf_t *const pt, const struct rt_db_internal *const ip, const fastf_t *const mat) { point_t mpt; RT_CK_DB_INTERNAL(ip); switch (ip->idb_type) { case ID_CLINE: { struct rt_cline_internal *cli = (struct rt_cline_internal *)ip->idb_ptr; RT_CLINE_CK_MAGIC(cli); VMOVE(mpt, cli->v); break; } case ID_PARTICLE: { struct rt_part_internal *part = (struct rt_part_internal *)ip->idb_ptr; RT_PART_CK_MAGIC(part); VMOVE(mpt, part->part_V); break; } case ID_PIPE: { struct rt_pipe_internal *pipeip; struct wdb_pipept *pipe_seg; pipeip = (struct rt_pipe_internal *)ip->idb_ptr; RT_PIPE_CK_MAGIC(pipeip); pipe_seg = BU_LIST_FIRST(wdb_pipept, &pipeip->pipe_segs_head); VMOVE(mpt, pipe_seg->pp_coord); break; } case ID_METABALL: { struct rt_metaball_internal *metaball = (struct rt_metaball_internal *)ip->idb_ptr; struct wdb_metaballpt *metaballpt; RT_METABALL_CK_MAGIC(metaball); VSETALL(mpt, 0.0); metaballpt = BU_LIST_FIRST(wdb_metaballpt, &metaball->metaball_ctrl_head); VMOVE(mpt, metaballpt->coord); break; } case ID_ARBN: { struct rt_arbn_internal *arbn = (struct rt_arbn_internal *)ip->idb_ptr; size_t i, j, k; int good_vert = 0; RT_ARBN_CK_MAGIC(arbn); for (i = 0; i < arbn->neqn; i++) { for (j = i + 1; j < arbn->neqn; j++) { for (k = j + 1; k < arbn->neqn; k++) { if (!bn_mkpoint_3planes(mpt, arbn->eqn[i], arbn->eqn[j], arbn->eqn[k])) { size_t l; good_vert = 1; for (l = 0; l < arbn->neqn; l++) { if (l == i || l == j || l == k) continue; if (DIST_PT_PLANE(mpt, arbn->eqn[l]) > gedp->ged_wdbp->wdb_tol.dist) { good_vert = 0; break; } } if (good_vert) break; } } if (good_vert) break; } if (good_vert) break; } break; } case ID_EBM: { struct rt_ebm_internal *ebm = (struct rt_ebm_internal *)ip->idb_ptr; point_t pnt; RT_EBM_CK_MAGIC(ebm); VSETALL(pnt, 0.0); MAT4X3PNT(mpt, ebm->mat, pnt); break; } case ID_BOT: { struct rt_bot_internal *bot = (struct rt_bot_internal *)ip->idb_ptr; VMOVE(mpt, bot->vertices); break; } case ID_DSP: { struct rt_dsp_internal *dsp = (struct rt_dsp_internal *)ip->idb_ptr; point_t pnt; RT_DSP_CK_MAGIC(dsp); VSETALL(pnt, 0.0); MAT4X3PNT(mpt, dsp->dsp_stom, pnt); break; } case ID_HF: { struct rt_hf_internal *hf = (struct rt_hf_internal *)ip->idb_ptr; RT_HF_CK_MAGIC(hf); VMOVE(mpt, hf->v); break; } case ID_VOL: { struct rt_vol_internal *vol = (struct rt_vol_internal *)ip->idb_ptr; point_t pnt; RT_VOL_CK_MAGIC(vol); VSETALL(pnt, 0.0); MAT4X3PNT(mpt, vol->mat, pnt); break; } case ID_HALF: { struct rt_half_internal *haf = (struct rt_half_internal *)ip->idb_ptr; RT_HALF_CK_MAGIC(haf); VSCALE(mpt, haf->eqn, haf->eqn[H]); break; } case ID_ARB8: { struct rt_arb_internal *arb = (struct rt_arb_internal *)ip->idb_ptr; RT_ARB_CK_MAGIC(arb); VMOVE(mpt, arb->pt[0]); break; } case ID_ELL: case ID_SPH: { struct rt_ell_internal *ell = (struct rt_ell_internal *)ip->idb_ptr; RT_ELL_CK_MAGIC(ell); VMOVE(mpt, ell->v); break; } case ID_SUPERELL: { struct rt_superell_internal *superell = (struct rt_superell_internal *)ip->idb_ptr; RT_SUPERELL_CK_MAGIC(superell); VMOVE(mpt, superell->v); break; } case ID_TOR: { struct rt_tor_internal *tor = (struct rt_tor_internal *)ip->idb_ptr; RT_TOR_CK_MAGIC(tor); VMOVE(mpt, tor->v); break; } case ID_TGC: case ID_REC: { struct rt_tgc_internal *tgc = (struct rt_tgc_internal *)ip->idb_ptr; RT_TGC_CK_MAGIC(tgc); VMOVE(mpt, tgc->v); break; } case ID_GRIP: { struct rt_grip_internal *gip = (struct rt_grip_internal *)ip->idb_ptr; RT_GRIP_CK_MAGIC(gip); VMOVE(mpt, gip->center); break; } case ID_ARS: { struct rt_ars_internal *ars = (struct rt_ars_internal *)ip->idb_ptr; RT_ARS_CK_MAGIC(ars); VMOVE(mpt, &ars->curves[0][0]); break; } case ID_RPC: { struct rt_rpc_internal *rpc = (struct rt_rpc_internal *)ip->idb_ptr; RT_RPC_CK_MAGIC(rpc); VMOVE(mpt, rpc->rpc_V); break; } case ID_RHC: { struct rt_rhc_internal *rhc = (struct rt_rhc_internal *)ip->idb_ptr; RT_RHC_CK_MAGIC(rhc); VMOVE(mpt, rhc->rhc_V); break; } case ID_EPA: { struct rt_epa_internal *epa = (struct rt_epa_internal *)ip->idb_ptr; RT_EPA_CK_MAGIC(epa); VMOVE(mpt, epa->epa_V); break; } case ID_EHY: { struct rt_ehy_internal *ehy = (struct rt_ehy_internal *)ip->idb_ptr; RT_EHY_CK_MAGIC(ehy); VMOVE(mpt, ehy->ehy_V); break; } case ID_HYP: { struct rt_hyp_internal *hyp = (struct rt_hyp_internal *)ip->idb_ptr; RT_HYP_CK_MAGIC(hyp); VMOVE(mpt, hyp->hyp_Vi); break; } case ID_ETO: { struct rt_eto_internal *eto = (struct rt_eto_internal *)ip->idb_ptr; RT_ETO_CK_MAGIC(eto); VMOVE(mpt, eto->eto_V); break; } case ID_POLY: { struct rt_pg_face_internal *_poly; struct rt_pg_internal *pg = (struct rt_pg_internal *)ip->idb_ptr; RT_PG_CK_MAGIC(pg); _poly = pg->poly; VMOVE(mpt, _poly->verts); break; } case ID_SKETCH: { struct rt_sketch_internal *skt = (struct rt_sketch_internal *)ip->idb_ptr; RT_SKETCH_CK_MAGIC(skt); VMOVE(mpt, skt->V); break; } case ID_EXTRUDE: { struct rt_extrude_internal *extr = (struct rt_extrude_internal *)ip->idb_ptr; RT_EXTRUDE_CK_MAGIC(extr); if (extr->skt && extr->skt->verts) { VJOIN2(mpt, extr->V, extr->skt->verts[0][0], extr->u_vec, extr->skt->verts[0][1], extr->v_vec); } else { VMOVE(mpt, extr->V); } break; } case ID_NMG: { struct vertex *v; struct vertexuse *vu; struct edgeuse *eu; struct loopuse *lu; struct faceuse *fu; struct shell *s; struct nmgregion *r; struct model *m = (struct model *) ip->idb_ptr; NMG_CK_MODEL(m); /* set default first */ VSETALL(mpt, 0.0); if (BU_LIST_IS_EMPTY(&m->r_hd)) break; r = BU_LIST_FIRST(nmgregion, &m->r_hd); if (!r) break; NMG_CK_REGION(r); if (BU_LIST_IS_EMPTY(&r->s_hd)) break; s = BU_LIST_FIRST(shell, &r->s_hd); if (!s) break; NMG_CK_SHELL(s); if (BU_LIST_IS_EMPTY(&s->fu_hd)) fu = (struct faceuse *)NULL; else fu = BU_LIST_FIRST(faceuse, &s->fu_hd); if (fu) { NMG_CK_FACEUSE(fu); lu = BU_LIST_FIRST(loopuse, &fu->lu_hd); NMG_CK_LOOPUSE(lu); if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC) { eu = BU_LIST_FIRST(edgeuse, &lu->down_hd); NMG_CK_EDGEUSE(eu); NMG_CK_VERTEXUSE(eu->vu_p); v = eu->vu_p->v_p; } else { vu = BU_LIST_FIRST(vertexuse, &lu->down_hd); NMG_CK_VERTEXUSE(vu); v = vu->v_p; } NMG_CK_VERTEX(v); if (!v->vg_p) break; VMOVE(mpt, v->vg_p->coord); break; } if (BU_LIST_IS_EMPTY(&s->lu_hd)) lu = (struct loopuse *)NULL; else lu = BU_LIST_FIRST(loopuse, &s->lu_hd); if (lu) { NMG_CK_LOOPUSE(lu); if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC) { eu = BU_LIST_FIRST(edgeuse, &lu->down_hd); NMG_CK_EDGEUSE(eu); NMG_CK_VERTEXUSE(eu->vu_p); v = eu->vu_p->v_p; } else { vu = BU_LIST_FIRST(vertexuse, &lu->down_hd); NMG_CK_VERTEXUSE(vu); v = vu->v_p; } NMG_CK_VERTEX(v); if (!v->vg_p) break; VMOVE(mpt, v->vg_p->coord); break; } if (BU_LIST_IS_EMPTY(&s->eu_hd)) eu = (struct edgeuse *)NULL; else eu = BU_LIST_FIRST(edgeuse, &s->eu_hd); if (eu) { NMG_CK_EDGEUSE(eu); NMG_CK_VERTEXUSE(eu->vu_p); v = eu->vu_p->v_p; NMG_CK_VERTEX(v); if (!v->vg_p) break; VMOVE(mpt, v->vg_p->coord); break; } vu = s->vu_p; if (vu) { NMG_CK_VERTEXUSE(vu); v = vu->v_p; NMG_CK_VERTEX(v); if (!v->vg_p) break; VMOVE(mpt, v->vg_p->coord); break; } } default: VSETALL(mpt, 0.0); bu_vls_printf(gedp->ged_result_str, "get_solid_keypoint: unrecognized solid type"); return GED_ERROR; } MAT4X3PNT(pt, mat, mpt); return GED_OK; }
/** * R T _ P G _ I M P O R T * * Read all the polygons in as a complex dynamic structure. * The caller is responsible for freeing the dynamic memory. * (vid rt_pg_ifree). */ int rt_pg_import4(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip) { struct rt_pg_internal *pgp; union record *rp; size_t i; size_t rno; /* current record number */ size_t p; /* current polygon index */ if (dbip) RT_CK_DBI(dbip); BU_CK_EXTERNAL(ep); rp = (union record *)ep->ext_buf; if (rp->u_id != ID_P_HEAD) { bu_log("rt_pg_import4: defective header record\n"); return -1; } RT_CK_DB_INTERNAL(ip); ip->idb_major_type = DB5_MAJORTYPE_BRLCAD; ip->idb_type = ID_POLY; ip->idb_meth = &rt_functab[ID_POLY]; BU_ALLOC(ip->idb_ptr, struct rt_pg_internal); pgp = (struct rt_pg_internal *)ip->idb_ptr; pgp->magic = RT_PG_INTERNAL_MAGIC; pgp->npoly = (ep->ext_nbytes - sizeof(union record)) / sizeof(union record); if (pgp->npoly <= 0) { bu_log("rt_pg_import4: polysolid with no polygons!\n"); return -1; } if (pgp->npoly) pgp->poly = (struct rt_pg_face_internal *)bu_malloc( pgp->npoly * sizeof(struct rt_pg_face_internal), "rt_pg_face_internal"); pgp->max_npts = 0; if (mat == NULL) mat = bn_mat_identity; for (p=0; p < pgp->npoly; p++) { struct rt_pg_face_internal *pp; pp = &pgp->poly[p]; rno = p+1; if (rp[rno].q.q_id != ID_P_DATA) { bu_log("rt_pg_import4: defective data record\n"); return -1; } pp->npts = rp[rno].q.q_count; pp->verts = (fastf_t *)bu_malloc(pp->npts * 3 * sizeof(fastf_t), "pg verts[]"); pp->norms = (fastf_t *)bu_malloc(pp->npts * 3 * sizeof(fastf_t), "pg norms[]"); for (i=0; i < pp->npts; i++) { point_t pnt; vect_t vec; if (dbip->dbi_version < 0) { flip_fastf_float(pnt, rp[rno].q.q_verts[i], 1, 1); flip_fastf_float(vec, rp[rno].q.q_norms[i], 1, 1); } else { VMOVE(pnt, rp[rno].q.q_verts[i]); VMOVE(vec, rp[rno].q.q_norms[i]); } /* Note: side effect of importing dbfloat_t */ MAT4X3PNT(&pp->verts[i*3], mat, pnt); MAT4X3VEC(&pp->norms[i*3], mat, vec); } if (pp->npts > pgp->max_npts) pgp->max_npts = pp->npts; } if (pgp->max_npts < 3) { bu_log("rt_pg_import4: polysolid with all polygons of less than %zu vertices!\n", pgp->max_npts); /* XXX free storage */ return -1; } return 0; }