/* * The only reason for this to be broken out is that * 2 separate locations in db_functree() call it. */ void db_functree_subtree(struct db_i *dbip, union tree *tp, void (*comb_func) (struct db_i *, struct directory *, void *), void (*leaf_func) (struct db_i *, struct directory *, void *), struct resource *resp, void *client_data) { struct directory *dp; if (!tp) return; RT_CHECK_DBI(dbip); RT_CK_TREE(tp); if (resp) { RT_CK_RESOURCE(resp); } switch (tp->tr_op) { case OP_DB_LEAF: if ((dp=db_lookup(dbip, tp->tr_l.tl_name, LOOKUP_NOISY)) == RT_DIR_NULL) return; db_functree(dbip, dp, comb_func, leaf_func, resp, client_data); break; case OP_UNION: case OP_INTERSECT: case OP_SUBTRACT: case OP_XOR: db_functree_subtree(dbip, tp->tr_b.tb_left, comb_func, leaf_func, resp, client_data); db_functree_subtree(dbip, tp->tr_b.tb_right, comb_func, leaf_func, resp, client_data); break; default: bu_log("db_functree_subtree: unrecognized operator %d\n", tp->tr_op); bu_bomb("db_functree_subtree: unrecognized operator\n"); } }
/** * A generic traversal function. */ void db_traverse_subtree(union tree *tp, void (*traverse_func) (struct directory *, struct db_traverse *), struct db_traverse *dtp) { struct directory *dp; if (!tp) return; RT_CK_DB_TRAVERSE(dtp); RT_CHECK_DBI(dtp->dbip); RT_CK_TREE(tp); if (dtp->resp) { RT_CK_RESOURCE(dtp->resp); } switch (tp->tr_op) { case OP_DB_LEAF: if ((dp=db_lookup(dtp->dbip, tp->tr_l.tl_name, LOOKUP_NOISY)) == RT_DIR_NULL) return; traverse_func(dp, dtp); break; case OP_UNION: case OP_INTERSECT: case OP_SUBTRACT: case OP_XOR: db_traverse_subtree(tp->tr_b.tb_left, traverse_func, dtp); db_traverse_subtree(tp->tr_b.tb_right, traverse_func, dtp); break; default: bu_log("db_functree_subtree: unrecognized operator %d\n", tp->tr_op); bu_bomb("db_functree_subtree: unrecognized operator\n"); } }
int ged_redraw(struct ged *gedp, int argc, const char *argv[]) { int ret; struct display_list *gdlp; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_DRAWABLE(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); RT_CHECK_DBI(gedp->ged_wdbp->dbip); bu_vls_trunc(gedp->ged_result_str, 0); if (argc == 1) { /* redraw everything */ for (BU_LIST_FOR(gdlp, display_list, gedp->ged_gdp->gd_headDisplay)) { ret = dl_redraw(gdlp, gedp->ged_wdbp->dbip, &gedp->ged_wdbp->wdb_initial_tree_state, gedp->ged_gvp, gedp->ged_create_vlist_callback); if (ret < 0) { bu_vls_printf(gedp->ged_result_str, "%s: redraw failure\n", argv[0]); return GED_ERROR; } } } else {
/* * This routine is the drawable geometry object's analog of rt_gettrees(). * Add a set of tree hierarchies to the active set. * Note that argv[0] should be ignored, it has the command name in it. * * Returns - * 0 Ordinarily * -1 On major error */ int _ged_drawtrees(struct ged *gedp, int argc, const char *argv[], int kind, struct _ged_client_data *_dgcdp) { int ret = 0; int c; int ncpu = 1; int nmg_use_tnurbs = 0; int enable_fastpath = 0; struct model *nmg_model; struct _ged_client_data dgcdp; int i; int ac = 1; char *av[3]; RT_CHECK_DBI(gedp->ged_wdbp->dbip); if (argc <= 0) return -1; /* FAIL */ ++drawtrees_depth; av[1] = (char *)0; /* options are already parsed into _dgcdp */ if (_dgcdp != (struct _ged_client_data *)0) { dgcdp = *_dgcdp; /* struct copy */ } else { struct bview *gvp; memset(&dgcdp, 0, sizeof(struct _ged_client_data)); dgcdp.gedp = gedp; gvp = gedp->ged_gvp; if (gvp && gvp->gv_adaptive_plot) dgcdp.autoview = 1; else dgcdp.autoview = 0; /* Initial values for options, must be reset each time */ dgcdp.draw_nmg_only = 0; /* no booleans */ dgcdp.nmg_triangulate = 1; dgcdp.draw_wireframes = 0; dgcdp.draw_normals = 0; dgcdp.draw_solid_lines_only = 0; dgcdp.draw_no_surfaces = 0; dgcdp.shade_per_vertex_normals = 0; dgcdp.draw_edge_uses = 0; dgcdp.wireframe_color_override = 0; dgcdp.fastpath_count = 0; dgcdp.shaded_mode_override = _GED_SHADED_MODE_UNSET; /* default color - red */ dgcdp.wireframe_color[0] = 255; dgcdp.wireframe_color[1] = 0; dgcdp.wireframe_color[2] = 0; /* default transparency - opaque */ dgcdp.transparency = 1.0; /* freesolid */ dgcdp.freesolid = gedp->freesolid; enable_fastpath = 0; /* Parse options. */ bu_optind = 0; /* re-init bu_getopt() */ while ((c = bu_getopt(argc, (char * const *)argv, "dfhm:nqstuvwx:C:STP:A:oR")) != -1) { switch (c) { case 'u': dgcdp.draw_edge_uses = 1; break; case 's': dgcdp.draw_solid_lines_only = 1; break; case 't': nmg_use_tnurbs = 1; break; case 'v': dgcdp.shade_per_vertex_normals = 1; break; case 'w': dgcdp.draw_wireframes = 1; break; case 'S': dgcdp.draw_no_surfaces = 1; break; case 'T': dgcdp.nmg_triangulate = 0; break; case 'n': dgcdp.draw_normals = 1; break; case 'P': ncpu = atoi(bu_optarg); break; case 'q': dgcdp.do_not_draw_nmg_solids_during_debugging = 1; break; case 'd': dgcdp.draw_nmg_only = 1; break; case 'f': enable_fastpath = 1; break; case 'C': { int r, g, b; char *cp = bu_optarg; r = atoi(cp); while ((*cp >= '0' && *cp <= '9')) cp++; while (*cp && (*cp < '0' || *cp > '9')) cp++; g = atoi(cp); while ((*cp >= '0' && *cp <= '9')) cp++; while (*cp && (*cp < '0' || *cp > '9')) cp++; b = atoi(cp); if (r < 0 || r > 255) r = 255; if (g < 0 || g > 255) g = 255; if (b < 0 || b > 255) b = 255; dgcdp.wireframe_color_override = 1; dgcdp.wireframe_color[0] = r; dgcdp.wireframe_color[1] = g; dgcdp.wireframe_color[2] = b; } break; case 'h': dgcdp.hiddenLine = 1; dgcdp.shaded_mode_override = _GED_SHADED_MODE_ALL; break; case 'm': dgcdp.shaded_mode_override = atoi(bu_optarg); switch (dgcdp.shaded_mode_override) { case 0: dgcdp.shaded_mode_override = _GED_WIREFRAME; break; case 1: dgcdp.shaded_mode_override = _GED_SHADED_MODE_BOTS; break; case 2: dgcdp.shaded_mode_override = _GED_SHADED_MODE_ALL; break; case 3: dgcdp.shaded_mode_override = _GED_SHADED_MODE_EVAL; break; default: if (dgcdp.shaded_mode_override < 0) { dgcdp.shaded_mode_override = _GED_SHADED_MODE_UNSET; } else { dgcdp.shaded_mode_override = _GED_SHADED_MODE_ALL; } } break; case 'x': dgcdp.transparency = atof(bu_optarg); /* clamp it to [0, 1] */ if (dgcdp.transparency < 0.0) dgcdp.transparency = 0.0; if (1.0 < dgcdp.transparency) dgcdp.transparency = 1.0; break; case 'R': dgcdp.autoview = 0; break; case 'A': case 'o': /* nothing to do, handled by edit_com wrapper on the front-end */ break; default: { bu_vls_printf(gedp->ged_result_str, "unrecognized option - %c\n", c); --drawtrees_depth; return GED_ERROR; } } } argc -= bu_optind; argv += bu_optind; switch (kind) { case _GED_DRAW_WIREFRAME: dgcdp.dmode = _GED_WIREFRAME; if (dgcdp.shaded_mode_override != _GED_SHADED_MODE_UNSET) { dgcdp.dmode = dgcdp.shaded_mode_override; } else if (gedp->ged_gdp->gd_shaded_mode) { dgcdp.dmode = gedp->ged_gdp->gd_shaded_mode; } break; case _GED_DRAW_NMG_POLY: dgcdp.dmode = _GED_BOOL_EVAL; break; } } if (!argc) { bu_vls_printf(gedp->ged_result_str, "Please specify one or more objects to be drawn.\n"); --drawtrees_depth; return -1; } switch (kind) { default: bu_vls_printf(gedp->ged_result_str, "ERROR, bad kind\n"); --drawtrees_depth; return -1; case _GED_DRAW_WIREFRAME: /* * If asking for wireframe and in shaded_mode and no shaded mode override, * or asking for wireframe and shaded mode is being overridden with a value * greater than 0, then draw shaded polygons for each object's primitives if possible. * * Note - * If shaded_mode is _GED_SHADED_MODE_BOTS, only BOTS and polysolids * will be shaded. The rest is drawn as wireframe. * If shaded_mode is _GED_SHADED_MODE_ALL, everything except pipe solids * are drawn as shaded polygons. */ if (dgcdp.dmode == _GED_SHADED_MODE_BOTS || dgcdp.dmode == _GED_SHADED_MODE_ALL || dgcdp.dmode == _GED_SHADED_MODE_EVAL) { struct _ged_client_data dgcdp_save; for (i = 0; i < argc; ++i) { if (drawtrees_depth == 1) dgcdp.gdlp = dl_addToDisplay(gedp->ged_gdp->gd_headDisplay, gedp->ged_wdbp->dbip, argv[i]); if (dgcdp.gdlp == GED_DISPLAY_LIST_NULL) continue; dgcdp_save = dgcdp; if (dgcdp.dmode == _GED_SHADED_MODE_EVAL) { ret = plot_shaded_eval(gedp, argv[i], &dgcdp); if (ret == GED_OK) { continue; } /* if evaluated shading failed, fall back to "all" mode */ dgcdp.gedp->ged_gdp->gd_shaded_mode = 0; dgcdp.shaded_mode_override = _GED_SHADED_MODE_ALL; dgcdp.dmode = _GED_SHADED_MODE_ALL; } av[0] = (char *)argv[i]; ret = db_walk_tree(gedp->ged_wdbp->dbip, ac, (const char **)av, ncpu, &gedp->ged_wdbp->wdb_initial_tree_state, NULL, draw_check_region_end, draw_check_leaf, (void *)&dgcdp); dgcdp = dgcdp_save; } } else { struct display_list **paths_to_draw; struct display_list *gdlp; paths_to_draw = (struct display_list **) bu_malloc(sizeof(struct display_list *) * argc, "redraw paths"); /* create solids */ for (i = 0; i < argc; ++i) { struct bview_client_data bview_data; bview_data.draw_solid_lines_only = dgcdp.draw_solid_lines_only; bview_data.wireframe_color_override = dgcdp.wireframe_color_override; bview_data.wireframe_color[0]= dgcdp.wireframe_color[0]; bview_data.wireframe_color[1]= dgcdp.wireframe_color[1]; bview_data.wireframe_color[2]= dgcdp.wireframe_color[2]; bview_data.transparency= dgcdp.transparency; bview_data.dmode = dgcdp.dmode; bview_data.hiddenLine = dgcdp.hiddenLine; bview_data.freesolid = (void *)gedp->freesolid; dgcdp.gdlp = dl_addToDisplay(gedp->ged_gdp->gd_headDisplay, gedp->ged_wdbp->dbip, argv[i]); bview_data.gdlp = dgcdp.gdlp; /* store draw path */ paths_to_draw[i] = dgcdp.gdlp; if (dgcdp.gdlp == GED_DISPLAY_LIST_NULL) { continue; } av[0] = (char *)argv[i]; ret = db_walk_tree(gedp->ged_wdbp->dbip, ac, (const char **)av, ncpu, &gedp->ged_wdbp->wdb_initial_tree_state, NULL, wireframe_region_end, append_solid_to_display_list, (void *)&bview_data); } /* We need to know the view size in order to choose * appropriate input values for the adaptive plot * routines. Unless we're keeping the current view, * we need to autoview now so we have the correct * view size for plotting. */ if (dgcdp.autoview) { const char *autoview_args[2] = {"autoview", NULL}; ged_autoview(gedp, 1, autoview_args); } /* calculate plot vlists for solids of each draw path */ for (i = 0; i < argc; ++i) { gdlp = paths_to_draw[i]; if (gdlp == GED_DISPLAY_LIST_NULL) { continue; } ret = dl_redraw(gdlp, gedp->ged_wdbp->dbip, &gedp->ged_wdbp->wdb_initial_tree_state, gedp->ged_gvp, gedp->ged_create_vlist_callback); if (ret < 0) { bu_vls_printf(gedp->ged_result_str, "%s: %s redraw failure\n", argv[0], argv[i]); return GED_ERROR; } } bu_free(paths_to_draw, "draw paths"); } break; case _GED_DRAW_NMG_POLY: { nmg_model = nmg_mm(); gedp->ged_wdbp->wdb_initial_tree_state.ts_m = &nmg_model; if (dgcdp.draw_edge_uses) { bu_vls_printf(gedp->ged_result_str, "Doing the edgeuse thang (-u)\n"); dgcdp.draw_edge_uses_vbp = rt_vlblock_init(); } for (i = 0; i < argc; ++i) { if (drawtrees_depth == 1) dgcdp.gdlp = dl_addToDisplay(gedp->ged_gdp->gd_headDisplay, gedp->ged_wdbp->dbip, argv[i]); if (dgcdp.gdlp == GED_DISPLAY_LIST_NULL) continue; av[0] = (char *)argv[i]; ret = db_walk_tree(gedp->ged_wdbp->dbip, ac, (const char **)av, ncpu, &gedp->ged_wdbp->wdb_initial_tree_state, enable_fastpath ? draw_nmg_region_start : 0, draw_nmg_region_end, nmg_use_tnurbs ? nmg_booltree_leaf_tnurb : nmg_booltree_leaf_tess, (void *)&dgcdp); } if (dgcdp.draw_edge_uses) { _ged_cvt_vlblock_to_solids(gedp, dgcdp.draw_edge_uses_vbp, "_EDGEUSES_", 0); bn_vlblock_free(dgcdp.draw_edge_uses_vbp); dgcdp.draw_edge_uses_vbp = (struct bn_vlblock *)NULL; } /* Destroy NMG */ nmg_km(nmg_model); break; } } --drawtrees_depth; if (dgcdp.fastpath_count) { bu_log("%d region%s rendered through polygon fastpath\n", dgcdp.fastpath_count, dgcdp.fastpath_count == 1 ? "" : "s"); } if (ret < 0) return -1; return 0; /* OK */ }
void pop_gop(int gop, char *parent1_id, char *parent2_id, char *child1_id, char *child2_id, struct db_i *dbi_p, struct db_i *dbi_c, struct resource *resp) { struct rt_db_internal in1, in2; struct rt_comb_internal *parent1; struct rt_comb_internal *parent2; struct directory *dp; union tree *cpoint, **cross_parent; struct node *add; int i = 0; struct node *chosen_node; int rand_node; RT_CHECK_DBI( dbi_p ); RT_CHECK_DBI( dbi_c ); RT_CK_RESOURCE( resp ); crossover_point = (union tree *)NULL; crossover_parent = (union tree **)NULL; node = (struct node*)NULL; if ( !rt_db_lookup_internal(dbi_p, parent1_id, &dp, &in1, LOOKUP_NOISY, &rt_uniresource)) bu_exit(EXIT_FAILURE, "Failed to read parent1"); shape_number =num_nodes= 0; parent1 = (struct rt_comb_internal *)in1.idb_ptr; mutate = 0; switch (gop) { case REPRODUCE: pop_functree(dbi_p, dbi_c, parent1->tree, resp, child1_id); break; case CROSSOVER: crossover = 1; /*load other parent */ if ( !rt_db_lookup_internal(dbi_p, parent2_id, &dp, &in2, LOOKUP_NOISY, resp)) bu_exit(EXIT_FAILURE, "Failed to read parent2"); parent2 = (struct rt_comb_internal *)in2.idb_ptr; BU_ALLOC(node, struct node); BU_LIST_INIT(&node->l); chosen_node = NULL; do{ num_nodes = 0; crossover_parent = &parent1->tree; crossover_node = (int)(pop_rand() * db_count_tree_nodes(parent1->tree, 0)); node_idx = 0; pop_functree(dbi_p, dbi_c, parent1->tree, resp, NULL); cross_parent = crossover_parent; cpoint = crossover_point; crossover_op = crossover_point->tr_op; #define MASK (OP_UNION | OP_XOR | OP_SUBTRACT|OP_INTERSECT) if (crossover_op & MASK)crossover_op = MASK; crossover_node = db_count_tree_nodes(crossover_point, 0); if (pop_find_nodes(parent2->tree) == crossover_node) { BU_ALLOC(add, struct node); add->s_parent = &parent2->tree; add->s_child = parent2->tree; BU_LIST_INSERT(&node->l, &add->l); ++num_nodes; } if (num_nodes > 0) { rand_node = (int)(pop_rand() * num_nodes); for (add=BU_LIST_FIRST(node, &node->l);BU_LIST_NOT_HEAD(add, &node->l) && chosen_node == NULL; add=BU_LIST_PNEXT(node, add)) { if (i++ == rand_node) { chosen_node = add; /* break cleanly...? */ } } } }while(chosen_node == NULL); /* cross trees */ *cross_parent = chosen_node->s_child; *chosen_node->s_parent =cpoint; while (BU_LIST_WHILE(add, node, &node->l)) { BU_LIST_DEQUEUE(&add->l); bu_free(add, "node"); } bu_free(node, "node"); crossover = 0; /*duplicate shapes held in trees*/ pop_functree(dbi_p, dbi_c, parent1->tree, resp, child1_id); shape_number = 0; pop_functree(dbi_p, dbi_c, parent2->tree, resp, child2_id); if ((dp = db_diradd(dbi_c, child2_id, -1, 0, dp->d_flags, (genptr_t)&dp->d_minor_type)) == RT_DIR_NULL) bu_exit(EXIT_FAILURE, "Failed to add new individual to child database"); if (rt_db_put_internal(dp, dbi_c, &in2, resp) < 0) bu_exit(EXIT_FAILURE, "Database write failure"); rt_db_free_internal(&in2); break; case MUTATE: crossover_parent = &parent1->tree; crossover_node = (int)(pop_rand() * db_count_tree_nodes(parent1->tree, 0)); node_idx = 0; mutate = 1; pop_functree(dbi_p, dbi_c, parent1->tree, resp, child1_id); mutate = 0; break; /* //random node to mutate n = (int)(pop_rand() * db_count_tree_nodes(parent1->tree, 0)); s_parent = &parent1->tree; s_node = n; node = 0; //find node pop_functree(dbi_p, dbi_c, parent1->tree, resp, NULL); */ default: bu_exit(EXIT_FAILURE, "illegal genetic operator\nfailed to execute genetic op"); } if ((dp=db_diradd(dbi_c, child1_id, -1, 0, dp->d_flags, (genptr_t)&dp->d_minor_type)) == RT_DIR_NULL) { bu_exit(EXIT_FAILURE, "Failed to add new individual to child database"); } if (rt_db_put_internal(dp, dbi_c, &in1, resp) < 0) bu_exit(EXIT_FAILURE, "Database write failure"); rt_db_free_internal(&in1); }
int ged_facetize(struct ged *gedp, int argc, const char *argv[]) { int i; int c; char *newname; struct rt_db_internal intern; struct directory *dp; int failed; int nmg_use_tnurbs = 0; struct db_tree_state init_state; struct db_i *dbip; union tree *facetize_tree; struct model *nmg_model; static const char *usage = "[ [-P] | [-n] [-t] [-T] ] new_obj old_obj [old_obj2 old_obj3 ...]"; /* static due to jumping */ static int triangulate; static int make_bot; static int marching_cube; static int screened_poisson; 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; } dbip = gedp->ged_wdbp->dbip; RT_CHECK_DBI(dbip); db_init_db_tree_state(&init_state, dbip, gedp->ged_wdbp->wdb_resp); /* Establish tolerances */ init_state.ts_ttol = &gedp->ged_wdbp->wdb_ttol; init_state.ts_tol = &gedp->ged_wdbp->wdb_tol; /* Initial values for options, must be reset each time */ marching_cube = 0; screened_poisson = 0; triangulate = 0; make_bot = 1; /* Parse options. */ bu_optind = 1; /* re-init bu_getopt() */ while ((c=bu_getopt(argc, (char * const *)argv, "mntTP")) != -1) { switch (c) { case 'm': marching_cube = triangulate = 1; /* no break, marching cubes assumes nmg for now */ case 'n': make_bot = 0; break; case 'P': screened_poisson = 1; triangulate = 1; make_bot = 1; break; case 'T': triangulate = 1; break; case 't': nmg_use_tnurbs = 1; break; default: { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } } } argc -= bu_optind; argv += bu_optind; if (argc < 0) { bu_vls_printf(gedp->ged_result_str, "facetize: missing argument\n"); return GED_ERROR; } if (screened_poisson && (marching_cube || !make_bot || nmg_use_tnurbs)) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } newname = (char *)argv[0]; argv++; argc--; if (argc < 0) { bu_vls_printf(gedp->ged_result_str, "facetize: missing argument\n"); return GED_ERROR; } if (db_lookup(dbip, newname, LOOKUP_QUIET) != RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "error: solid '%s' already exists, aborting\n", newname); return GED_ERROR; } if (screened_poisson) { struct rt_bot_internal *bot; BU_ALLOC(bot, struct rt_bot_internal); bot->magic = RT_BOT_INTERNAL_MAGIC; bot->mode = RT_BOT_SOLID; bot->orientation = RT_BOT_UNORIENTED; bot->thickness = (fastf_t *)NULL; bot->face_mode = (struct bu_bitv *)NULL; /* TODO - generate point cloud, then mesh - need to see the input points for debugging */ (void)rt_generate_mesh(&(bot->faces), (int *)&(bot->num_faces), (point_t **)&(bot->vertices), (int *)&(bot->num_vertices), dbip, argv[0], 15); /* Export BOT as a new solid */ RT_DB_INTERNAL_INIT(&intern); intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; intern.idb_type = ID_BOT; intern.idb_meth = &OBJ[ID_BOT]; intern.idb_ptr = (void *) bot; } else { bu_vls_printf(gedp->ged_result_str, "facetize: tessellating primitives with tolerances a=%g, r=%g, n=%g\n", gedp->ged_wdbp->wdb_ttol.abs, gedp->ged_wdbp->wdb_ttol.rel, gedp->ged_wdbp->wdb_ttol.norm); facetize_tree = (union tree *)0; nmg_model = nmg_mm(); init_state.ts_m = &nmg_model; i = db_walk_tree(dbip, argc, (const char **)argv, 1, &init_state, 0, /* take all regions */ facetize_region_end, nmg_use_tnurbs ? nmg_booltree_leaf_tnurb : nmg_booltree_leaf_tess, (void *)&facetize_tree ); if (i < 0) { bu_vls_printf(gedp->ged_result_str, "facetize: error in db_walk_tree()\n"); /* Destroy NMG */ nmg_km(nmg_model); return GED_ERROR; } if (facetize_tree) { /* Now, evaluate the boolean tree into ONE region */ bu_vls_printf(gedp->ged_result_str, "facetize: evaluating boolean expressions\n"); if (!BU_SETJUMP) { /* try */ failed = nmg_boolean(facetize_tree, nmg_model, &gedp->ged_wdbp->wdb_tol, &rt_uniresource); } else { /* catch */ BU_UNSETJUMP; bu_vls_printf(gedp->ged_result_str, "WARNING: facetization failed!!!\n"); db_free_tree(facetize_tree, &rt_uniresource); facetize_tree = (union tree *)NULL; nmg_km(nmg_model); nmg_model = (struct model *)NULL; return GED_ERROR; } BU_UNSETJUMP; } else failed = 1; if (failed) { bu_vls_printf(gedp->ged_result_str, "facetize: no resulting region, aborting\n"); db_free_tree(facetize_tree, &rt_uniresource); facetize_tree = (union tree *)NULL; nmg_km(nmg_model); nmg_model = (struct model *)NULL; return GED_ERROR; } /* New region remains part of this nmg "model" */ NMG_CK_REGION(facetize_tree->tr_d.td_r); bu_vls_printf(gedp->ged_result_str, "facetize: %s\n", facetize_tree->tr_d.td_name); /* Triangulate model, if requested */ if (triangulate && !make_bot) { bu_vls_printf(gedp->ged_result_str, "facetize: triangulating resulting object\n"); if (!BU_SETJUMP) { /* try */ if (marching_cube == 1) nmg_triangulate_model_mc(nmg_model, &gedp->ged_wdbp->wdb_tol); else nmg_triangulate_model(nmg_model, &gedp->ged_wdbp->wdb_tol); } else { /* catch */ BU_UNSETJUMP; bu_vls_printf(gedp->ged_result_str, "WARNING: triangulation failed!!!\n"); db_free_tree(facetize_tree, &rt_uniresource); facetize_tree = (union tree *)NULL; nmg_km(nmg_model); nmg_model = (struct model *)NULL; return GED_ERROR; } BU_UNSETJUMP; } if (make_bot) { struct rt_bot_internal *bot; struct nmgregion *r; struct shell *s; bu_vls_printf(gedp->ged_result_str, "facetize: converting to BOT format\n"); /* WTF, FIXME: this is only dumping the first shell of the first region */ r = BU_LIST_FIRST(nmgregion, &nmg_model->r_hd); if (r && BU_LIST_NEXT(nmgregion, &r->l) != (struct nmgregion *)&nmg_model->r_hd) bu_vls_printf(gedp->ged_result_str, "WARNING: model has more than one region, only facetizing the first\n"); s = BU_LIST_FIRST(shell, &r->s_hd); if (s && BU_LIST_NEXT(shell, &s->l) != (struct shell *)&r->s_hd) bu_vls_printf(gedp->ged_result_str, "WARNING: model has more than one shell, only facetizing the first\n"); if (!BU_SETJUMP) { /* try */ bot = (struct rt_bot_internal *)nmg_bot(s, &gedp->ged_wdbp->wdb_tol); } else { /* catch */ BU_UNSETJUMP; bu_vls_printf(gedp->ged_result_str, "WARNING: conversion to BOT failed!\n"); db_free_tree(facetize_tree, &rt_uniresource); facetize_tree = (union tree *)NULL; nmg_km(nmg_model); nmg_model = (struct model *)NULL; return GED_ERROR; } BU_UNSETJUMP; nmg_km(nmg_model); nmg_model = (struct model *)NULL; /* Export BOT as a new solid */ RT_DB_INTERNAL_INIT(&intern); intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; intern.idb_type = ID_BOT; intern.idb_meth = &OBJ[ID_BOT]; intern.idb_ptr = (void *) bot; } else { bu_vls_printf(gedp->ged_result_str, "facetize: converting NMG to database format\n"); /* Export NMG as a new solid */ RT_DB_INTERNAL_INIT(&intern); intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; intern.idb_type = ID_NMG; intern.idb_meth = &OBJ[ID_NMG]; intern.idb_ptr = (void *)nmg_model; nmg_model = (struct model *)NULL; } } dp=db_diradd(dbip, newname, RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&intern.idb_type); if (dp == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "Cannot add %s to directory\n", newname); return GED_ERROR; } if (rt_db_put_internal(dp, dbip, &intern, &rt_uniresource) < 0) { bu_vls_printf(gedp->ged_result_str, "Failed to write %s to database\n", newname); rt_db_free_internal(&intern); return GED_ERROR; } if (!screened_poisson) { facetize_tree->tr_d.td_r = (struct nmgregion *)NULL; /* Free boolean tree, and the regions in it */ db_free_tree(facetize_tree, &rt_uniresource); facetize_tree = (union tree *)NULL; } return GED_OK; }