Beispiel #1
0
/**
 * 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;
}