HIDDEN void find_ref(struct db_i *dbip, struct rt_comb_internal *comb, union tree *comb_leaf, void *object, void *comb_name_ptr, void *user_ptr3, void *UNUSED(user_ptr4)) { char *obj_name; char *comb_name; struct ged *gedp = (struct ged *)user_ptr3; if (dbip) RT_CK_DBI(dbip); if (comb) RT_CK_COMB(comb); RT_CK_TREE(comb_leaf); obj_name = (char *)object; if (!BU_STR_EQUAL(comb_leaf->tr_l.tl_name, obj_name)) return; comb_name = (char *)comb_name_ptr; bu_vls_printf(gedp->ged_result_str, "%s ", comb_name); }
/* return 0 when IS a light or an error occurred. regions are skipped * when this function returns 0. */ static int select_non_lights(struct db_tree_state *UNUSED(tsp), const struct db_full_path *pathp, const struct rt_comb_internal *UNUSED(combp), void *UNUSED(client_data)) { struct directory *dp; struct rt_db_internal intern; struct rt_comb_internal *comb; int id; RT_CK_FULL_PATH(pathp); dp = DB_FULL_PATH_CUR_DIR(pathp); id = rt_db_get_internal(&intern, dp, dbip, (matp_t)NULL, &rt_uniresource); if (id < 0) { /* error occurred retrieving object */ bu_log("Warning: Can not load internal form of %s\n", dp->d_namep); return 0; } if ((dp->d_flags & RT_DIR_COMB) && (id == ID_COMBINATION)) { comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); if (BU_STR_EQUAL(bu_vls_addr(&comb->shader), "light")) { rt_db_free_internal(&intern); return 0; } } return 1; }
void count_refs(struct db_i *dbip, struct directory *dp, void *UNUSED(ptr)) { struct rt_db_internal intern; struct rt_comb_internal *comb; int id; 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 get internal form of %s\n", dp->d_namep); return; } comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); if (!comb->tree) { bu_log("Warning: empty combination (%s)\n", dp->d_namep); dp->d_uses = 0; return; } comb_form = 0; db_tree_funcleaf(dbip, comb, comb->tree, incr_refs, (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL); }
int rt_db_get_internal( struct rt_db_internal *ip, const struct directory *dp, const struct db_i *dbip, const mat_t mat, struct resource *resp) { struct bu_external ext; int id; int ret; RT_DB_INTERNAL_INIT(ip); if (dbip->dbi_version > 4) return rt_db_get_internal5(ip, dp, dbip, mat, resp); BU_EXTERNAL_INIT(&ext); if (db_get_external(&ext, dp, dbip) < 0) return -2; /* FAIL */ if (dp->d_flags & RT_DIR_COMB) { id = ID_COMBINATION; } else { /* As a convenience to older ft_import4 routines */ if (mat == NULL) mat = bn_mat_identity; id = rt_id_solid(&ext); } /* ip is already initialized and should not be re-initialized */ ret = -1; if (OBJ[id].ft_import4) { ret = OBJ[id].ft_import4(ip, &ext, mat, dbip, resp); } if (ret < 0) { bu_log("rt_db_get_internal(%s): import failure\n", dp->d_namep); rt_db_free_internal(ip); bu_free_external(&ext); return -1; /* FAIL */ } bu_free_external(&ext); RT_CK_DB_INTERNAL(ip); ip->idb_meth = &OBJ[id]; /* prior to version 5, there are no attributes ... */ bu_avs_init_empty(&ip->idb_avs); /* ... but this isn't the whole story: */ if (id == ID_COMBINATION) { const struct rt_comb_internal *comb = (const struct rt_comb_internal *)ip->idb_ptr; RT_CK_COMB(comb); db5_sync_comb_to_attr(&ip->idb_avs, comb); } return id; /* OK */ }
HIDDEN int printcodes(FILE *fp, struct directory *dp, int pathpos) { int i; struct rt_db_internal intern; struct rt_comb_internal *comb; int id; CHECK_DBI_NULL; if (pathpos >= MAX_LEVELS) { regflag = ABORTED; return TCL_ERROR; } if (!(dp->d_flags & RT_DIR_COMB)) return 0; if ((id=rt_db_get_internal(&intern, dp, dbip, (matp_t)NULL, &rt_uniresource)) < 0) { Tcl_AppendResult(INTERP, "printcodes: Cannot get records for ", dp->d_namep, "\n", (char *)NULL); return TCL_ERROR; } if (id != ID_COMBINATION) return TCL_OK; comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); if (comb->region_flag) { fprintf(fp, "%-6ld %-3ld %-3ld %-4ld ", comb->region_id, comb->aircode, comb->GIFTmater, comb->los); for (i=0; i < pathpos; i++) fprintf(fp, "/%s", path[i]->d_namep); fprintf(fp, "/%s\n", dp->d_namep); intern.idb_meth->ft_ifree(&intern); return TCL_OK; } if (comb->tree) { path[pathpos] = dp; db_tree_funcleaf(dbip, comb, comb->tree, Do_printnode, (void *)fp, (void *)&pathpos, (void *)NULL, (void *)NULL); } intern.idb_meth->ft_ifree(&intern); return TCL_OK; }
int ged_comb_color(struct rt_wdb *wdbp, int argc, const char *argv[]) { int i; int val; register struct directory *dp; struct rt_db_internal intern; struct rt_comb_internal *comb; static const char *usage = "comb_color combination R G B"; GED_CHECK_DATABASE_OPEN(wdbp, GED_ERROR); GED_CHECK_READ_ONLY(wdbp, GED_ERROR); /* initialize result */ bu_vls_trunc(&wdbp->wdb_result_str, 0); wdbp->wdb_result = GED_RESULT_NULL; wdbp->wdb_result_flags = 0; /* must be wanting help */ if (argc == 1) { wdbp->wdb_result_flags |= GED_RESULT_FLAGS_HELP_BIT; bu_vls_printf(&wdbp->wdb_result_str, "Usage: %s %s", argv[0], usage); return GED_OK; } if (argc != 5) { bu_vls_printf(&wdbp->wdb_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } GED_DB_LOOKUP(wdbp, dp, argv[1], LOOKUP_NOISY, GED_ERROR); GED_CHECK_COMB(wdbp, dp, GED_ERROR); GED_DB_GET_INTERNAL(wdbp, &intern, dp, (fastf_t *)NULL, &rt_uniresource, GED_ERROR); comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); for (i = 0; i < 3; ++i) { if (sscanf(argv[i+2], "%d", &val) != 1 || val < 0 || 255 < val) { bu_vls_printf(&wdbp->wdb_result_str,"RGB value out of range: %s", argv[i + 2]); rt_db_free_internal(&intern, &rt_uniresource); return GED_ERROR; } else comb->rgb[i] = val; } comb->rgb_valid = 1; GED_DB_PUT_INTERNAL(wdbp, dp, &intern, &rt_uniresource, GED_ERROR); return GED_OK; }
HIDDEN int wcodes_printcodes(struct ged *gedp, FILE *fp, struct directory *dp, size_t pathpos) { size_t i; struct rt_db_internal intern; struct rt_comb_internal *comb; int id; if (!(dp->d_flags & RT_DIR_COMB)) return GED_OK; if ((id=rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (matp_t)NULL, &rt_uniresource)) < 0) { bu_vls_printf(gedp->ged_result_str, "Cannot get records for %s\n", dp->d_namep); return GED_ERROR; } if (id != ID_COMBINATION) { intern.idb_meth->ft_ifree(&intern); return GED_OK; } comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); if (comb->region_flag) { fprintf(fp, "%-6ld %-3ld %-3ld %-4ld ", comb->region_id, comb->aircode, comb->GIFTmater, comb->los); for (i =0 ; i < pathpos; i++) fprintf(fp, "/%s", path[i]->d_namep); fprintf(fp, "/%s\n", dp->d_namep); intern.idb_meth->ft_ifree(&intern); return GED_OK; } if (comb->tree) { if (pathpos >= path_capacity) { path_capacity += PATH_STEP; path = (struct directory **)bu_realloc(path, sizeof(struct directory *) * path_capacity, "realloc path bigger"); } path[pathpos] = dp; db_tree_funcleaf(gedp->ged_wdbp->dbip, comb, comb->tree, wcodes_printnode, (void *)fp, (void *)&pathpos, (void *)gedp, (void *)gedp); } intern.idb_meth->ft_ifree(&intern); return GED_OK; }
void incr_refs(struct db_i *dbip, struct rt_comb_internal *comb, union tree *tp, void *UNUSED(user_ptr1), void *UNUSED(user_ptr2), void *UNUSED(user_ptr3), void *UNUSED(user_ptr4)) { struct directory *dp; RT_CK_COMB(comb); RT_CK_DBI(dbip); RT_CK_TREE(tp); if ((dp = db_lookup(dbip, tp->tr_l.tl_name, LOOKUP_NOISY)) == RT_DIR_NULL) return; dp->d_nref++; }
int rt_comb_export4( struct bu_external *ep, const struct rt_db_internal *ip, double UNUSED(local2mm), const struct db_i *dbip, struct resource *resp) { struct rt_comb_internal *comb; size_t node_count; size_t actual_count; struct rt_tree_array *rt_tree_array; union tree *tp; union record *rp; size_t j; char *endp; struct bu_vls tmp_vls = BU_VLS_INIT_ZERO; RT_CK_DB_INTERNAL(ip); if (dbip) RT_CK_DBI(dbip); RT_CK_RESOURCE(resp); if (ip->idb_type != ID_COMBINATION) bu_bomb("rt_comb_export4() type not ID_COMBINATION"); comb = (struct rt_comb_internal *)ip->idb_ptr; RT_CK_COMB(comb); if (comb->tree && db_ck_v4gift_tree(comb->tree) < 0) { db_non_union_push(comb->tree, resp); if (db_ck_v4gift_tree(comb->tree) < 0) { /* Need to further modify tree */ bu_log("rt_comb_export4() Unable to V4-ify tree, aborting.\n"); rt_pr_tree(comb->tree, 0); return -1; } } /* Count # leaves in tree -- that's how many Member records needed. */ node_count = db_tree_nleaves(comb->tree); if (node_count > 0) { rt_tree_array = (struct rt_tree_array *)bu_calloc(node_count, sizeof(struct rt_tree_array), "rt_tree_array"); /* Convert tree into array form */ actual_count = db_flatten_tree(rt_tree_array, comb->tree, OP_UNION, 1, resp) - rt_tree_array; BU_ASSERT_SIZE_T(actual_count, ==, node_count); comb->tree = TREE_NULL; } else {
HIDDEN int edcodes_collect_regnames(struct ged *gedp, struct directory *dp, int pathpos) { int id; int status = 0; struct rt_db_internal intern; struct rt_comb_internal *comb; if (!(dp->d_flags & RT_DIR_COMB)) return EDCODES_OK; if ((id=rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (matp_t)NULL, &rt_uniresource)) < 0) { bu_vls_printf(gedp->ged_result_str, "Cannot get records for %s\n", dp->d_namep); return EDCODES_NOTOK; } if (id != ID_COMBINATION) { intern.idb_meth->ft_ifree(&intern); return EDCODES_OK; } comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); if (comb->region_flag) { bu_vls_printf(gedp->ged_result_str, " %s", dp->d_namep); intern.idb_meth->ft_ifree(&intern); return EDCODES_OK; } if (comb->tree) { db_tree_funcleaf(gedp->ged_wdbp->dbip, comb, comb->tree, edcodes_traverse_node, (void *)&pathpos, (void *)gedp, (void *)&status, (void *)NULL); } intern.idb_meth->ft_ifree(&intern); if (status == EDCODES_HALT) return EDCODES_HALT; return EDCODES_OK; }
static int select_lights(struct db_tree_state *UNUSED(tsp), const struct db_full_path *pathp, const struct rt_comb_internal *UNUSED(combp), void *UNUSED(client_data)) { struct directory *dp; struct rt_db_internal intern; struct rt_comb_internal *comb; int id; RT_CK_FULL_PATH( pathp ); dp = DB_FULL_PATH_CUR_DIR( pathp ); if ( !(dp->d_flags & RT_DIR_COMB) ) return -1; 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 -1; } if ( id != ID_COMBINATION ) { bu_log( "Directory/database mismatch!\n\t is '%s' a combination or not?\n", dp->d_namep ); return -1; } comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB( comb ); if ( BU_STR_EQUAL( bu_vls_addr( &comb->shader ), "light" ) ) { rt_db_free_internal(&intern); return 0; } else { rt_db_free_internal(&intern); 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 {
int ged_remove(struct ged *gedp, int argc, const char *argv[]) { struct directory *dp; int i; int num_deleted; struct rt_db_internal intern; struct rt_comb_internal *comb; int ret; static const char *usage = "comb object(s)"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_DRAWABLE(gedp, GED_ERROR); GED_CHECK_READ_ONLY(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 < 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_NOISY)) == RT_DIR_NULL) return GED_ERROR; if ((dp->d_flags & RT_DIR_COMB) == 0) { bu_vls_printf(gedp->ged_result_str, "rm: %s is not a combination", dp->d_namep); return GED_ERROR; } if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) { bu_vls_printf(gedp->ged_result_str, "Database read error, aborting"); return GED_ERROR; } comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); /* Process each argument */ num_deleted = 0; ret = TCL_OK; for (i = 2; i < argc; i++) { if (db_tree_del_dbleaf(&(comb->tree), argv[i], &rt_uniresource, 0) < 0) { bu_vls_printf(gedp->ged_result_str, "ERROR: Failure deleting %s/%s\n", dp->d_namep, argv[i]); ret = GED_ERROR; } else { struct bu_vls path = BU_VLS_INIT_ZERO; bu_vls_printf(&path, "%s/%s", dp->d_namep, argv[i]); _ged_eraseAllPathsFromDisplay(gedp, bu_vls_addr(&path), 0); bu_vls_free(&path); bu_vls_printf(gedp->ged_result_str, "deleted %s/%s\n", dp->d_namep, argv[i]); num_deleted++; } } if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) { bu_vls_printf(gedp->ged_result_str, "Database write error, aborting"); return GED_ERROR; } return ret; }
/** * When performing "ev" on a region, consider whether to process the * whole subtree recursively. * * Normally, say "yes" to all regions by returning 0. * * Check for special case: a region of one solid, which can be * directly drawn as polygons without going through NMGs. If we draw * it here, then return -1 to signal caller to ignore further * processing of this region. A hack to view polygonal models * (converted from FASTGEN) more rapidly. */ static int draw_nmg_region_start(struct db_tree_state *tsp, const struct db_full_path *pathp, const struct rt_comb_internal *combp, void *client_data) { union tree *tp; struct directory *dp; struct rt_db_internal intern; mat_t xform; matp_t matp; struct bu_list vhead; struct _ged_client_data *dgcdp = (struct _ged_client_data *)client_data; if (RT_G_DEBUG&DEBUG_TREEWALK) { char *sofar = db_path_to_string(pathp); bu_vls_printf(dgcdp->gedp->ged_result_str, "nmg_region_start(%s)\n", sofar); bu_free((void *)sofar, "path string"); rt_pr_tree(combp->tree, 1); db_pr_tree_state(tsp); } RT_CK_DBI(tsp->ts_dbip); RT_CK_RESOURCE(tsp->ts_resp); BU_LIST_INIT(&vhead); RT_CK_COMB(combp); tp = combp->tree; if (!tp) return -1; RT_CK_TREE(tp); if (tp->tr_l.tl_op != OP_DB_LEAF) return 0; /* proceed as usual */ /* The subtree is a single node. It may be a combination, though */ /* Fetch by name, check to see if it's an easy type */ dp = db_lookup(tsp->ts_dbip, tp->tr_l.tl_name, LOOKUP_NOISY); if (!dp) return 0; /* proceed as usual */ if (!bn_mat_is_identity(tsp->ts_mat)) { if (tp->tr_l.tl_mat) { matp = xform; bn_mat_mul(xform, tsp->ts_mat, tp->tr_l.tl_mat); } else { matp = tsp->ts_mat; } } else { if (tp->tr_l.tl_mat) { matp = tp->tr_l.tl_mat; } else { matp = (matp_t)NULL; } } if (rt_db_get_internal(&intern, dp, tsp->ts_dbip, matp, &rt_uniresource) < 0) return 0; /* proceed as usual */ switch (intern.idb_type) { case ID_POLY: { if (RT_G_DEBUG&DEBUG_TREEWALK) { bu_log("fastpath draw ID_POLY %s\n", dp->d_namep); } if (dgcdp->draw_wireframes) { (void)rt_pg_plot(&vhead, &intern, tsp->ts_ttol, tsp->ts_tol, NULL); } else { (void)rt_pg_plot_poly(&vhead, &intern, tsp->ts_ttol, tsp->ts_tol); } } goto out; case ID_BOT: { if (RT_G_DEBUG&DEBUG_TREEWALK) { bu_log("fastpath draw ID_BOT %s\n", dp->d_namep); } if (dgcdp->draw_wireframes) { (void)rt_bot_plot(&vhead, &intern, tsp->ts_ttol, tsp->ts_tol, NULL); } else { (void)rt_bot_plot_poly(&vhead, &intern, tsp->ts_ttol, tsp->ts_tol); } } goto out; case ID_BREP: { if (RT_G_DEBUG&DEBUG_TREEWALK) { bu_log("fastpath draw ID_BREP %s\n", dp->d_namep); } if (dgcdp->draw_wireframes) { (void)rt_brep_plot(&vhead, &intern, tsp->ts_ttol, tsp->ts_tol, NULL); } else { (void)rt_brep_plot_poly(&vhead, pathp, &intern, tsp->ts_ttol, tsp->ts_tol, NULL); } } goto out; case ID_COMBINATION: default: break; } rt_db_free_internal(&intern); return 0; out: { struct db_full_path pp; db_full_path_init(&pp); db_dup_full_path(&pp, pathp); /* Successful fastpath drawing of this solid */ db_add_node_to_full_path(&pp, dp); _ged_drawH_part2(0, &vhead, &pp, tsp, dgcdp); db_free_full_path(&pp); } rt_db_free_internal(&intern); dgcdp->fastpath_count++; return -1; /* SKIP THIS REGION */ }
int main(int argc, char **argv) { struct rt_wdb *fp; struct db_i *dbip; struct directory *dp; long errors = 0; struct bn_tol tol; char name[17]; bu_setprogname(argv[0]); /* FIXME: These need to be improved */ tol.magic = BN_TOL_MAGIC; tol.dist = 0.0005; tol.dist_sq = tol.dist * tol.dist; tol.perp = 1e-6; tol.para = 1 - tol.perp; bu_debug = BU_DEBUG_COREDUMP; rt_init_resource( &rt_uniresource, 0, NULL ); if ( argc != 3 ) { fprintf(stderr, "Usage: %s v4.g v5.g\n", argv[0]); return 1; } if ( (dbip = db_open(argv[1], DB_OPEN_READONLY)) == DBI_NULL ) { perror( argv[1] ); return 2; } if ( (fp = wdb_fopen( argv[2] )) == NULL ) { perror( argv[2] ); return 3; } if ( db_version(dbip) != 4 ) { bu_log( "Input database must be a version 4 database!!!!\n" ); return 4; } RT_CK_DBI(dbip); if ( db_dirbuild( dbip ) ) bu_exit(1, "db_dirbuild failed\n" ); db_update_ident( fp->dbip, dbip->dbi_title, dbip->dbi_local2base ); /* Retrieve every item in the input database */ FOR_ALL_DIRECTORY_START(dp, dbip) { struct rt_db_internal intern; int id; int ret; fprintf(stderr, "%.16s\n", dp->d_namep ); id = rt_db_get_internal( &intern, dp, dbip, NULL, &rt_uniresource ); if ( id < 0 ) { fprintf(stderr, "%s: rt_db_get_internal(%s) failure, skipping\n", argv[0], dp->d_namep); errors++; continue; } if ( id == ID_COMBINATION ) { struct rt_comb_internal *comb; char *ptr; comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB( comb ); /* Convert "plastic" to "phong" in the shader string */ while ( (ptr=strstr( bu_vls_addr( &comb->shader), "plastic" )) != NULL ) { ptr[0] = 'p'; /* p */ ptr[1] = 'h'; /* l */ ptr[2] = 'o'; /* a */ ptr[3] = 'n'; /* s */ ptr[4] = 'g'; /* t */ ptr[5] = ' '; /* i */ ptr[6] = ' '; /* c */ } } if ( id == ID_HF ) { if (rt_hf_to_dsp( &intern )) { fprintf(stderr, "%s: Conversion from HF to DSP failed for solid %s\n", argv[0], dp->d_namep ); errors++; continue; } } if ( id == ID_POLY) { if ( rt_pg_to_bot( &intern, &tol, &rt_uniresource ) ) { fprintf( stderr, "%s: Conversion from polysolid to BOT failed for solid %s\n", argv[0], dp->d_namep ); errors++; continue; } } /* to insure null termination */ bu_strlcpy( name, dp->d_namep, sizeof(name) ); ret = wdb_put_internal( fp, name, &intern, 1.0 ); if ( ret < 0 ) { fprintf(stderr, "%s: wdb_put_internal(%s) failure, skipping\n", argv[0], dp->d_namep); rt_db_free_internal(&intern); errors++; continue; } rt_db_free_internal(&intern); } FOR_ALL_DIRECTORY_END wdb_close( fp ); db_close( dbip ); fprintf(stderr, "%ld objects failed to convert\n", errors); return 0; }
int wdb_comb_std_cmd(struct rt_wdb *wdbp, Tcl_Interp *interp, int argc, char *argv[]) { char *comb_name; int ch; int region_flag = -1; struct directory *dp; struct rt_db_internal intern; struct rt_comb_internal *comb = NULL; struct tokens tok_hd; short last_tok; int i; union tree *final_tree; if (wdbp->dbip->dbi_read_only) { Tcl_AppendResult(interp, "Database is read-only!\n", (char *)NULL); return TCL_ERROR; } if (argc < 3) { struct bu_vls vls = BU_VLS_INIT_ZERO; bu_vls_printf(&vls, "helplib_alias wdb_comb_std %s", argv[0]); Tcl_Eval(interp, bu_vls_addr(&vls)); bu_vls_free(&vls); return TCL_ERROR; } /* Parse options */ bu_optind = 1; /* re-init bu_getopt() */ while ((ch = bu_getopt(argc, argv, "cgr?")) != -1) { switch (ch) { case 'c': case 'g': region_flag = 0; break; case 'r': region_flag = 1; break; /* XXX How about -p and -v for FASTGEN? */ case '?': default: PRINT_USAGE; return TCL_OK; } } argc -= (bu_optind + 1); argv += bu_optind; comb_name = *argv++; if (argc == -1) { PRINT_USAGE; return TCL_OK; } if ((region_flag != -1) && (argc == 0)) { /* * Set/Reset the REGION flag of an existing combination */ if ((dp = db_lookup(wdbp->dbip, comb_name, LOOKUP_NOISY)) == RT_DIR_NULL) return TCL_ERROR; if (!(dp->d_flags & RT_DIR_COMB)) { Tcl_AppendResult(interp, comb_name, " is not a combination\n", (char *)0); return TCL_ERROR; } if (rt_db_get_internal(&intern, dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) { Tcl_AppendResult(interp, "Database read error, aborting\n", (char *)NULL); return TCL_ERROR; } comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); if (region_flag) { if (!comb->region_flag) { /* assign values from the defaults */ comb->region_id = wdbp->wdb_item_default++; comb->aircode = wdbp->wdb_air_default; comb->GIFTmater = wdbp->wdb_mat_default; comb->los = wdbp->wdb_los_default; } comb->region_flag = 1; } else comb->region_flag = 0; if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0) { rt_db_free_internal(&intern); Tcl_AppendResult(interp, "Database write error, aborting\n", (char *)NULL); return TCL_ERROR; } return TCL_OK; } /* * At this point, we know we have a Boolean expression. * If the combination already existed and region_flag is -1, * then leave its region_flag alone. * If the combination didn't exist yet, * then pretend region_flag was 0. * Otherwise, make sure to set its c_flags according to region_flag. */ dp = db_lookup(wdbp->dbip, comb_name, LOOKUP_QUIET); if (dp != RT_DIR_NULL) { Tcl_AppendResult(interp, "ERROR: ", comb_name, " already exists\n", (char *)0); return TCL_ERROR; } /* parse Boolean expression */ BU_LIST_INIT(&tok_hd.l); tok_hd.type = WDB_TOK_NULL; last_tok = WDB_TOK_LPAREN; for (i = 0; i < argc; i++) { char *ptr; ptr = argv[i]; while (*ptr) { while (*ptr == '(' || *ptr == ')') { switch (*ptr) { case '(': wdb_append_lparen(&tok_hd.l); last_tok = WDB_TOK_LPAREN; break; case ')': wdb_append_rparen(&tok_hd.l); last_tok = WDB_TOK_RPAREN; break; } ptr++; } if (*ptr == '\0') continue; if (last_tok == WDB_TOK_RPAREN) { /* next token MUST be an operator */ if (wdb_add_operator(interp, &tok_hd.l, *ptr, &last_tok) == TCL_ERROR) { wdb_free_tokens(&tok_hd.l); return TCL_ERROR; } ptr++; } else if (last_tok == WDB_TOK_LPAREN) { /* next token MUST be an operand */ int name_len; name_len = wdb_add_operand(interp, &tok_hd.l, ptr); if (name_len < 1) { wdb_free_tokens(&tok_hd.l); return TCL_ERROR; } last_tok = WDB_TOK_TREE; ptr += name_len; } else if (last_tok == WDB_TOK_TREE) { /* must be an operator */ if (wdb_add_operator(interp, &tok_hd.l, *ptr, &last_tok) == TCL_ERROR) { wdb_free_tokens(&tok_hd.l); return TCL_ERROR; } ptr++; } else if (last_tok == WDB_TOK_UNION || last_tok == WDB_TOK_INTER || last_tok == WDB_TOK_SUBTR) { /* must be an operand */ int name_len; name_len = wdb_add_operand(interp, &tok_hd.l, ptr); if (name_len < 1) { wdb_free_tokens(&tok_hd.l); return TCL_ERROR; } last_tok = WDB_TOK_TREE; ptr += name_len; } } } if (wdb_check_syntax(interp, wdbp->dbip, &tok_hd.l, comb_name, dp)) { wdb_free_tokens(&tok_hd.l); return TCL_ERROR; } final_tree = wdb_eval_bool(&tok_hd.l); { int flags; flags = RT_DIR_COMB; BU_ALLOC(comb, struct rt_comb_internal); RT_COMB_INTERNAL_INIT(comb); comb->tree = final_tree; comb->region_id = -1; if (region_flag == (-1)) comb->region_flag = 0; else comb->region_flag = region_flag; if (comb->region_flag) { struct bu_vls tmp_vls = BU_VLS_INIT_ZERO; comb->region_flag = 1; comb->region_id = wdbp->wdb_item_default++;; comb->aircode = wdbp->wdb_air_default; comb->los = wdbp->wdb_los_default; comb->GIFTmater = wdbp->wdb_mat_default; bu_vls_printf(&tmp_vls, "Creating region id=%ld, air=%ld, los=%ld, GIFTmaterial=%ld\n", comb->region_id, comb->aircode, comb->los, comb->GIFTmater); Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL); bu_vls_free(&tmp_vls); flags |= RT_DIR_REGION; } RT_DB_INTERNAL_INIT(&intern); intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; intern.idb_type = ID_COMBINATION; intern.idb_meth = &rt_functab[ID_COMBINATION]; intern.idb_ptr = (genptr_t)comb; dp=db_diradd(wdbp->dbip, comb_name, RT_DIR_PHONY_ADDR, 0, flags, (genptr_t)&intern.idb_type); if (dp == RT_DIR_NULL) { Tcl_AppendResult(interp, "Failed to add ", comb_name, " to directory, aborting\n", (char *)NULL); return TCL_ERROR; } if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0) { Tcl_AppendResult(interp, "Failed to write ", dp->d_namep, (char *)NULL); return TCL_ERROR; } } return TCL_OK; }
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; }
/** * make n copies of a v5 combination. */ static struct directory * copy_v5_comb(struct db_i *_dbip, struct directory *proto, struct clone_state *state, int idx) { struct directory *dp = (struct directory *)NULL; struct bu_vls *name; size_t i; /* sanity */ if (!proto) { bu_log("ERROR: clone internal consistency error\n"); return (struct directory *)NULL; } /* make n copies */ for (i = 0; i < state->n_copies; i++) { if (i==0) name = get_name(_dbip, proto, state, i); else { dp = db_lookup(_dbip, bu_vls_addr(&obj_list.names[idx].dest[i-1]), LOOKUP_QUIET); if (!dp) { continue; } name = get_name(_dbip, dp, state, i); } bu_vls_strcpy(&obj_list.names[idx].dest[i], bu_vls_addr(name)); /* we have a before and an after, do the copy */ if (proto->d_namep && bu_vls_addr(name)) { struct rt_db_internal dbintern; struct rt_comb_internal *comb; dp = db_lookup(_dbip, proto->d_namep, LOOKUP_QUIET); if (!dp) { bu_vls_free(name); continue; } if (rt_db_get_internal(&dbintern, dp, _dbip, bn_mat_identity, &rt_uniresource) < 0) { bu_log("ERROR: clone internal error copying %s\n", proto->d_namep); return NULL; } if ((dp=db_diradd(wdbp->dbip, bu_vls_addr(name), -1, 0, proto->d_flags, (genptr_t)&proto->d_minor_type)) == RT_DIR_NULL) { bu_log("An error has occurred while adding a new object to the database."); return NULL; } RT_CK_DB_INTERNAL(&dbintern); comb = (struct rt_comb_internal *)dbintern.idb_ptr; RT_CK_COMB(comb); RT_CK_TREE(comb->tree); /* recursively update the tree */ copy_v5_comb_tree(comb->tree, i); if (rt_db_put_internal(dp, wdbp->dbip, &dbintern, &rt_uniresource) < 0) { bu_log("ERROR: clone internal error copying %s\n", proto->d_namep); bu_vls_free(name); return NULL; } bu_vls_free(name); rt_db_free_internal(&dbintern); } /* done with this name */ bu_vls_free(name); } return dp; }
int ged_comb_std(struct ged *gedp, int argc, const char *argv[]) { char *comb_name; int ch; int region_flag = -1; struct directory *dp = RT_DIR_NULL; struct rt_db_internal intern; struct rt_comb_internal *comb = NULL; struct tokens tok_hd; short last_tok; int i; union tree *final_tree; static const char *usage = "[-cr] comb_name <boolean_expr>"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(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 < 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } /* Parse options */ bu_optind = 1; /* re-init bu_getopt() */ while ((ch = bu_getopt(argc, (char * const *)argv, "cgr?")) != -1) { switch (ch) { case 'c': case 'g': region_flag = 0; break; case 'r': region_flag = 1; break; /* XXX How about -p and -v for FASTGEN? */ case '?': default: bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_OK; } } argc -= (bu_optind + 1); argv += bu_optind; comb_name = (char *)*argv++; if (argc == -1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_OK; } if ((region_flag != -1) && (argc == 0)) { /* * Set/Reset the REGION flag of an existing combination */ GED_DB_LOOKUP(gedp, dp, comb_name, LOOKUP_NOISY, GED_ERROR & GED_QUIET); if (!(dp->d_flags & RT_DIR_COMB)) { bu_vls_printf(gedp->ged_result_str, "%s is not a combination\n", comb_name); return GED_ERROR; } GED_DB_GET_INTERNAL(gedp, &intern, dp, (fastf_t *)NULL, &rt_uniresource, GED_ERROR); comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); if (region_flag) { if (!comb->region_flag) { /* assign values from the defaults */ comb->region_id = gedp->ged_wdbp->wdb_item_default++; comb->aircode = gedp->ged_wdbp->wdb_air_default; comb->GIFTmater = gedp->ged_wdbp->wdb_mat_default; comb->los = gedp->ged_wdbp->wdb_los_default; } comb->region_flag = 1; } else comb->region_flag = 0; GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); return GED_OK; } /* * At this point, we know we have a Boolean expression. * If the combination already existed and region_flag is -1, * then leave its region_flag alone. * If the combination didn't exist yet, * then pretend region_flag was 0. * Otherwise, make sure to set its c_flags according to region_flag. */ GED_CHECK_EXISTS(gedp, comb_name, LOOKUP_QUIET, GED_ERROR); dp = RT_DIR_NULL; /* parse Boolean expression */ BU_LIST_INIT(&tok_hd.l); tok_hd.type = TOK_NULL; last_tok = TOK_LPAREN; for (i = 0; i < argc; i++) { char *ptr; ptr = (char *)argv[i]; while (*ptr) { while (*ptr == '(' || *ptr == ')') { switch (*ptr) { case '(': append_lparen(&tok_hd.l); last_tok = TOK_LPAREN; break; case ')': append_rparen(&tok_hd.l); last_tok = TOK_RPAREN; break; } ptr++; } if (*ptr == '\0') continue; if (last_tok == TOK_RPAREN) { /* next token MUST be an operator */ if (add_operator(gedp, &tok_hd.l, *ptr, &last_tok) == GED_ERROR) { free_tokens(&tok_hd.l); return GED_ERROR; } ptr++; } else if (last_tok == TOK_LPAREN) { /* next token MUST be an operand */ int name_len; name_len = add_operand(gedp, &tok_hd.l, ptr); if (name_len < 1) { free_tokens(&tok_hd.l); return GED_ERROR; } last_tok = TOK_TREE; ptr += name_len; } else if (last_tok == TOK_TREE) { /* must be an operator */ if (add_operator(gedp, &tok_hd.l, *ptr, &last_tok) == GED_ERROR) { free_tokens(&tok_hd.l); return GED_ERROR; } ptr++; } else if (last_tok == TOK_UNION || last_tok == TOK_INTER || last_tok == TOK_SUBTR) { /* must be an operand */ int name_len; name_len = add_operand(gedp, &tok_hd.l, ptr); if (name_len < 1) { free_tokens(&tok_hd.l); return GED_ERROR; } last_tok = TOK_TREE; ptr += name_len; } } } if (check_syntax(gedp, &tok_hd.l, comb_name, dp)) { free_tokens(&tok_hd.l); return GED_ERROR; } final_tree = eval_bool(&tok_hd.l); { int flags; flags = RT_DIR_COMB; BU_ALLOC(comb, struct rt_comb_internal); RT_COMB_INTERNAL_INIT(comb); comb->tree = final_tree; comb->region_id = -1; if (region_flag == (-1)) comb->region_flag = 0; else comb->region_flag = region_flag; if (comb->region_flag) { comb->region_flag = 1; comb->region_id = gedp->ged_wdbp->wdb_item_default++; comb->aircode = gedp->ged_wdbp->wdb_air_default; comb->los = gedp->ged_wdbp->wdb_los_default; comb->GIFTmater = gedp->ged_wdbp->wdb_mat_default; bu_vls_printf(gedp->ged_result_str, "Creating region with attrs: region_id=%d, ", comb->region_id); if (comb->aircode) bu_vls_printf(gedp->ged_result_str, "air=%d, ", comb->aircode); bu_vls_printf(gedp->ged_result_str, "los=%d, material_id=%d\n", comb->los, comb->GIFTmater); flags |= RT_DIR_REGION; } RT_DB_INTERNAL_INIT(&intern); intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; intern.idb_type = ID_COMBINATION; intern.idb_meth = &OBJ[ID_COMBINATION]; intern.idb_ptr = (void *)comb; GED_DB_DIRADD(gedp, dp, comb_name, RT_DIR_PHONY_ADDR, 0, flags, (void *)&intern.idb_type, GED_ERROR); GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); } return GED_OK; }
void csg_comb_func(struct db_i *dbip, struct directory *dp, void *UNUSED(ptr)) { struct rt_db_internal intern; struct rt_comb_internal *comb; struct iges_properties props; int comb_len; size_t i; int dependent = 1; int *de_pointers; int id; /* when this is called in facet mode, we only want groups */ if (mode == FACET_MODE && (dp->d_flags & RT_DIR_REGION)) return; /* check if already written */ if (dp->d_uses < 0) return; for (i = 0; i < no_of_indeps; i++) { if (!bu_strncmp(dp->d_namep, independent[i], NAMESIZE+1)) { dependent = 0; break; } } id = rt_db_get_internal(&intern, dp, dbip, (matp_t)NULL, &rt_uniresource); if (id < 0) return; if (id != ID_COMBINATION) { bu_log("Directory/Database mismatch! is %s a combination or not?\n", dp->d_namep); return; } comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); if (verbose) bu_log("Combination - %s\n", dp->d_namep); if (!comb->tree) { bu_log("Warning: empty combination (%s)\n", dp->d_namep); dp->d_uses = 0; return; } comb_len = db_tree_nleaves(comb->tree); de_pointers = (int *)bu_calloc(comb_len, sizeof(int), "csg_comb_func"); comb_form = 0; de_pointer_number = 0; if (get_de_pointers(comb->tree, dp, comb_len, de_pointers)) { bu_log("Error in combination %s\n", dp->d_namep); bu_free((char *)de_pointers, "csg_comb_func de_pointers"); rt_db_free_internal(&intern); return; } bu_strlcpy(props.name, dp->d_namep, NAMESIZE+1); props.material_name[0] = '\0'; props.material_params[0] = '\0'; props.region_flag = ' '; props.ident = 0; props.air_code = 0; props.material_code = 0; props.los_density = 0; props.color[0] = 0; props.color[1] = 0; props.color[2] = 0; get_props(&props, comb); dp->d_uses = (-comb_to_iges(comb, comb_len, dependent, &props, de_pointers, fp_dir, fp_param)); if (!dp->d_uses) { comb_error++; bu_log("g-iges: combination (%s) not written to iges file\n", dp->d_namep); } rt_db_free_internal(&intern); bu_free((char *)de_pointers, "csg_comb_func de_pointers"); }
static int copy_object(struct ged *gedp, struct directory *input_dp, struct db_i *input_dbip, struct db_i *curr_dbip, Tcl_HashTable *name_tbl, Tcl_HashTable *used_names_tbl, struct ged_concat_data *cc_data) { struct rt_db_internal ip; struct rt_extrude_internal *extr; struct rt_dsp_internal *dsp; struct rt_comb_internal *comb; struct directory *new_dp; char *new_name; if (rt_db_get_internal(&ip, input_dp, input_dbip, NULL, &rt_uniresource) < 0) { bu_vls_printf(gedp->ged_result_str, "Failed to get internal form of object (%s) - aborting!!!\n", input_dp->d_namep); return GED_ERROR; } if (ip.idb_major_type == DB5_MAJORTYPE_BRLCAD) { /* adjust names of referenced object in any object that reference other objects */ switch (ip.idb_minor_type) { case DB5_MINORTYPE_BRLCAD_COMBINATION: comb = (struct rt_comb_internal *)ip.idb_ptr; RT_CK_COMB(comb); adjust_names(comb->tree, curr_dbip, name_tbl, used_names_tbl, cc_data); break; case DB5_MINORTYPE_BRLCAD_EXTRUDE: extr = (struct rt_extrude_internal *)ip.idb_ptr; RT_EXTRUDE_CK_MAGIC(extr); new_name = get_new_name(extr->sketch_name, curr_dbip, name_tbl, used_names_tbl, cc_data); if (new_name) { bu_free(extr->sketch_name, "sketch name"); extr->sketch_name = bu_strdup(new_name); } break; case DB5_MINORTYPE_BRLCAD_DSP: dsp = (struct rt_dsp_internal *)ip.idb_ptr; RT_DSP_CK_MAGIC(dsp); if (dsp->dsp_datasrc == RT_DSP_SRC_OBJ) { /* This dsp references a database object, may need to change its name */ new_name = get_new_name(bu_vls_addr(&dsp->dsp_name), curr_dbip, name_tbl, used_names_tbl, cc_data); if (new_name) { bu_vls_free(&dsp->dsp_name); bu_vls_strcpy(&dsp->dsp_name, new_name); } } break; } } new_name = get_new_name(input_dp->d_namep, curr_dbip, name_tbl, used_names_tbl, cc_data); if (!new_name) { new_name = input_dp->d_namep; } if ((new_dp = db_diradd(curr_dbip, new_name, RT_DIR_PHONY_ADDR, 0, input_dp->d_flags, (void *)&input_dp->d_minor_type)) == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "Failed to add new object name (%s) to directory - aborting!!\n", new_name); return GED_ERROR; } if (rt_db_put_internal(new_dp, curr_dbip, &ip, &rt_uniresource) < 0) { bu_vls_printf(gedp->ged_result_str, "Failed to write new object (%s) to database - aborting!!\n", new_name); return GED_ERROR; } return GED_OK; }