/** * R T _ F R E E _ S O L T A B * * Decrement use count on soltab structure. If no longer needed, * release associated storage, and free the structure. * * This routine semaphore protects against other copies of itself * running in parallel, and against other routines (such as * rt_find_identical_solid()) which might also be modifying the linked * list heads. * * Called by - * db_free_tree() * rt_clean() * rt_gettrees() * rt_kill_deal_solid_refs() */ void rt_free_soltab(struct soltab *stp) { int hash; RT_CK_SOLTAB(stp); if ( stp->st_id < 0 ) bu_bomb("rt_free_soltab: bad st_id"); hash = db_dirhash(stp->st_dp->d_namep); ACQUIRE_SEMAPHORE_TREE(hash); /* start critical section */ if ( --(stp->st_uses) > 0 ) { RELEASE_SEMAPHORE_TREE(hash); return; } BU_LIST_DEQUEUE( &(stp->l2) ); /* remove from st_dp->d_use_hd list */ BU_LIST_DEQUEUE( &(stp->l) ); /* uses rti_solidheads[] */ RELEASE_SEMAPHORE_TREE(hash); /* end critical section */ if ( stp->st_aradius > 0 ) { stp->st_meth->ft_free( stp ); stp->st_aradius = 0; } if ( stp->st_matp ) bu_free( (char *)stp->st_matp, "st_matp"); stp->st_matp = (matp_t)0; /* Sanity */ bu_ptbl_free(&stp->st_regions); stp->st_dp = DIR_NULL; /* Sanity */ if ( stp->st_path.magic ) { RT_CK_FULL_PATH( &stp->st_path ); db_free_full_path( &stp->st_path ); } bu_free( (char *)stp, "struct soltab" ); }
/** * 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 */ }
static int plot_shaded_eval( struct ged *gedp, const char *path_name, struct _ged_client_data *dgcdp) { int ret; const char *av[3]; const char *tmp_basename = "tmp_shaded_eval_obj"; char *brep_name; /* make a name for the temp brep */ av[0] = "make_name"; av[1] = tmp_basename; ged_make_name(gedp, 2, (const char **)av); brep_name = bu_vls_strdup(gedp->ged_result_str); bu_vls_trunc(gedp->ged_result_str, 0); /* create temp evaluated brep from named object */ av[0] = "brep"; av[1] = path_name; av[2] = brep_name; ret = ged_brep(gedp, 3, av); if (ret == GED_OK) { int brep_made = 0; struct db_tree_state ts; struct rt_db_internal brep_intern; struct db_full_path input_path, brep_path; RT_DB_INTERNAL_INIT(&brep_intern); db_full_path_init(&input_path); db_full_path_init(&brep_path); /* get brep internal */ ret = get_path_and_state(&ts, &brep_path, brep_name, gedp); if (ret == GED_OK) { struct directory *dp = DB_FULL_PATH_CUR_DIR(&brep_path); if (dp->d_flags & RT_DIR_COMB) { ret = rt_db_get_internal(&brep_intern, dp, ts.ts_dbip, NULL, ts.ts_resp); } else { ret = rt_db_get_internal(&brep_intern, dp, ts.ts_dbip, ts.ts_mat, ts.ts_resp); } if (ret >= 0) { brep_made = 1; } db_free_full_path(&brep_path); } /* plot brep, but use the path and state of the input object */ if (brep_made) { ret = get_path_and_state(&ts, &input_path, path_name, gedp); if (ret == GED_OK) { plot_shaded(&ts, &input_path, &brep_intern, dgcdp); rt_db_free_internal(&brep_intern); db_free_full_path(&input_path); } } /* kill temp brep */ av[0] = "kill"; av[1] = brep_name; ged_kill(gedp, 2, av); } bu_free((char *)brep_name, "vls_strdup"); return ret; }