size_t db_tree_nleaves(const union tree *tp) { if (tp == TREE_NULL) return 0; RT_CK_TREE(tp); switch (tp->tr_op) { case OP_NOP: return 0; case OP_DB_LEAF: return 1; case OP_SOLID: return 1; case OP_REGION: return 1; case OP_NOT: case OP_GUARD: case OP_XNOP: /* Unary ops */ return db_tree_nleaves(tp->tr_b.tb_left); case OP_UNION: case OP_INTERSECT: case OP_SUBTRACT: case OP_XOR: /* This node is known to be a binary op */ return db_tree_nleaves(tp->tr_b.tb_left) + db_tree_nleaves(tp->tr_b.tb_right); default: bu_log("db_tree_nleaves: bad op %d\n", tp->tr_op); bu_bomb("db_tree_nleaves\n"); } return 0; /* for the compiler */ }
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 {
static int list_children(struct ged *gedp, struct directory *dp) { size_t i; struct rt_db_internal intern; struct rt_comb_internal *comb; if (!(dp->d_flags & RT_DIR_COMB)) return GED_OK; 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; if (comb->tree) { struct bu_vls vls = BU_VLS_INIT_ZERO; size_t node_count; size_t actual_count; struct rt_tree_array *rt_tree_array; if (db_ck_v4gift_tree(comb->tree) < 0) { db_non_union_push(comb->tree, &rt_uniresource); if (db_ck_v4gift_tree(comb->tree) < 0) { bu_vls_printf(gedp->ged_result_str, "Cannot flatten tree for listing"); return GED_ERROR; } } 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), "tree list"); actual_count = (struct rt_tree_array *)db_flatten_tree( rt_tree_array, comb->tree, OP_UNION, 1, &rt_uniresource) - rt_tree_array; BU_ASSERT_SIZE_T(actual_count, ==, node_count); comb->tree = TREE_NULL; } else {
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"); }
int ged_get_comb(struct ged *gedp, int argc, const char *argv[]) { struct directory *dp; struct rt_db_internal intern; struct rt_comb_internal *comb; struct rt_tree_array *rt_tree_array; size_t i; size_t node_count; size_t actual_count; static const char *usage = "comb"; 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 != 2) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } 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 is not a combination, so cannot be edited this way\n", 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, "Database read error, aborting\n"); return GED_ERROR; } comb = (struct rt_comb_internal *)intern.idb_ptr; if (comb->tree && db_ck_v4gift_tree(comb->tree) < 0) { db_non_union_push(comb->tree, &rt_uniresource); if (db_ck_v4gift_tree(comb->tree) < 0) { bu_vls_printf(gedp->ged_result_str, "Cannot flatten tree for editing\n"); return GED_ERROR; } } 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), "tree list"); actual_count = (struct rt_tree_array *)db_flatten_tree(rt_tree_array, comb->tree, OP_UNION, 1, &rt_uniresource) - rt_tree_array; BU_ASSERT_SIZE_T(actual_count, ==, node_count); comb->tree = TREE_NULL; } else {