void Convtree() { int conv = 0; int tottrees = 0; union tree *ptr; struct rt_comb_internal *comb; int no_of_assoc = 0; int no_of_props = 0; int att_de = 0; struct brlcad_att brl_att; int i, j, k; if (bu_debug & BU_DEBUG_MEM_CHECK) bu_log("Doing memory checking in Convtree()\n"); MEMCHECK; bu_log("\nConverting boolean tree entities:\n"); for (i = 0; i < totentities; i++) { /* loop through all entities */ if (dir[i]->type != 180) /* This is not a tree */ continue; att_de = 0; /* For default if there is no attribute entity */ tottrees++; if (dir[i]->param <= pstart) { /* Illegal parameter address */ bu_log("Entity number %d (Boolean Tree) does not have a legal parameter pointer\n", i); continue; } Readrec(dir[i]->param); /* read first record into buffer */ MEMCHECK; ptr = Readtree(dir[i]->rot); /* construct the tree */ MEMCHECK; if (!ptr) { /* failure */ bu_log("\tFailed to convert Boolean tree at D%07d\n", dir[i]->direct); continue; } /* skip over the associativities */ Readint(&no_of_assoc, ""); for (k = 0; k < no_of_assoc; k++) Readint(&j, ""); /* get property entity DE's */ Readint(&no_of_props, ""); for (k = 0; k < no_of_props; k++) { Readint(&j, ""); if (dir[(j-1)/2]->type == 422 && dir[(j-1)/2]->referenced == brlcad_att_de) { /* this is one of our attribute instances */ att_de = j; } } Read_att(att_de, &brl_att); /* Read_att will supply defaults if att_de is 0 */ if (att_de == 0) brl_att.region_flag = 1; BU_ALLOC(comb, struct rt_comb_internal); RT_COMB_INTERNAL_INIT(comb); comb->tree = ptr; if (brl_att.region_flag) { comb->region_flag = 1; comb->region_id = brl_att.ident; comb->aircode = brl_att.air_code; comb->GIFTmater = brl_att.material_code; comb->los = brl_att.los_density; } if (dir[i]->colorp != 0) { comb->rgb_valid = 1; comb->rgb[0] = dir[i]->rgb[0]; comb->rgb[1] = dir[i]->rgb[1]; comb->rgb[2] = dir[i]->rgb[2]; } comb->inherit = brl_att.inherit; bu_vls_init(&comb->shader); if (brl_att.material_name) { bu_vls_strcpy(&comb->shader, brl_att.material_name); if (brl_att.material_params) { bu_vls_putc(&comb->shader, ' '); bu_vls_strcat(&comb->shader, brl_att.material_params); } } bu_vls_init(&comb->material); MEMCHECK; if (wdb_export(fdout, dir[i]->name, (void *)comb, ID_COMBINATION, mk_conv2mm)) bu_exit(1, "mk_export_fwrite() failed for combination (%s)\n", dir[i]->name); conv++; MEMCHECK; } bu_log("Converted %d trees successfully out of %d total trees\n", conv, tottrees); MEMCHECK; }
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; }
int rt_comb_import4( struct rt_db_internal *ip, const struct bu_external *ep, const mat_t matrix, /* NULL if identity */ const struct db_i *dbip, struct resource *resp) { union record *rp; struct rt_tree_array *rt_tree_array; union tree *tree; struct rt_comb_internal *comb; size_t j; size_t node_count; BU_CK_EXTERNAL(ep); rp = (union record *)ep->ext_buf; if (dbip) RT_CK_DBI(dbip); if (rp[0].u_id != ID_COMB) { bu_log("rt_comb_import4: Attempt to import a non-combination\n"); return -1; } /* Compute how many granules of MEMBER records follow */ node_count = ep->ext_nbytes/sizeof(union record) - 1; if (node_count) rt_tree_array = (struct rt_tree_array *)bu_calloc(node_count, sizeof(struct rt_tree_array), "rt_tree_array"); else rt_tree_array = (struct rt_tree_array *)NULL; for (j = 0; j < node_count; j++) { if (rp[j+1].u_id != ID_MEMB) { bu_free((void *)rt_tree_array, "rt_comb_import4: rt_tree_array"); bu_log("rt_comb_import4(): granule in external buffer is not ID_MEMB, id=%d\n", rp[j+1].u_id); return -1; } switch (rp[j+1].M.m_relation) { case '+': rt_tree_array[j].tl_op = OP_INTERSECT; break; case '-': rt_tree_array[j].tl_op = OP_SUBTRACT; break; default: bu_log("rt_comb_import4() unknown op=x%x, assuming UNION\n", rp[j+1].M.m_relation); /* Fall through */ case 'u': rt_tree_array[j].tl_op = OP_UNION; break; } /* Build leaf node for in-memory tree */ { union tree *tp; mat_t diskmat; char namebuf[NAMESIZE+1]; RT_GET_TREE(tp, resp); rt_tree_array[j].tl_tree = tp; tp->tr_l.tl_op = OP_DB_LEAF; /* bu_strlcpy not safe here, buffer size mismatch */ memset(namebuf, 0, NAMESIZE+1); memcpy(namebuf, rp[j+1].M.m_instname, sizeof(rp[j+1].M.m_instname)); tp->tr_l.tl_name = bu_strdup(namebuf); flip_mat_dbmat(diskmat, rp[j+1].M.m_mat, dbip->dbi_version < 0 ? 1 : 0); /* Verify that rotation part is pure rotation */ if (fabs(diskmat[0]) > 1 || fabs(diskmat[1]) > 1 || fabs(diskmat[2]) > 1 || fabs(diskmat[4]) > 1 || fabs(diskmat[5]) > 1 || fabs(diskmat[6]) > 1 || fabs(diskmat[8]) > 1 || fabs(diskmat[9]) > 1 || fabs(diskmat[10]) > 1) { bu_log("ERROR: %s/%s improper scaling, rotation matrix elements > 1\n", rp[0].c.c_name, namebuf); } /* Verify that perspective isn't used as a modeling transform */ if (!ZERO(diskmat[12]) || !ZERO(diskmat[13]) || !ZERO(diskmat[14])) { bu_log("ERROR: %s/%s has perspective transform\n", rp[0].c.c_name, namebuf); } /* See if disk record is identity matrix */ if (bn_mat_is_identity(diskmat)) { if (matrix == NULL) { tp->tr_l.tl_mat = NULL; /* identity */ } else { tp->tr_l.tl_mat = bn_mat_dup(matrix); } } else { if (matrix == NULL) { tp->tr_l.tl_mat = bn_mat_dup(diskmat); } else { mat_t prod; bn_mat_mul(prod, matrix, diskmat); tp->tr_l.tl_mat = bn_mat_dup(prod); } } /* bu_log("M_name=%s, matp=x%x\n", tp->tr_l.tl_name, tp->tr_l.tl_mat); */ } } if (node_count) tree = db_mkgift_tree(rt_tree_array, node_count, &rt_uniresource); else tree = (union tree *)NULL; RT_DB_INTERNAL_INIT(ip); ip->idb_major_type = DB5_MAJORTYPE_BRLCAD; ip->idb_type = ID_COMBINATION; ip->idb_meth = &OBJ[ID_COMBINATION]; BU_ALLOC(comb, struct rt_comb_internal); RT_COMB_INTERNAL_INIT(comb); comb->tree = tree; ip->idb_ptr = (void *)comb; switch (rp[0].c.c_flags) { case DBV4_NON_REGION_NULL: case DBV4_NON_REGION: comb->region_flag = 0; break; case DBV4_REGION: comb->region_flag = 1; comb->is_fastgen = REGION_NON_FASTGEN; break; case DBV4_REGION_FASTGEN_PLATE: comb->region_flag = 1; comb->is_fastgen = REGION_FASTGEN_PLATE; break; case DBV4_REGION_FASTGEN_VOLUME: comb->region_flag = 1; comb->is_fastgen = REGION_FASTGEN_VOLUME; break; default: bu_log("WARNING: combination %s has illegal c_flag=x%x\n", rp[0].c.c_name, rp[0].c.c_flags); break; } if (comb->region_flag) { if (dbip->dbi_version < 0) { comb->region_id = flip_short(rp[0].c.c_regionid); comb->aircode = flip_short(rp[0].c.c_aircode); comb->GIFTmater = flip_short(rp[0].c.c_material); comb->los = flip_short(rp[0].c.c_los); } else { comb->region_id = rp[0].c.c_regionid; comb->aircode = rp[0].c.c_aircode; comb->GIFTmater = rp[0].c.c_material; comb->los = rp[0].c.c_los; } } else { /* set some reasonable defaults */ comb->region_id = 0; comb->aircode = 0; comb->GIFTmater = 0; comb->los = 0; } comb->rgb_valid = rp[0].c.c_override; if (comb->rgb_valid) { comb->rgb[0] = rp[0].c.c_rgb[0]; comb->rgb[1] = rp[0].c.c_rgb[1]; comb->rgb[2] = rp[0].c.c_rgb[2]; } if (rp[0].c.c_matname[0] != '\0') { #define MAX_SS 128 char shader_str[MAX_SS]; memset(shader_str, 0, MAX_SS); /* copy shader info to a static string */ /* write shader name. c_matname is a buffer, bu_strlcpy not * safe here. */ memcpy(shader_str, rp[0].c.c_matname, sizeof(rp[0].c.c_matname)); bu_strlcat(shader_str, " ", MAX_SS); /* write shader parameters. c_matparm is a buffer, bu_strlcpy * not safe here. */ memcpy(shader_str+strlen(shader_str), rp[0].c.c_matparm, sizeof(rp[0].c.c_matparm)); /* convert to TCL format and place into comb->shader */ if (bu_shader_to_list(shader_str, &comb->shader)) { bu_log("rt_comb_import4: Error: Cannot convert following shader to TCL format:\n"); bu_log("\t%s\n", shader_str); bu_vls_free(&comb->shader); return -1; } } /* XXX Separate flags for color inherit, shader inherit, (new) material inherit? */ /* XXX cf: ma_cinherit, ma_minherit */ /* This ? is necessary to clean up old databases with grunge here */ comb->inherit = (rp[0].c.c_inherit == DB_INH_HIGHER) ? 1 : 0; /* Automatic material table lookup here? */ if (comb->region_flag) bu_vls_printf(&comb->material, "gift%ld", comb->GIFTmater); if (rt_tree_array) bu_free((void *)rt_tree_array, "rt_tree_array"); return 0; }
int ged_put_comb(struct ged *gedp, int argc, const char *argv[]) { struct directory *dp; struct rt_db_internal intern; struct rt_comb_internal *comb; char new_name_v4[NAMESIZE+1]; char *new_name; int offset; int save_comb_flag = 0; static const char *usage = "comb_name is_Region id air material los color shader inherit boolean_expr"; static const char *noregionusage = "comb_name n color shader inherit boolean_expr"; static const char *regionusage = "comb_name y id air material los color shader inherit boolean_expr"; const char *saved_name = NULL; 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 < 7 || 11 < argc) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } comb = (struct rt_comb_internal *)NULL; dp = db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_QUIET); if (dp != RT_DIR_NULL) { if (!(dp->d_flags & RT_DIR_COMB)) { bu_vls_printf(gedp->ged_result_str, "%s: %s is not a combination, so cannot be edited this way\n", argv[0], argv[1]); 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, "%s: Database read error, aborting\n", argv[0]); return GED_ERROR; } comb = (struct rt_comb_internal *)intern.idb_ptr; saved_name = save_comb(gedp, dp); /* Save combination to a temp name */ save_comb_flag = 1; } /* empty the existing combination */ if (comb) { db_free_tree(comb->tree, &rt_uniresource); comb->tree = NULL; } else { /* make an empty combination structure */ BU_ALLOC(comb, struct rt_comb_internal); if (comb == NULL) bu_bomb("Unable to allocate comb memory"); RT_COMB_INTERNAL_INIT(comb); } if (db_version(gedp->ged_wdbp->dbip) < 5) { new_name = new_name_v4; if (dp == RT_DIR_NULL) NAMEMOVE(argv[1], new_name_v4); else NAMEMOVE(dp->d_namep, new_name_v4); } else { if (dp == RT_DIR_NULL) new_name = (char *)argv[1]; else new_name = dp->d_namep; } if (*argv[2] == 'y' || *argv[2] == 'Y') comb->region_flag = 1; else comb->region_flag = 0; if (comb->region_flag) { if (argc != 11) { bu_vls_printf(gedp->ged_result_str, "region_flag is set, incorrect number of arguments supplied.\n"); bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], regionusage); return GED_ERROR; } comb->region_id = atoi(argv[3]); comb->aircode = atoi(argv[4]); comb->GIFTmater = atoi(argv[5]); comb->los = atoi(argv[6]); offset = 6; } else { if (argc != 7) { bu_vls_printf(gedp->ged_result_str, "region_flag is not set, incorrect number of arguments supplied.\n"); bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], noregionusage); return GED_ERROR; } offset = 2; } put_rgb_into_comb(comb, argv[offset + 1]); bu_vls_strcpy(&comb->shader, argv[offset +2]); if (*argv[offset + 3] == 'y' || *argv[offset + 3] == 'Y') comb->inherit = 1; else comb->inherit = 0; if (put_tree_into_comb(gedp, comb, dp, argv[1], new_name, argv[offset + 4]) == GED_ERROR) { if (comb && dp) { restore_comb(gedp, dp, saved_name); bu_vls_printf(gedp->ged_result_str, "%s: \toriginal restored\n", argv[0]); } bu_file_delete(_ged_tmpfil); return GED_ERROR; } else if (save_comb_flag) { /* eliminate the temporary combination */ const char *av[3]; av[0] = "kill"; av[1] = saved_name; av[2] = NULL; (void)ged_kill(gedp, 2, (const char **)av); } bu_file_delete(_ged_tmpfil); return GED_OK; }
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; }