Пример #1
0
int
ged_find_botpt_nearest_pt(struct ged *gedp, int argc, const char *argv[])
{
    static const char *usage = "bot view_xyz";
    struct rt_db_internal intern;
    struct rt_bot_internal *botip;
    mat_t mat;
    int nearest_pt;
    vect_t view;

    /* must be double for scanf */
    double scan[ELEMENTS_PER_VECT];

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_VIEW(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;
    }

    if (bu_sscanf(argv[2], "%lf %lf %lf", &scan[X], &scan[Y], &scan[Z]) != 3) {
	bu_vls_printf(gedp->ged_result_str, "%s: bad view location - %s", argv[0], argv[2]);
	return GED_ERROR;
    }

    if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], gedp->ged_wdbp, mat) == GED_ERROR) {
	bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
	return GED_ERROR;
    }

    if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
	intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
	bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
	rt_db_free_internal(&intern);

	return GED_ERROR;
    }

    botip = (struct rt_bot_internal *)intern.idb_ptr;
    VMOVE(view, scan); /* convert double to fastf_t */

    nearest_pt = rt_bot_find_v_nearest_pt2(botip, view, gedp->ged_gvp->gv_model2view);
    bu_vls_printf(gedp->ged_result_str, "%d", nearest_pt);

    rt_db_free_internal(&intern);
    return GED_OK;
}
Пример #2
0
/* A "wrapping" combination is a combination that contains a single object
 * and does not apply a matrix to it */
int
Comb_Is_Wrapper(struct directory *dp, struct rt_wdb *wdbp)
{
    struct rt_db_internal comb_intern;
    struct rt_db_internal comb_child_intern;
    struct rt_comb_internal *comb;
    union tree *child;
    struct directory *child_dp;
    int node_count = 0;

    rt_db_get_internal(&comb_intern, dp, wdbp->dbip, bn_mat_identity, &rt_uniresource);
    RT_CK_DB_INTERNAL(&comb_intern);
    if (comb_intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_COMBINATION) {
	rt_db_free_internal(&comb_intern);
	return -1;
    }

    /* If this comb has more than one child, it isn't a wrapper */
    comb = (struct rt_comb_internal *)comb_intern.idb_ptr;
    if (comb->tree) {
	node_count = db_count_tree_nodes(comb->tree, 0);
	if (node_count > 1) {
	    rt_db_free_internal(&comb_intern);
	    return 1;
	}
    } else {
	/* Empty comb */
	return -2;
    }

    /* If the child doesn't exist, this isn't a wrapper */
    child = _db_tree_get_child(comb->tree);
    child_dp = db_lookup(wdbp->dbip, child->tr_l.tl_name, LOOKUP_QUIET);
    if (child_dp == RT_DIR_NULL) {
	rt_db_free_internal(&comb_intern);
	return 1;
    }

    /* If the child is a comb, this isn't a wrapper */
    rt_db_get_internal(&comb_child_intern, child_dp, wdbp->dbip, bn_mat_identity, &rt_uniresource);
    RT_CK_DB_INTERNAL(&comb_child_intern);
    if (comb_child_intern.idb_minor_type == DB5_MINORTYPE_BRLCAD_COMBINATION) {
	rt_db_free_internal(&comb_intern);
	rt_db_free_internal(&comb_child_intern);
	return 1;
    }

    /* If the child has a matrix over it, this isn't a wrapper */
    if (child->tr_l.tl_mat) {
	rt_db_free_internal(&comb_intern);
	rt_db_free_internal(&comb_child_intern);
	return 1;
    }

    /* If we made it here, we have a wrapper */
    rt_db_free_internal(&comb_intern);
    rt_db_free_internal(&comb_child_intern);
    return 0;
}
Пример #3
0
int
ged_get_bot_edges(struct ged *gedp, int argc, const char *argv[])
{
    static const char *usage = "bot";
    struct rt_db_internal intern;
    struct rt_bot_internal *botip;
    mat_t mat;
    size_t edge_count;
    size_t *edge_list;

    GED_CHECK_DATABASE_OPEN(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;
    }

    if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], gedp->ged_wdbp, mat) == GED_ERROR) {
	bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
	return GED_ERROR;
    }

    if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
	intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
	bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
	rt_db_free_internal(&intern);

	return GED_ERROR;
    }

    botip = (struct rt_bot_internal *)intern.idb_ptr;
    if ((edge_count = rt_bot_get_edge_list(botip, &edge_list)) > 0) {
	size_t i;

	for (i = 0; i < edge_count; i++)
	    bu_vls_printf(gedp->ged_result_str, "{%zu %zu} ", edge_list[i*2], edge_list[i*2+1]);

	bu_free(edge_list, "bot edge list");
    }

    rt_db_free_internal(&intern);
    return GED_OK;
}
Пример #4
0
void
csg_leaf_func(struct db_i *dbip, struct directory *dp, void *UNUSED(ptr))
{
    struct rt_db_internal ip;

    /* if this solid has already been output, don't do it again */
    if (dp->d_uses < 0)
	return;

    if (verbose)
	bu_log("solid - %s\n", dp->d_namep);

    if (rt_db_get_internal(&ip, dp, dbip, (fastf_t *)NULL, &rt_uniresource) < 0)
	bu_log("Error in import");

    solid_is_brep = 0;
    dp->d_uses = (-iges_write[ip.idb_type].do_iges_write(&ip, dp->d_namep, fp_dir, fp_param));

    if (!dp->d_uses) {
	bu_log("g-iges: failed to translate %s to IGES format\n", dp->d_namep);
	solid_error++;
    }

    if (solid_is_brep)
	dp->d_nref = 1;
    else
	dp->d_nref = 0;

    rt_db_free_internal(&ip);
}
/* return 0 when IS a light or an error occurred. regions are skipped
 * when this function returns 0.
 */
static int
select_non_lights(struct db_tree_state *UNUSED(tsp), const struct db_full_path *pathp, const struct rt_comb_internal *UNUSED(combp), void *UNUSED(client_data))
{
    struct directory *dp;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    int id;

    RT_CK_FULL_PATH(pathp);
    dp = DB_FULL_PATH_CUR_DIR(pathp);

    id = rt_db_get_internal(&intern, dp, dbip, (matp_t)NULL, &rt_uniresource);
    if (id < 0) {
	/* error occurred retrieving object */
	bu_log("Warning: Can not load internal form of %s\n", dp->d_namep);
	return 0;
    }

    if ((dp->d_flags & RT_DIR_COMB) && (id == ID_COMBINATION)) {
	comb = (struct rt_comb_internal *)intern.idb_ptr;
	RT_CK_COMB(comb);
	if (BU_STR_EQUAL(bu_vls_addr(&comb->shader), "light")) {
	    rt_db_free_internal(&intern);
	    return 0;
	}
    }

    return 1;
}
Пример #6
0
int
rt_db_get_internal(
    struct rt_db_internal *ip,
    const struct directory *dp,
    const struct db_i *dbip,
    const mat_t mat,
    struct resource *resp)
{
    struct bu_external ext;
    int id;
    int ret;

    RT_DB_INTERNAL_INIT(ip);

    if (dbip->dbi_version > 4)
	return rt_db_get_internal5(ip, dp, dbip, mat, resp);

    BU_EXTERNAL_INIT(&ext);

    if (db_get_external(&ext, dp, dbip) < 0)
	return -2;		/* FAIL */

    if (dp->d_flags & RT_DIR_COMB) {
	id = ID_COMBINATION;
    } else {
	/* As a convenience to older ft_import4 routines */
	if (mat == NULL) mat = bn_mat_identity;
	id = rt_id_solid(&ext);
    }

    /* ip is already initialized and should not be re-initialized */
    ret = -1;
    if (OBJ[id].ft_import4) {
	ret = OBJ[id].ft_import4(ip, &ext, mat, dbip, resp);
    }
    if (ret < 0) {
	bu_log("rt_db_get_internal(%s):  import failure\n",
	       dp->d_namep);
	rt_db_free_internal(ip);
	bu_free_external(&ext);
	return -1;		/* FAIL */
    }
    bu_free_external(&ext);
    RT_CK_DB_INTERNAL(ip);
    ip->idb_meth = &OBJ[id];

    /* prior to version 5, there are no attributes ... */
    bu_avs_init_empty(&ip->idb_avs);

    /* ... but this isn't the whole story: */
    if (id == ID_COMBINATION) {
	const struct rt_comb_internal *comb = (const struct rt_comb_internal *)ip->idb_ptr;
	RT_CK_COMB(comb);

	db5_sync_comb_to_attr(&ip->idb_avs, comb);
    }

    return id;			/* OK */
}
Пример #7
0
static int
select_lights(struct db_tree_state *UNUSED(tsp), const struct db_full_path *pathp, const struct rt_comb_internal *UNUSED(combp), void *UNUSED(client_data))
{
    struct directory *dp;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    int id;

    RT_CK_FULL_PATH( pathp );
    dp = DB_FULL_PATH_CUR_DIR( pathp );

    if ( !(dp->d_flags & RT_DIR_COMB) )
	return -1;

    id = rt_db_get_internal( &intern, dp, dbip, (matp_t)NULL, &rt_uniresource );
    if ( id < 0 )
    {
	bu_log( "Cannot internal form of %s\n", dp->d_namep );
	return -1;
    }

    if ( id != ID_COMBINATION )
    {
	bu_log( "Directory/database mismatch!\n\t is '%s' a combination or not?\n",
		dp->d_namep );
	return -1;
    }

    comb = (struct rt_comb_internal *)intern.idb_ptr;
    RT_CK_COMB( comb );

    if ( BU_STR_EQUAL( bu_vls_addr( &comb->shader ), "light" ) )
    {
	rt_db_free_internal(&intern);
	return 0;
    }
    else
    {
	rt_db_free_internal(&intern);
	return -1;
    }
}
Пример #8
0
int
rt_db_put_internal(
    struct directory *dp,
    struct db_i *dbip,
    struct rt_db_internal *ip,
    struct resource *resp)
{
    struct bu_external ext;
    int ret;

    RT_CK_DB_INTERNAL(ip);

    if (db_version(dbip) > 4)
	return rt_db_put_internal5(dp, dbip, ip, resp,
				   DB5_MAJORTYPE_BRLCAD);

    BU_EXTERNAL_INIT(&ext);

    /* Scale change on export is 1.0 -- no change */
    ret = -1;
    if (ip->idb_meth->ft_export4) {
	ret = ip->idb_meth->ft_export4(&ext, ip, 1.0, dbip, resp);
    }
    if (ret < 0) {
	bu_log("rt_db_put_internal(%s):  solid export failure\n",
	       dp->d_namep);
	rt_db_free_internal(ip);
	bu_free_external(&ext);
	return -2;		/* FAIL */
    }
    rt_db_free_internal(ip);

    if (db_put_external(&ext, dp, dbip) < 0) {
	bu_free_external(&ext);
	return -1;		/* FAIL */
    }

    bu_free_external(&ext);
    return 0;			/* OK */
}
Пример #9
0
int
ged_comb_color(struct rt_wdb *wdbp, int argc, const char *argv[])
{
    int				i;
    int				val;
    register struct directory	*dp;
    struct rt_db_internal	intern;
    struct rt_comb_internal	*comb;
    static const char *usage = "comb_color combination R G B";

    GED_CHECK_DATABASE_OPEN(wdbp, GED_ERROR);
    GED_CHECK_READ_ONLY(wdbp, GED_ERROR);

    /* initialize result */
    bu_vls_trunc(&wdbp->wdb_result_str, 0);
    wdbp->wdb_result = GED_RESULT_NULL;
    wdbp->wdb_result_flags = 0;

    /* must be wanting help */
    if (argc == 1) {
	wdbp->wdb_result_flags |= GED_RESULT_FLAGS_HELP_BIT;
	bu_vls_printf(&wdbp->wdb_result_str, "Usage: %s %s", argv[0], usage);
	return GED_OK;
    }

    if (argc != 5) {
	bu_vls_printf(&wdbp->wdb_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    GED_DB_LOOKUP(wdbp, dp, argv[1], LOOKUP_NOISY, GED_ERROR);
    GED_CHECK_COMB(wdbp, dp, GED_ERROR);
    GED_DB_GET_INTERNAL(wdbp, &intern, dp, (fastf_t *)NULL, &rt_uniresource, GED_ERROR);

    comb = (struct rt_comb_internal *)intern.idb_ptr;
    RT_CK_COMB(comb);

    for (i = 0; i < 3; ++i) {
	if (sscanf(argv[i+2], "%d", &val) != 1 || val < 0 || 255 < val) {
	    bu_vls_printf(&wdbp->wdb_result_str,"RGB value out of range: %s", argv[i + 2]);
	    rt_db_free_internal(&intern, &rt_uniresource);
	    return GED_ERROR;
	}
	else
	    comb->rgb[i] = val;
    }

    comb->rgb_valid = 1;
    GED_DB_PUT_INTERNAL(wdbp, dp, &intern, &rt_uniresource, GED_ERROR);

    return GED_OK;
}
Пример #10
0
int
ged_adjust(struct ged *gedp, int argc, const char *argv[])
{
    int status;
    struct directory *dp;
    char *name;
    struct rt_db_internal intern;
    static const char *usage = "object attr value ?attr value?";

    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 < 4) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    name = (char *)argv[1];

    GED_DB_LOOKUP(gedp, dp, name, LOOKUP_QUIET, GED_ERROR);

    GED_DB_GET_INTERNAL(gedp, &intern, dp, (matp_t)NULL, &rt_uniresource, GED_ERROR);
    RT_CK_DB_INTERNAL(&intern);

    /* Find out what type of object we are dealing with and tweak it. */
    RT_CK_FUNCTAB(intern.idb_meth);

    if (!intern.idb_meth->ft_adjust) {
	bu_vls_printf(gedp->ged_result_str, "wdb_export(%s) adjust failure", name);
	return GED_ERROR;
    }

    status = intern.idb_meth->ft_adjust(gedp->ged_result_str, &intern, argc-2, argv+2);
    if (status == GED_OK && wdb_put_internal(gedp->ged_wdbp, name, &intern, 1.0) < 0) {
	bu_vls_printf(gedp->ged_result_str, "wdb_export(%s) failure", name);
	rt_db_free_internal(&intern);
	return GED_ERROR;
    }

    return GED_OK;
}
Пример #11
0
/* Convenience function to get a comb child's directory pointer
 * when it the comb only has one child */
struct directory *
Comb_Get_Only_Child(struct directory *dp, struct rt_wdb *wdbp)
{
    struct rt_db_internal comb_intern;
    struct rt_comb_internal *comb;
    union tree *child;
    struct directory *child_dp;
    int node_count = 0;

    rt_db_get_internal(&comb_intern, dp, wdbp->dbip, bn_mat_identity, &rt_uniresource);
    RT_CK_DB_INTERNAL(&comb_intern);
    if (comb_intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_COMBINATION) {
	rt_db_free_internal(&comb_intern);
	return RT_DIR_NULL;
    }

    /* If this comb has more than one child, there exists no "only" child */
    comb = (struct rt_comb_internal *)comb_intern.idb_ptr;
    if (comb->tree) {
	node_count = db_count_tree_nodes(comb->tree, 0);
	if (node_count > 1) {
	    rt_db_free_internal(&comb_intern);
	    return RT_DIR_NULL;
	}
    } else {
	/* Empty comb - there exists no "only" child */
	return RT_DIR_NULL;
    }

    /* If the child doesn't exist, there exists no "only" child, so at
     * this point whatever db_lookup returns is fine */
    child = _db_tree_get_child(comb->tree);
    child_dp = db_lookup(wdbp->dbip, child->tr_l.tl_name, LOOKUP_QUIET);
    rt_db_free_internal(&comb_intern);
    return child_dp;
}
Пример #12
0
int
ged_whatid(struct ged *gedp, int argc, const char *argv[])
{
    struct directory *dp;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    static const char *usage = "region";

    GED_CHECK_DATABASE_OPEN(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;
    }


    if ((dp=db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_NOISY)) == RT_DIR_NULL)
	return GED_ERROR;

    if (!(dp->d_flags & RT_DIR_REGION)) {
	bu_vls_printf(gedp->ged_result_str, "%s is not a region", argv[1]);
	return GED_ERROR;
    }

    if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0)
	return GED_ERROR;
    comb = (struct rt_comb_internal *)intern.idb_ptr;

    bu_vls_printf(gedp->ged_result_str, "%ld", comb->region_id);
    rt_db_free_internal(&intern);

    return GED_OK;
}
void smoothBot
(
    rt_wdb* wdbp,
    char*   name
) {
    directory* dp = db_lookup(wdbp->dbip, name, LOOKUP_QUIET);

    if (dp != RT_DIR_NULL) {
	rt_db_internal intern;

	if (rt_db_get_internal(&intern, dp, wdbp->dbip, 0, &rt_uniresource) == ID_BOT) {
	    rt_bot_internal* bot = static_cast<rt_bot_internal*>(intern.idb_ptr);

	    rt_bot_smooth(bot, name, wdbp->dbip, M_PI_4);

	    if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0) {
		bu_bomb("Database write failure in smoothBot\n");
	    }
	}

	rt_db_free_internal(&intern);
    }
}
Пример #14
0
void
verify_region_attrs(struct directory *dp, struct db_i *dbip, Tcl_Obj *obj)
{
    Tcl_Obj **objs;
    int len = 0;
    int i;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;

    if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) {
	fprintf(stderr, "Cannot import %s\n", dp->d_namep);
	bu_exit(1, NULL);
    }

    comb = (struct rt_comb_internal *)intern.idb_ptr;
    RT_CHECK_COMB(comb);

    if (Tcl_ListObjGetElements(INTERP, obj, &len, &objs) != TCL_OK) {
	fprintf(stderr, "Cannot get length of attributes for %s\n", dp->d_namep);
	bu_exit(1, NULL);
    }

    for (i=1; i<len; i += 2) {
	char *key, *value;

	key = Tcl_GetStringFromObj(objs[i-1], NULL);
	value = Tcl_GetStringFromObj(objs[i], NULL);
	if (BU_STR_EQUAL(key, "region_id")) {
	    long id;

	    id = strtol(value, NULL, 0);
	    if (id != comb->region_id) {
		fprintf(stderr, "WARNING: %s in %s: \"region_id\" attribute says %ld, while region says %ld\n",
			dp->d_namep, dbip->dbi_filename, id, comb->region_id);
	    }
	} else if (BU_STR_EQUAL(key, "giftmater")) {
	    long GIFTmater;

	    GIFTmater = strtol(value, NULL, 0);
	    if (GIFTmater != comb->GIFTmater) {
		fprintf(stderr, "WARNING: %s in %s: \"giftmater\" attribute says %ld, while region says %ld\n",
			dp->d_namep, dbip->dbi_filename, GIFTmater, comb->GIFTmater);
	    }
	} else if (BU_STR_EQUAL(key, "los")) {
	    long los;

	    los = strtol(value, NULL, 0);
	    if (los != comb->los) {
		fprintf(stderr, "WARNING: %s in %s: \"los\" attribute says %ld, while region says %ld\n",
			dp->d_namep, dbip->dbi_filename, los, comb->los);
	    }
	} else if (BU_STR_EQUAL(key, "material")) {
	    if (!bu_strncmp(value, "gift", 4)) {
		long GIFTmater;

		GIFTmater = strtol(&value[4], NULL, 0);
		if (GIFTmater != comb->GIFTmater) {
		    fprintf(stderr, "WARNING: %s in %s: \"material\" attribute says %s, while region says %ld\n",
			    dp->d_namep, dbip->dbi_filename, value, comb->GIFTmater);
		}
	    }
	} else if (BU_STR_EQUAL(key, "aircode")) {
	    long aircode;

	    aircode = strtol(value, NULL, 0);
	    if (aircode != comb->aircode) {
		fprintf(stderr, "WARNING: %s in %s: \"aircode\" attribute says %ld, while region says %ld\n",
			dp->d_namep, dbip->dbi_filename, aircode, comb->aircode);
	    }
	}
    }
    rt_db_free_internal(&intern);
}
Пример #15
0
/**
 * Apply a 4x4 transformation matrix to the internal form of a solid.
 *
 * If "free" flag is non-zero, storage for the original solid is
 * released.  If "os" is same as "is", storage for the original solid
 * is overwritten with the new, transformed solid.
 *
 * Returns -
 * -1 FAIL
 *  0 OK
 */
int
rt_generic_xform(
    struct rt_db_internal *op,
    const mat_t mat,
    struct rt_db_internal *ip,
    int release,
    struct db_i *dbip,
    struct resource *resp)
{
    struct bu_external ext;
    int id;
    struct bu_attribute_value_set avs;

    RT_CK_DB_INTERNAL(ip);
    RT_CK_DBI(dbip);
    RT_CK_RESOURCE(resp);

    memset(&avs, 0, sizeof(struct bu_attribute_value_set));

    id = ip->idb_type;
    BU_EXTERNAL_INIT(&ext);
    /* Scale change on export is 1.0 -- no change */
    switch (db_version(dbip)) {
	case 4:
	    if (OBJ[id].ft_export4(&ext, ip, 1.0, dbip, resp) < 0) {
		bu_log("rt_generic_xform():  %s export failure\n",
		       OBJ[id].ft_name);
		return -1;			/* FAIL */
	    }
	    if ((release || op == ip)) rt_db_free_internal(ip);

	    RT_DB_INTERNAL_INIT(op);
	    if (OBJ[id].ft_import4(op, &ext, mat, dbip, resp) < 0) {
		bu_log("rt_generic_xform():  solid import failure\n");
		return -1;			/* FAIL */
	    }
	    break;
	case 5:
	    if (OBJ[id].ft_export5(&ext, ip, 1.0, dbip, resp) < 0) {
		bu_log("rt_generic_xform():  %s export failure\n",
		       OBJ[id].ft_name);
		return -1;			/* FAIL */
	    }

	    if ((release || op == ip)) {
		if (ip->idb_avs.magic == BU_AVS_MAGIC) {
		    /* grab the attributes before they are lost
		     * by rt_db_free_internal or RT_DB_INTERNAL_INIT
		     */
		    bu_avs_init(&avs, ip->idb_avs.count, "avs");
		    bu_avs_merge(&avs, &ip->idb_avs);
		}
		rt_db_free_internal(ip);
	    }

	    RT_DB_INTERNAL_INIT(op);

	    if (!release && op != ip) {
		/* just copy the attributes from ip to op */
		if (ip->idb_avs.magic == BU_AVS_MAGIC) {
		    bu_avs_init(&op->idb_avs, ip->idb_avs.count, "avs");
		    bu_avs_merge(&op->idb_avs, &ip->idb_avs);
		}
	    } else if (avs.magic == BU_AVS_MAGIC) {
		/* put the saved attributes in the output */
		bu_avs_init(&op->idb_avs, avs.count, "avs");
		bu_avs_merge(&op->idb_avs, &avs);
		bu_avs_free(&avs);
	    }

	    if (OBJ[id].ft_import5(op, &ext, mat, dbip, resp) < 0) {
		bu_log("rt_generic_xform():  solid import failure\n");
		return -1;			/* FAIL */
	    }
	    break;
    }

    bu_free_external(&ext);

    RT_CK_DB_INTERNAL(op);
    return 0;				/* OK */
}
Пример #16
0
/**
 * R T _ P G _ T O _ B O T
 *
 * Convert in-memory form of a polysolid (pg) to a bag of triangles (BoT)
 * There is no record in the V5 database for a polysolid.
 *
 * Depends on the "max_npts" parameter having been set.
 *
 * Returns -
 * -1 FAIL
 * 0 OK
 */
int
rt_pg_to_bot(struct rt_db_internal *ip, const struct bn_tol *tol, struct resource *resp)
{
    struct rt_pg_internal *ip_pg;
    struct rt_bot_internal *ip_bot;
    size_t max_pts;
    size_t max_tri;
    size_t p;
    size_t i;

    RT_CK_DB_INTERNAL(ip);
    BN_CK_TOL(tol);
    RT_CK_RESOURCE(resp);

    if (ip->idb_type != ID_POLY) {
	bu_log("ERROR: rt_pt_to_bot() called with a non-polysolid!!!\n");
	return -1;
    }
    ip_pg = (struct rt_pg_internal *)ip->idb_ptr;

    RT_PG_CK_MAGIC(ip_pg);

    BU_ALLOC(ip_bot, struct rt_bot_internal);
    ip_bot->magic = RT_BOT_INTERNAL_MAGIC;
    ip_bot->mode = RT_BOT_SOLID;
    ip_bot->orientation = RT_BOT_CCW;
    ip_bot->bot_flags = 0;

    /* maximum possible vertices */
    max_pts = ip_pg->npoly * ip_pg->max_npts;
    BU_ASSERT_SIZE_T(max_pts, >, 0);

    /* maximum possible triangular faces */
    max_tri = ip_pg->npoly * 3;
    BU_ASSERT_SIZE_T(max_tri, >, 0);

    ip_bot->num_vertices = 0;
    ip_bot->num_faces = 0;
    ip_bot->thickness = (fastf_t *)NULL;
    ip_bot->face_mode = (struct bu_bitv *)NULL;

    ip_bot->vertices = (fastf_t *)bu_calloc(max_pts * 3, sizeof(fastf_t), "BOT vertices");
    ip_bot->faces = (int *)bu_calloc(max_tri * 3, sizeof(int), "BOT faces");

    for (p=0; p<ip_pg->npoly; p++) {
	vect_t work[3], tmp;
	struct tri_specific trip;
	fastf_t m1, m2, m3, m4;
	size_t v0=0, v2=0;
	int first;

	first = 1;
	VMOVE(work[0], &ip_pg->poly[p].verts[0*3]);
	VMOVE(work[1], &ip_pg->poly[p].verts[1*3]);

	for (i=2; i < ip_pg->poly[p].npts; i++) {
	    VMOVE(work[2], &ip_pg->poly[p].verts[i*3]);

	    VSUB2(trip.tri_BA, work[1], work[0]);
	    VSUB2(trip.tri_CA, work[2], work[0]);
	    VCROSS(trip.tri_wn, trip.tri_BA, trip.tri_CA);

	    /* Check to see if this plane is a line or pnt */
	    m1 = MAGNITUDE(trip.tri_BA);
	    m2 = MAGNITUDE(trip.tri_CA);
	    VSUB2(tmp, work[1], work[2]);
	    m3 = MAGNITUDE(tmp);
	    m4 = MAGNITUDE(trip.tri_wn);
	    if (m1 >= tol->dist && m2 >= tol->dist &&
		m3 >= tol->dist && m4 >= tol->dist) {

		/* add this triangle to the BOT */
		if (first) {
		    ip_bot->faces[ip_bot->num_faces * 3] = ip_bot->num_vertices;
		    VMOVE(&ip_bot->vertices[ip_bot->num_vertices * 3], work[0]);
		    v0 = ip_bot->num_vertices;
		    ip_bot->num_vertices++;

		    ip_bot->faces[ip_bot->num_faces * 3 + 1] = ip_bot->num_vertices;
		    VMOVE(&ip_bot->vertices[ip_bot->num_vertices * 3], work[1]);
		    ip_bot->num_vertices++;
		    first = 0;
		} else {
		    ip_bot->faces[ip_bot->num_faces * 3] = v0;
		    ip_bot->faces[ip_bot->num_faces * 3 + 1] = v2;
		}
		VMOVE(&ip_bot->vertices[ip_bot->num_vertices * 3], work[2]);
		ip_bot->faces[ip_bot->num_faces * 3 + 2] = ip_bot->num_vertices;
		v2 = ip_bot->num_vertices;
		ip_bot->num_vertices++;

		ip_bot->num_faces++;
	    }

	    /* Chop off a triangle, and continue */
	    VMOVE(work[1], work[2]);
	}
    }

    rt_bot_vertex_fuse(ip_bot, tol);
    rt_bot_face_fuse(ip_bot);

    rt_db_free_internal(ip);

    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_BOT;
    ip->idb_meth = &rt_functab[ID_BOT];
    ip->idb_ptr = ip_bot;

    return 0;
}
Пример #17
0
void
db_update_nref( struct db_i *dbip, struct resource *resp )
{
    register int			i;
    register struct directory      *dp;
    struct rt_db_internal		intern;
    struct rt_comb_internal	       *comb;

    RT_CK_DBI( dbip );
    RT_CK_RESOURCE(resp);

    /* First, clear any existing counts */
    for ( i = 0; i < RT_DBNHASH; i++ )
	for ( dp = dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw )
	    dp->d_nref = 0;

    /* Examine all COMB nodes */
    for ( i = 0; i < RT_DBNHASH; i++ )  {
	for ( dp = dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw ) {

	    /* handle non-combination objects that reference other objects */
	    if ( dp->d_major_type == DB5_MAJORTYPE_BRLCAD ) {
		struct directory *dp2;

		if ( dp->d_minor_type == DB5_MINORTYPE_BRLCAD_EXTRUDE ) {
		    struct rt_extrude_internal *extr;

		    if ( rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, resp) < 0 )
			continue;
		    extr = (struct rt_extrude_internal *)intern.idb_ptr;
		    RT_EXTRUDE_CK_MAGIC( extr );
		    if ( extr->sketch_name ) {
			dp2 = db_lookup( dbip, extr->sketch_name, LOOKUP_QUIET );
			if ( dp2 != DIR_NULL ) {
			    dp2->d_nref++;
			}
		    }
		    rt_db_free_internal( &intern, resp );
		} else if ( dp->d_minor_type ==  DB5_MINORTYPE_BRLCAD_DSP ) {
		    struct rt_dsp_internal *dsp;

		    if ( rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, resp) < 0 )
			continue;
		    dsp = (struct rt_dsp_internal *)intern.idb_ptr;
		    RT_DSP_CK_MAGIC( dsp );
		    if ( dsp->dsp_datasrc == RT_DSP_SRC_OBJ && bu_vls_strlen( &dsp->dsp_name) > 0 ) {
			dp2 = db_lookup( dbip, bu_vls_addr( &dsp->dsp_name ), LOOKUP_QUIET );
			if ( dp2 != DIR_NULL ) {
			    dp2->d_nref++;
			}
		    }
		    rt_db_free_internal( &intern, resp );
		}
	    }
	    if ( !(dp->d_flags & DIR_COMB) )
		continue;
	    if ( rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, resp) < 0 )
		continue;
	    if ( intern.idb_type != ID_COMBINATION )  {
		bu_log("NOTICE: %s was marked a combination, but isn't one?  Clearing flag\n",
		       dp->d_namep);
		dp->d_flags &= ~DIR_COMB;
		rt_db_free_internal( &intern, resp );
		continue;
	    }
	    comb = (struct rt_comb_internal *)intern.idb_ptr;
	    db_tree_funcleaf( dbip, comb, comb->tree,
			      db_count_refs, (genptr_t)NULL,
			      (genptr_t)NULL, (genptr_t)NULL );
	    rt_db_free_internal( &intern, resp );
	}
    }
}
Пример #18
0
   or  poly-bot file_poly.g file_bot.g\n\
 Convert polysolids to BOT solids in v4 database format only\n";

int
main(int argc, char **argv)
{
    FILE *ifp;
    FILE *ofp;
    union record record;
    union record *poly;
    long poly_limit=0;
    long curr_poly=0;
    struct bn_tol		tol;
    int polys=0;
    int frees=0;
    int others=0;
    int bots=0;
    int i;
    int num_rec;
    int first=1;

    bu_setprogname(argv[0]);

    ifp = stdin;
    ofp = stdout;

    /* FIXME: These need to be improved */
    tol.magic = BN_TOL_MAGIC;
    tol.dist = 0.0005;
    tol.dist_sq = tol.dist * tol.dist;
    tol.perp = 1e-6;
    tol.para = 1 - tol.perp;

    if (argc >= 3) {
	ifp = fopen(argv[1], "rb");
	if (!ifp)
	    perror(argv[1]);

	ofp = fopen(argv[2], "wb");
	if (!ofp)
	    perror(argv[2]);

	if (ifp == NULL || ofp == NULL) {
	    bu_exit(1, "poly-bot: can't open files.");
	}
#if defined(_WIN32) && !defined(__CYGWIN__)
    } else {
	setmode(fileno(ifp), O_BINARY);
	setmode(fileno(ofp), O_BINARY);
#endif
    }
    if (isatty(fileno(ifp))) {
	bu_exit(1, "%s", usage);
    }

    poly = (union record *)bu_malloc( POLY_BLOCK * sizeof( union record ), "poly" );
    poly_limit = POLY_BLOCK;

    /* Read database file */
    while ( fread( (char *)&record, sizeof record, 1, ifp ) == 1  && !feof(ifp) )
    {
    top:
	switch ( record.u_id )
	{
	    case ID_FREE:
		frees++;
		continue;

	    case DBID_SKETCH:
		num_rec = ntohl(*(uint32_t *)&record.skt.skt_count);
		others += num_rec + 1;
		if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
		    bu_exit(1, "Write failed!\n" );
		for ( i=0; i<num_rec; i++ )
		{
		    if ( fread( (char *)&record, sizeof record, 1, ifp ) != 1 )
			bu_exit(1, "Unexpected EOF encountered while copying a SKETCH\n" );
		    if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
			bu_exit(1, "Write failed!\n" );
		}
		break;
	    case DBID_EXTR:
		num_rec = ntohl(*(uint32_t *)&record.extr.ex_count);
		others += num_rec + 1;
		if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
		    bu_exit(1, "Write failed!\n" );
		for ( i=0; i<num_rec; i++ )
		{
		    if ( fread( (char *)&record, sizeof record, 1, ifp ) != 1 )
			bu_exit(1, "Unexpected EOF encountered while copying an EXTRUSION\n" );
		    if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
			bu_exit(1, "Write failed!\n" );
		}
		break;
	    case DBID_NMG:
		num_rec = ntohl(*(uint32_t *)&record.nmg.N_count);
		others += num_rec + 1;
		if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
		    bu_exit(1, "Write failed!\n" );
		for ( i=0; i<num_rec; i++ )
		{
		    if ( fread( (char *)&record, sizeof record, 1, ifp ) != 1 )
			bu_exit(1, "Unexpected EOF encountered while copying an ARBN\n" );
		    if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
			bu_exit(1, "Write failed!\n" );
		}
		break;
	    case DBID_PIPE:
		num_rec = ntohl(*(uint32_t *)&record.pwr.pwr_count);
		others += num_rec + 1;
		if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
		    bu_exit(1, "Write failed!\n" );
		for ( i=0; i<num_rec; i++ )
		{
		    if ( fread( (char *)&record, sizeof record, 1, ifp ) != 1 )
			bu_exit(1, "Unexpected EOF encountered while copying a PIPE\n" );
		    if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
			bu_exit(1, "Write failed!\n" );
		}
		break;
	    case DBID_ARBN:
		num_rec = ntohl(*(uint32_t *)&record.n.n_grans);
		others += num_rec + 1;
		if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
		    bu_exit(1, "Write failed!\n" );
		for ( i=0; i<num_rec; i++ )
		{
		    if ( fread( (char *)&record, sizeof record, 1, ifp ) != 1 )
			bu_exit(1, "Unexpected EOF encountered while copying an ARBN\n" );
		    if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
			bu_exit(1, "Write failed!\n" );
		}
		break;
	    case DBID_STRSOL:
		num_rec = DB_SS_NGRAN - 1;
		others += num_rec + 1;
		if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
		    bu_exit(1, "Write failed!\n" );
		for ( i=0; i<num_rec; i++ )
		{
		    if ( fread( (char *)&record, sizeof record, 1, ifp ) != 1 )
			bu_exit(1, "Unexpected EOF encountered while copying a STRSOL\n" );
		    if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
			bu_exit(1, "Write failed!\n" );
		}
		break;
	    case ID_BSURF:
		num_rec = record.d.d_nknots + record.d.d_nctls;
		others += num_rec + 1;
		if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
		    bu_exit(1, "Write failed!\n" );
		for ( i=0; i<num_rec; i++ )
		{
		    if ( fread( (char *)&record, sizeof record, 1, ifp ) != 1 )
			bu_exit(1, "Unexpected EOF encountered while copying a NURB\n" );
		    if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
			bu_exit(1, "Write failed!\n" );
		}
		break;
	    case DBID_BOT:
		bots++;
		if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
		    bu_exit(1, "Write failed!\n" );
		num_rec = ntohl(*(uint32_t *)&record.bot.bot_nrec);
		for ( i=0; i<num_rec; i++ )
		{
		    if ( fread( (char *)&record, sizeof record, 1, ifp ) != 1 )
			bu_exit(1, "Unexpected EOF encountered while copying a BOT\n" );
		    if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
			bu_exit(1, "Write failed!\n" );
		}
		break;
	    case ID_P_HEAD:
	    {
		struct rt_db_internal intern;
		struct bu_external ext;
		struct bu_external ext2;

		polys++;
		curr_poly = 0;
		poly[curr_poly++] = record;	/* struct copy */
		bu_log( "Converting %s\n", poly[0].p.p_name );
		while ( fread( (char *)&record, sizeof record, 1, ifp ) == 1  &&
			!feof(ifp) &&
			record.u_id == ID_P_DATA )
		{
		    if ( curr_poly >= poly_limit )
		    {
			poly_limit += POLY_BLOCK;
			poly = (union record *)bu_realloc( poly, poly_limit*sizeof( union record ), "poly realloc" );
		    }
		    poly[curr_poly++] = record;	/* struct copy */
		}
		BU_EXTERNAL_INIT( &ext );
		ext.ext_nbytes = curr_poly * sizeof( union record );
		ext.ext_buf = (uint8_t *)poly;
		if ( rt_functab[ID_POLY].ft_import4( &intern, &ext, bn_mat_identity, (struct db_i *)NULL, &rt_uniresource ) )
		{
		    bu_exit(1, "Import failed for polysolid %s\n", poly[0].p.p_name );
		}
		/* Don't free this ext buffer! */

		if ( rt_pg_to_bot( &intern, &tol, &rt_uniresource ) < 0 )  {
		    bu_exit(1, "Unable to convert polysolid %s\n", poly[0].p.p_name );
		}

		BU_EXTERNAL_INIT( &ext2 );
		if ( rt_functab[ID_POLY].ft_export4( &ext2, &intern, 1.0, (struct db_i *)NULL, &rt_uniresource ) < 0 )  {
		    bu_exit(1, "Unable to export v4 BoT %s\n", poly[0].p.p_name );
		}
		rt_db_free_internal(&intern);
		if ( db_fwrite_external( ofp, poly[0].p.p_name, &ext2 ) < 0 )  {
		    bu_exit(1, "Unable to fwrite v4 BoT %s\n", poly[0].p.p_name );
		}
		bu_free_external( &ext2 );

		if ( feof( ifp ) )
		    break;
		goto top;
	    }
	    case ID_P_DATA:
		/* This should not happen! */
		bu_log( "ERROR: Unattached polysolid data record!\n" );
		continue;
	    default:
		if ( first )
		{
		    if ( record.u_id != ID_IDENT ) {
			bu_exit(1, "This is not a BRL-CAD 'v4' database, aborting.\n" );
		    }
		    first = 0;
		}
		others++;
		if ( fwrite( &record, sizeof( union record ), 1, ofp ) < 1 )
		    bu_exit(1, "Write failed!\n" );
	}
    }

    bu_log( "%d polysolids converted to BOT solids\n", polys );
    bu_log( "%d BOT solids copied without change\n", bots );
    bu_log( "%d other records copied without change\n", others );
    bu_log( "%d free records skipped\n", frees );

    fclose(ofp);
    return 0;
}
Пример #19
0
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;
}
Пример #20
0
int
ged_move(struct ged *gedp, int argc, const char *argv[])
{
    struct ged_display_list *gdlp;
    struct directory *dp;
    struct rt_db_internal intern;
    static const char *usage = "from to";

    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;
    }

    if ((dp = db_lookup(gedp->ged_wdbp->dbip,  argv[1], LOOKUP_NOISY)) == RT_DIR_NULL)
	return GED_ERROR;

    if (db_lookup(gedp->ged_wdbp->dbip, argv[2], LOOKUP_QUIET) != RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s: already exists", argv[2]);
	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");
	return GED_ERROR;
    }

    /* Change object name in the in-memory directory. */
    if (db_rename(gedp->ged_wdbp->dbip, dp, argv[2]) < 0) {
	rt_db_free_internal(&intern);
	bu_vls_printf(gedp->ged_result_str, "error in db_rename to %s, aborting", argv[2]);
	return GED_ERROR;
    }

    /* Re-write to the database.  New name is applied on the way out. */
    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
	bu_vls_printf(gedp->ged_result_str, "Database write error, aborting");
	return GED_ERROR;
    }

    /* Change object name if it matches the first element in the display list path. */
    for (BU_LIST_FOR(gdlp, ged_display_list, gedp->ged_gdp->gd_headDisplay)) {
	int first = 1;
	int found = 0;
	struct bu_vls new_path = BU_VLS_INIT_ZERO;
	char *dupstr = strdup(bu_vls_addr(&gdlp->gdl_path));
	char *tok = strtok(dupstr, "/");

	while (tok) {
	    if (first) {
		first = 0;

		if (BU_STR_EQUAL(tok, argv[1])) {
		    found = 1;
		    bu_vls_printf(&new_path, "%s", argv[2]);
		} else
		    break; /* no need to go further */
	    } else
		bu_vls_printf(&new_path, "/%s", tok);

	    tok = strtok((char *)NULL, "/");
	}

	if (found) {
	    bu_vls_free(&gdlp->gdl_path);
	    bu_vls_printf(&gdlp->gdl_path, "%s", bu_vls_addr(&new_path));
	}

	free((void *)dupstr);
	bu_vls_free(&new_path);
    }

    return GED_OK;
}
Пример #21
0
int
ged_bot_face_sort(struct ged *gedp, int argc, const char *argv[])
{
    int i;
    int tris_per_piece=0;
    static const char *usage = "triangles_per_piece bot_solid1 [bot_solid2 bot_solid3 ...]";

    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;
    }

    tris_per_piece = atoi(argv[1]);
    if (tris_per_piece < 1) {
	bu_vls_printf(gedp->ged_result_str,
		      "Illegal value for triangle per piece (%s)\n",
		      argv[1]);
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    for (i = 2; i < argc; i++) {
	struct directory *dp;
	struct rt_db_internal intern;
	struct rt_bot_internal *bot;

	if ((dp=db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL) {
	    continue;
	}

	GED_DB_GET_INTERNAL(gedp, &intern, dp, bn_mat_identity, gedp->ged_wdbp->wdb_resp, GED_ERROR);

	if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
	    rt_db_free_internal(&intern);
	    bu_vls_printf(gedp->ged_result_str,
			  "%s is not a BOT primitive, skipped\n",
			  dp->d_namep);
	    continue;
	}

	bot = (struct rt_bot_internal *)intern.idb_ptr;
	RT_BOT_CK_MAGIC(bot);

	bu_log("processing %s (%zu triangles)\n", dp->d_namep, bot->num_faces);

	if (rt_bot_sort_faces(bot, tris_per_piece)) {
	    rt_db_free_internal(&intern);
	    bu_vls_printf(gedp->ged_result_str,
			  "Face sort failed for %s, this BOT not sorted\n",
			  dp->d_namep);
	    continue;
	}

	GED_DB_PUT_INTERNAL(gedp, dp, &intern, gedp->ged_wdbp->wdb_resp, GED_ERROR);
    }

    return GED_OK;
}
Пример #22
0
int
rt_mk_binunif(struct rt_wdb *wdbp, const char *obj_name, const char *file_name, unsigned int minor_type, size_t max_count)
{
    int ret;
    struct stat st;
    size_t num_items = 0;
    size_t obj_length = 0;
    size_t item_length = 0;
    unsigned int major_type = DB5_MAJORTYPE_BINARY_UNIF;
    struct directory *dp = NULL;
    struct bu_mapped_file *bu_fd = NULL;
    struct rt_binunif_internal *bip = NULL;
    struct bu_external body;
    struct bu_external bin_ext;
    struct rt_db_internal intern;

    item_length = db5_type_sizeof_h_binu(minor_type);
    if (item_length == 0) {
	bu_log("Unrecognized minor type (%d)!\n", minor_type);
	return -1;
    }

    if (bu_stat(file_name, &st)) {
	bu_log("Cannot stat input file (%s)", file_name);
	return -1;
    }

    bu_fd = bu_open_mapped_file(file_name, NULL);
    if (bu_fd == NULL) {
	bu_log("Cannot open input file (%s) for reading", file_name);
	return -1;
    }

    /* create the rt_binunif internal form */
    BU_ALLOC(bip, struct rt_binunif_internal);
    bip->magic = RT_BINUNIF_INTERNAL_MAGIC;
    bip->type = minor_type;

    num_items = (size_t)(st.st_size / item_length);

    /* maybe only a partial file read */
    if (max_count > 0 && max_count < num_items) {
	num_items = max_count;
    }

    obj_length = num_items * item_length;
    if (obj_length < 1) {
	obj_length = 1;
    }

    /* just copy the bytes */
    bip->count = (long)num_items;
    bip->u.int8 = (char *)bu_malloc(obj_length, "binary uniform object");
    memcpy(bip->u.int8, bu_fd->buf, obj_length);

    bu_close_mapped_file(bu_fd);

    /* create the rt_internal form */
    RT_DB_INTERNAL_INIT(&intern);
    intern.idb_major_type = major_type;
    intern.idb_minor_type = minor_type;
    intern.idb_ptr = (genptr_t)bip;
    intern.idb_meth = &rt_functab[ID_BINUNIF];

    /* create body portion of external form */
    ret = -1;
    if (intern.idb_meth->ft_export5) {
	ret = intern.idb_meth->ft_export5(&body, &intern, 1.0, wdbp->dbip, wdbp->wdb_resp);
    }
    if (ret != 0) {
	bu_log("Error while attempting to export %s\n", obj_name);
	rt_db_free_internal(&intern);
	return -1;
    }

    /* create entire external form */
    db5_export_object3(&bin_ext, DB5HDR_HFLAGS_DLI_APPLICATION_DATA_OBJECT,
		       obj_name, 0, NULL, &body,
		       intern.idb_major_type, intern.idb_minor_type,
		       DB5_ZZZ_UNCOMPRESSED, DB5_ZZZ_UNCOMPRESSED);

    rt_db_free_internal(&intern);
    bu_free_external(&body);

    /* make sure the database directory is initialized */
    if (wdbp->dbip->dbi_eof == RT_DIR_PHONY_ADDR) {
	ret = db_dirbuild(wdbp->dbip);
	if (ret) {
	    return -1;
	}
    }

    /* add this (phony until written) object to the directory */
    if ((dp=db_diradd5(wdbp->dbip, obj_name, RT_DIR_PHONY_ADDR, major_type,
		       minor_type, 0, 0, NULL)) == RT_DIR_NULL) {
	bu_log("Error while attempting to add new name (%s) to the database",
	       obj_name);
	bu_free_external(&bin_ext);
	return -1;
    }

    /* and write it to the database */
    if (db_put_external5(&bin_ext, dp, wdbp->dbip)) {
	bu_log("Error while adding new binary object (%s) to the database",
	       obj_name);
	bu_free_external(&bin_ext);
	return -1;
    }

    bu_free_external(&bin_ext);

    return 0;
}
Пример #23
0
int
wrobj( char name[], int flags )
{
    struct directory *tdp;
    struct rt_db_internal intern;
    int i;

    if (dbip == DBI_NULL)
	return 0;

    if ( db_lookup( dbip, name, LOOKUP_QUIET) != DIR_NULL ) {
	Tcl_AppendResult(interp, "track naming error: ", name,
			 " already exists\n", (char *)NULL);
	return(-1);
    }

    if ( flags != DIR_SOLID )
    {
	Tcl_AppendResult(interp, "wrobj can only write solids, aborting\n" );
	return( -1 );
    }

    RT_INIT_DB_INTERNAL( &intern );
    switch ( sol.s_type )
    {
	case ID_ARB8:
	{
	    struct rt_arb_internal *arb;

	    BU_GETSTRUCT( arb, rt_arb_internal );

	    arb->magic = RT_ARB_INTERNAL_MAGIC;

	    VMOVE( arb->pt[0], &sol.s_values[0] );
	    for ( i=1; i<8; i++ )
		VADD2( arb->pt[i], &sol.s_values[i*3], arb->pt[0] )

		    intern.idb_ptr = (genptr_t)arb;
	    intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
	    intern.idb_type = ID_ARB8;
	    intern.idb_meth = &rt_functab[ID_ARB8];
	}
	break;
	case ID_TGC:
	{
	    struct rt_tgc_internal *tgc;

	    BU_GETSTRUCT( tgc, rt_tgc_internal );

	    tgc->magic = RT_TGC_INTERNAL_MAGIC;

	    VMOVE( tgc->v, &sol.s_values[0] );
	    VMOVE( tgc->h, &sol.s_values[3] );
	    VMOVE( tgc->a, &sol.s_values[6] );
	    VMOVE( tgc->b, &sol.s_values[9] );
	    VMOVE( tgc->c, &sol.s_values[12] );
	    VMOVE( tgc->d, &sol.s_values[15] );

	    intern.idb_ptr = (genptr_t)tgc;
	    intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
	    intern.idb_type = ID_TGC;
	    intern.idb_meth = &rt_functab[ID_TGC];
	}
	break;
	default:
	    Tcl_AppendResult(interp, "Unrecognized solid type in 'wrobj', aborting\n", (char *)NULL );
	    return( -1 );
    }

    if ( (tdp = db_diradd( dbip, name, -1L, 0, flags, (genptr_t)&intern.idb_type)) == DIR_NULL )
    {
	rt_db_free_internal( &intern, &rt_uniresource );
	Tcl_AppendResult(interp, "Cannot add '", name, "' to directory, aborting\n", (char *)NULL );
	return( -1 );
    }

    if ( rt_db_put_internal( tdp, dbip, &intern, &rt_uniresource ) < 0 )
    {
	rt_db_free_internal( &intern, &rt_uniresource );
	Tcl_AppendResult(interp, "wrobj(", name, "):  write error\n", (char *)NULL);
	TCL_ERROR_RECOVERY_SUGGESTION;
	return( -1 );
    }
    return(0);
}
Пример #24
0
int
main(int argc, char **argv)
{
    struct rt_wdb	*fp;
    struct db_i	*dbip;
    struct directory	*dp;
    long	errors = 0;
    struct bn_tol tol;
    char name[17];

    bu_setprogname(argv[0]);

    /* FIXME: These need to be improved */
    tol.magic = BN_TOL_MAGIC;
    tol.dist = 0.0005;
    tol.dist_sq = tol.dist * tol.dist;
    tol.perp = 1e-6;
    tol.para = 1 - tol.perp;

    bu_debug = BU_DEBUG_COREDUMP;

    rt_init_resource( &rt_uniresource, 0, NULL );

    if ( argc != 3 )  {
	fprintf(stderr, "Usage: %s v4.g v5.g\n", argv[0]);
	return 1;
    }

    if ( (dbip = db_open(argv[1], DB_OPEN_READONLY)) == DBI_NULL )  {
	perror( argv[1] );
	return 2;
    }

    if ( (fp = wdb_fopen( argv[2] )) == NULL )  {
	perror( argv[2] );
	return 3;
    }

    if ( db_version(dbip) != 4 ) {
	bu_log( "Input database must be a version 4 database!!!!\n" );
	return 4;
    }

    RT_CK_DBI(dbip);
    if ( db_dirbuild( dbip ) )
	bu_exit(1, "db_dirbuild failed\n" );

    db_update_ident( fp->dbip, dbip->dbi_title, dbip->dbi_local2base );

    /* Retrieve every item in the input database */
    FOR_ALL_DIRECTORY_START(dp, dbip)  {
	struct rt_db_internal	intern;
	int id;
	int ret;

	fprintf(stderr, "%.16s\n", dp->d_namep );

	id = rt_db_get_internal( &intern, dp, dbip, NULL, &rt_uniresource );
	if ( id < 0 )  {
	    fprintf(stderr,
		    "%s: rt_db_get_internal(%s) failure, skipping\n",
		    argv[0], dp->d_namep);
	    errors++;
	    continue;
	}
	if ( id == ID_COMBINATION ) {
	    struct rt_comb_internal *comb;
	    char *ptr;

	    comb = (struct rt_comb_internal *)intern.idb_ptr;
	    RT_CK_COMB( comb );

	    /* Convert "plastic" to "phong" in the shader string */
	    while ( (ptr=strstr( bu_vls_addr( &comb->shader), "plastic" )) != NULL ) {
		ptr[0] = 'p'; /* p */
		ptr[1] = 'h'; /* l */
		ptr[2] = 'o'; /* a */
		ptr[3] = 'n'; /* s */
		ptr[4] = 'g'; /* t */
		ptr[5] = ' '; /* i */
		ptr[6] = ' '; /* c */
	    }
	}
	if ( id == ID_HF ) {
	    if (rt_hf_to_dsp( &intern )) {
		fprintf(stderr,
			"%s: Conversion from HF to DSP failed for solid %s\n",
			argv[0], dp->d_namep );
		errors++;
		continue;
	    }
	}
	if ( id == ID_POLY)
	{
	    if ( rt_pg_to_bot( &intern, &tol, &rt_uniresource ) )
	    {
		fprintf( stderr, "%s: Conversion from polysolid to BOT failed for solid %s\n",
			 argv[0], dp->d_namep );
		errors++;
		continue;
	    }
	}

	/* to insure null termination */
	bu_strlcpy( name, dp->d_namep, sizeof(name) );
	ret = wdb_put_internal( fp, name, &intern, 1.0 );
	if ( ret < 0 )  {
	    fprintf(stderr,
		    "%s: wdb_put_internal(%s) failure, skipping\n",
		    argv[0], dp->d_namep);
	    rt_db_free_internal(&intern);
	    errors++;
	    continue;
	}
	rt_db_free_internal(&intern);
    } FOR_ALL_DIRECTORY_END

	  wdb_close( fp );
    db_close( dbip );

    fprintf(stderr, "%ld objects failed to convert\n", errors);
    return 0;
}
Пример #25
0
/**
 * Apply a transformation matrix to the specified 'ip' input revolve
 * object, storing the results in the specified 'op' out pointer or
 * creating a copy if NULL.
 */
int
rt_revolve_xform(
    struct rt_db_internal *op,
    const mat_t mat,
    struct rt_db_internal *ip,
    int release,
    struct db_i *dbip,
    struct resource *resp)
{
    struct rt_revolve_internal *rip, *rop;
    point_t tmp_vec;

    if (dbip) RT_CK_DBI(dbip);
    RT_CK_DB_INTERNAL(ip);
    RT_CK_RESOURCE(resp);
    rip = (struct rt_revolve_internal *)ip->idb_ptr;
    RT_REVOLVE_CK_MAGIC(rip);

    if (bu_debug&BU_DEBUG_MEM_CHECK) {
	bu_log("Barrier check at start of revolve_xform():\n");
	bu_mem_barriercheck();
    }

    if (op != ip) {
	RT_DB_INTERNAL_INIT(op);
	BU_ALLOC(rop, struct rt_revolve_internal);
	rop->magic = RT_REVOLVE_INTERNAL_MAGIC;
	bu_vls_init(&rop->sketch_name);
	bu_vls_vlscat(&rop->sketch_name, &rip->sketch_name);
	op->idb_ptr = (void *)rop;
	op->idb_meth = &OBJ[ID_REVOLVE];
	op->idb_major_type = DB5_MAJORTYPE_BRLCAD;
	op->idb_type = ID_REVOLVE;
	if (ip->idb_avs.magic == BU_AVS_MAGIC) {
	    bu_avs_init(&op->idb_avs, ip->idb_avs.count, "avs");
	    bu_avs_merge(&op->idb_avs, &ip->idb_avs);
	}
    } else {
	rop = (struct rt_revolve_internal *)ip->idb_ptr;
    }
    MAT4X3PNT(tmp_vec, mat, rip->v3d);
    VMOVE(rop->v3d, tmp_vec);
    MAT4X3VEC(tmp_vec, mat, rip->axis3d);
    VMOVE(rop->axis3d, tmp_vec);
    V2MOVE(rop->v2d, rip->v2d);
    V2MOVE(rop->axis2d, rip->axis2d);

    if (release && ip != op) {
	rop->skt = rip->skt;
	rip->skt = (struct rt_sketch_internal *)NULL;
	rt_db_free_internal(ip);
    } else if (rip->skt) {
	rop->skt = rt_copy_sketch(rip->skt);
    } else {
	rop->skt = (struct rt_sketch_internal *)NULL;
    }

    if (bu_debug&BU_DEBUG_MEM_CHECK) {
	bu_log("Barrier check at end of revolve_xform():\n");
	bu_mem_barriercheck();
    }

    return 0;
}
Пример #26
0
int
ged_nmg_collapse(struct ged *gedp, int argc, const char *argv[])
{
    char *new_name;
    struct model *m;
    struct rt_db_internal intern;
    struct directory *dp;
    struct bu_ptbl faces;
    struct face *fp;
    size_t count;
    fastf_t tol_coll;
    fastf_t min_angle;
    static const char *usage = "nmg_prim new_prim max_err_dist [min_angle]";

    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 < 4) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    if (strchr(argv[2], '/')) {
	bu_vls_printf(gedp->ged_result_str, "Do not use '/' in solid names: %s\n", argv[2]);
	return GED_ERROR;
    }

    new_name = (char *)argv[2];

    if (db_lookup(gedp->ged_wdbp->dbip, new_name, LOOKUP_QUIET) != RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s already exists\n", new_name);
	return GED_ERROR;
    }

    if ((dp=db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_NOISY)) == RT_DIR_NULL)
	return GED_ERROR;

    if (dp->d_flags & RT_DIR_COMB) {
	bu_vls_printf(gedp->ged_result_str, "%s is a combination, only NMG primitives are allowed here\n", argv[1]);
	return GED_ERROR;
    }

    if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (matp_t)NULL, &rt_uniresource) < 0) {
	bu_vls_printf(gedp->ged_result_str, "Failed to get internal form of %s!!!!\n", argv[1]);
	return GED_ERROR;
    }

    if (intern.idb_type != ID_NMG) {
	bu_vls_printf(gedp->ged_result_str, "%s is not an NMG solid!!!!\n", argv[1]);
	rt_db_free_internal(&intern);
	return GED_ERROR;
    }

    tol_coll = atof(argv[3]) * gedp->ged_wdbp->dbip->dbi_local2base;
    if (tol_coll <= 0.0) {
	bu_vls_printf(gedp->ged_result_str, "tolerance distance too small\n");
	return GED_ERROR;
    }

    if (argc == 5) {
	min_angle = atof(argv[4]);
	if (min_angle < 0.0) {
	    bu_vls_printf(gedp->ged_result_str, "Minimum angle cannot be less than zero\n");
	    return GED_ERROR;
	}
    } else
	min_angle = 0.0;

    m = (struct model *)intern.idb_ptr;
    NMG_CK_MODEL(m);

    /* check that all faces are planar */
    nmg_face_tabulate(&faces, &m->magic);
    for (BU_PTBL_FOR(fp, (struct face *), &faces)) {
	if (fp->g.magic_p != NULL && *(fp->g.magic_p) != NMG_FACE_G_PLANE_MAGIC) {
	    bu_log("\tnot planar\n");
	    bu_ptbl_free(&faces);
	    bu_vls_printf(gedp->ged_result_str,
			  "nmg_collapse can only be applied to NMG primitives with planar faces\n");
	    return GED_ERROR;
	}
    }
    bu_ptbl_free(&faces);

    /* triangulate model */
    nmg_triangulate_model(m, &gedp->ged_wdbp->wdb_tol);

    count = (size_t)nmg_edge_collapse(m, &gedp->ged_wdbp->wdb_tol, tol_coll, min_angle);

    dp=db_diradd(gedp->ged_wdbp->dbip, new_name, 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", new_name);
	rt_db_free_internal(&intern);
	return GED_ERROR;
    }

    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
	rt_db_free_internal(&intern);
	bu_vls_printf(gedp->ged_result_str, "Database write error, aborting.\n");
	return GED_ERROR;
    }

    rt_db_free_internal(&intern);

    bu_vls_printf(gedp->ged_result_str, "%zu edges collapsed\n", count);

    return GED_OK;
}
Пример #27
0
int
ged_bo(struct ged *gedp, int argc, const char *argv[])
{
    int c;
    unsigned int minor_type=0;
    char *obj_name;
    char *file_name;
    int input_mode=0;
    int output_mode=0;
    struct rt_binunif_internal *bip;
    struct rt_db_internal intern;
    struct directory *dp;
    const char *argv0;
    static const char *usage = "{-i major_type minor_type | -o} dest source";

    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);

    argv0 = argv[0];

    /* must be wanting help */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	return GED_HELP;
    }

    /* check that we are using a version 5 database */
    if (db_version(gedp->ged_wdbp->dbip) < 5) {
	bu_vls_printf(gedp->ged_result_str, "This is an older database version.\nIt does not support binary objects.Use \"dbupgrade\" to upgrade this database to the current version.\n");
	return GED_ERROR;
    }

    bu_optind = 1;		/* re-init bu_getopt() */
    bu_opterr = 0;          /* suppress bu_getopt()'s error message */
    while ((c=bu_getopt(argc, (char * const *)argv, "iou:")) != -1) {
	switch (c) {
	    case 'i':
		input_mode = 1;
		break;
	    case 'o':
		output_mode = 1;
		break;
	    default:
		bu_vls_printf(gedp->ged_result_str, "Unrecognized option - %c", c);
		return GED_ERROR;

	}
    }

    if (input_mode + output_mode != 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	return GED_ERROR;
    }

    argc -= bu_optind;
    argv += bu_optind;

    if ((input_mode && argc != 4) || (output_mode && argc != 2)) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	return GED_ERROR;
    }


    if (input_mode) {
	if (argv[0][0] == 'u') {

	    if (argv[1][1] != '\0') {
		bu_vls_printf(gedp->ged_result_str, "Unrecognized minor type: %s", argv[1]);
		return GED_ERROR;
	    }

	    switch ((int)argv[1][0]) {
		case 'f':
		    minor_type = DB5_MINORTYPE_BINU_FLOAT;
		    break;
		case 'd':
		    minor_type = DB5_MINORTYPE_BINU_DOUBLE;
		    break;
		case 'c':
		    minor_type = DB5_MINORTYPE_BINU_8BITINT;
		    break;
		case 's':
		    minor_type = DB5_MINORTYPE_BINU_16BITINT;
		    break;
		case 'i':
		    minor_type = DB5_MINORTYPE_BINU_32BITINT;
		    break;
		case 'l':
		    minor_type = DB5_MINORTYPE_BINU_64BITINT;
		    break;
		case 'C':
		    minor_type = DB5_MINORTYPE_BINU_8BITINT_U;
		    break;
		case 'S':
		    minor_type = DB5_MINORTYPE_BINU_16BITINT_U;
		    break;
		case 'I':
		    minor_type = DB5_MINORTYPE_BINU_32BITINT_U;
		    break;
		case 'L':
		    minor_type = DB5_MINORTYPE_BINU_64BITINT_U;
		    break;
		default:
		    bu_vls_printf(gedp->ged_result_str, "Unrecognized minor type: %s", argv[1]);
		    return GED_ERROR;
	    }
	} else {
	    bu_vls_printf(gedp->ged_result_str, "Unrecognized major type: %s", argv[0]);
	    return GED_ERROR;
	}

	/* skip past major_type and minor_type */
	argc -= 2;
	argv += 2;

	if (minor_type == 0) {
	    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	    return GED_ERROR;
	}

	obj_name = (char *)*argv;
	GED_CHECK_EXISTS(gedp, obj_name, LOOKUP_QUIET, GED_ERROR);

	argc--;
	argv++;

	file_name = (char *)*argv;

	/* make a binunif of the entire file */
	if (rt_mk_binunif (gedp->ged_wdbp, obj_name, file_name, minor_type, 0)) {
	    bu_vls_printf(gedp->ged_result_str, "Error creating %s", obj_name);
	    return GED_ERROR;
	}

    } else if (output_mode) {
	FILE *fp;

	file_name = (char *)*argv;

	argc--;
	argv++;

	obj_name = (char *)*argv;

	if ((dp=db_lookup(gedp->ged_wdbp->dbip, obj_name, LOOKUP_NOISY)) == RT_DIR_NULL) {
	    return GED_ERROR;
	}
	if (!(dp->d_major_type & DB5_MAJORTYPE_BINARY_MASK)) {
	    bu_vls_printf(gedp->ged_result_str, "%s is not a binary object", obj_name);
	    return GED_ERROR;
	}

	if (dp->d_major_type != DB5_MAJORTYPE_BINARY_UNIF) {
	    bu_vls_printf(gedp->ged_result_str, "source must be a uniform binary object");
	    return GED_ERROR;
	}

	fp = fopen(file_name, "w+b");
	if (fp == NULL) {
	    bu_vls_printf(gedp->ged_result_str, "Error: cannot open file %s for writing", file_name);
	    return GED_ERROR;
	}

	if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, NULL,
			       &rt_uniresource) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "Error reading %s from database", dp->d_namep);
	    fclose(fp);
	    return GED_ERROR;
	}

	RT_CK_DB_INTERNAL(&intern);

	bip = (struct rt_binunif_internal *)intern.idb_ptr;
	if (bip->count < 1) {
	    bu_vls_printf(gedp->ged_result_str, "%s has no contents", obj_name);
	    fclose(fp);
	    rt_db_free_internal(&intern);
	    return GED_ERROR;
	}

	if (fwrite(bip->u.int8, bip->count * db5_type_sizeof_h_binu(bip->type),
		   1, fp) != 1) {
	    bu_vls_printf(gedp->ged_result_str, "Error writing contents to file");
	    fclose(fp);
	    rt_db_free_internal(&intern);
	    return GED_ERROR;
	}

	fclose(fp);
	rt_db_free_internal(&intern);

    } else {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	return GED_ERROR;
    }

    return GED_OK;
}
int
ged_copyeval(struct ged *gedp, int argc, const char *argv[])
{
    static const char *usage = "path_to_old_prim new_prim";
    struct _ged_trace_data gtd;
    struct directory *dp;
    struct rt_db_internal *ip;
    struct rt_db_internal internal, new_int;

    char *tok;
    int endpos = 0;
    int i;
    mat_t start_mat;

    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;
    }

    /* initialize gtd */
    gtd.gtd_gedp = gedp;
    gtd.gtd_flag = _GED_CPEVAL;
    gtd.gtd_prflag = 0;

    /* check if new solid name already exists in description */
    GED_CHECK_EXISTS(gedp, argv[2], LOOKUP_QUIET, GED_ERROR);

    MAT_IDN(start_mat);

    /* build directory pointer array for desired path */
    if (strchr(argv[1], '/')) {
	tok = strtok((char *)argv[1], "/");
	while (tok) {
	    GED_DB_LOOKUP(gedp, gtd.gtd_obj[endpos], tok, LOOKUP_NOISY, GED_ERROR & GED_QUIET);
	    endpos++;
	    tok = strtok((char *)NULL, "/");
	}
    } else {
	GED_DB_LOOKUP(gedp, gtd.gtd_obj[endpos], argv[1], LOOKUP_NOISY, GED_ERROR & GED_QUIET);
	endpos++;
    }

    if (endpos < 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    gtd.gtd_objpos = endpos - 1;

    GED_DB_GET_INTERNAL(gedp, &internal, gtd.gtd_obj[endpos - 1], bn_mat_identity, &rt_uniresource, GED_ERROR);

    if (endpos > 1) {
	/* Make sure that final component in path is a solid */
	if (internal.idb_type == ID_COMBINATION) {
	    rt_db_free_internal(&internal);
	    bu_vls_printf(gedp->ged_result_str, "final component on path must be a primitive!\n");
	    return GED_ERROR;
	}

	/* Accumulate the matrices */
	ged_trace(gtd.gtd_obj[0], 0, start_mat, &gtd, 1);

	if (gtd.gtd_prflag == 0) {
	    bu_vls_printf(gedp->ged_result_str, "PATH:  ");

	    for (i = 0; i < gtd.gtd_objpos; i++)
		bu_vls_printf(gedp->ged_result_str, "/%s", gtd.gtd_obj[i]->d_namep);

	    bu_vls_printf(gedp->ged_result_str, "  NOT FOUND\n");
	    rt_db_free_internal(&internal);
	    return GED_ERROR;
	}

	/* Have found the desired path - wdb_xform is the transformation matrix */
	/* wdb_xform matrix calculated in wdb_trace() */

	/* create the new solid */
	RT_DB_INTERNAL_INIT(&new_int);
	if (rt_generic_xform(&new_int, gtd.gtd_xform,
			     &internal, 0, gedp->ged_wdbp->dbip, &rt_uniresource)) {
	    rt_db_free_internal(&internal);
	    bu_vls_printf(gedp->ged_result_str, "ged_copyeval: rt_generic_xform failed\n");
	    return GED_ERROR;
	}

	ip = &new_int;
    } else
	ip = &internal;

    /* should call GED_DB_DIRADD() but need to deal with freeing the
     * internals on failure.
     */
    dp=db_diradd(gedp->ged_wdbp->dbip, argv[2], RT_DIR_PHONY_ADDR, 0, gtd.gtd_obj[endpos-1]->d_flags, (void *)&ip->idb_type);
    if (dp == RT_DIR_NULL) {
	rt_db_free_internal(&internal);
	if (ip == &new_int)
	    rt_db_free_internal(&new_int);
	bu_vls_printf(gedp->ged_result_str, "An error has occurred while adding a new object to the database.");
	return GED_ERROR;
    }

    /* should call GED_DB_DIRADD() but need to deal with freeing the
     * internals on failure.
     */
    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, ip, &rt_uniresource) < 0) {
	/* if (ip == &new_int) then new_int gets freed by the rt_db_put_internal above
	 * regardless of whether it succeeds or not. At this point only internal needs
	 * to be freed. On the other hand if (ip == &internal), the internal gets freed
	 * freed by the rt_db_put_internal above. In this case memory for new_int has
	 * not been allocated.
	 */
	if (ip == &new_int)
	    rt_db_free_internal(&internal);

	bu_vls_printf(gedp->ged_result_str, "Database write error, aborting");
	return GED_ERROR;
    }

    /* see previous comment */
    if (ip == &new_int)
	rt_db_free_internal(&internal);

    return GED_OK;
}
Пример #29
0
HIDDEN int
move_all_func(struct ged *gedp, int nflag, const char *old_name, const char *new_name)
{
    int i;
    struct ged_display_list *gdlp;
    struct directory *dp;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    struct bu_ptbl stack;

    /* rename the record itself */
    if ((dp = db_lookup(gedp->ged_wdbp->dbip, old_name, LOOKUP_NOISY)) == RT_DIR_NULL)
	return GED_ERROR;

    if (db_lookup(gedp->ged_wdbp->dbip, new_name, LOOKUP_QUIET) != RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s: already exists", new_name);
	return GED_ERROR;
    }

    /* if this was a sketch, we need to look for all the extrude
     * objects that might use it.
     *
     * This has to be done here, before we rename the (possible) sketch object
     * because the extrude will do a rt_db_get on the sketch when we call
     * rt_db_get_internal on it.
     */
    if (dp->d_major_type == DB5_MAJORTYPE_BRLCAD && \
	dp->d_minor_type == DB5_MINORTYPE_BRLCAD_SKETCH) {

	struct directory *dirp;

	for (i = 0; i < RT_DBNHASH; i++) {
	    for (dirp = gedp->ged_wdbp->dbip->dbi_Head[i]; dirp != RT_DIR_NULL; dirp = dirp->d_forw) {

		if (dirp->d_major_type == DB5_MAJORTYPE_BRLCAD && \
		    dirp->d_minor_type == DB5_MINORTYPE_BRLCAD_EXTRUDE) {
		    struct rt_extrude_internal *extrude;

		    if (rt_db_get_internal(&intern, dirp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
			bu_log("Can't get extrude %s?\n", dirp->d_namep);
			continue;
		    }
		    extrude = (struct rt_extrude_internal *)intern.idb_ptr;
		    RT_EXTRUDE_CK_MAGIC(extrude);

		    if (BU_STR_EQUAL(extrude->sketch_name, old_name)) {
			if (nflag) {
			    bu_vls_printf(gedp->ged_result_str, "%s ", dirp->d_namep);
			    rt_db_free_internal(&intern);
			} else {
			    bu_free(extrude->sketch_name, "sketch name");
			    extrude->sketch_name = bu_strdup(new_name);

			    if (rt_db_put_internal(dirp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
				bu_log("oops\n");
			    }
			}
		    } else
			rt_db_free_internal(&intern);
		}
	    }
	}
    }

    if (!nflag) {
	/* Change object name in the directory. */
	if (db_rename(gedp->ged_wdbp->dbip, dp, new_name) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "error in rename to %s, aborting", new_name);
	    return GED_ERROR;
	}

	/* Change name in the file */
	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;
	}

	if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "Database write error, aborting");
	    return GED_ERROR;
	}
    }

    bu_ptbl_init(&stack, 64, "combination stack for wdb_mvall_cmd");


    /* Examine all COMB nodes */
    for (i = 0; i < RT_DBNHASH; i++) {
	for (dp = gedp->ged_wdbp->dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw) {
	    if (nflag) {
		union tree *comb_leaf;
		int done=0;

		if (!(dp->d_flags & RT_DIR_COMB)) continue;
		if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) continue;
		comb = (struct rt_comb_internal *)intern.idb_ptr;
		bu_ptbl_reset(&stack);
		/* visit each leaf in the combination */
		comb_leaf = comb->tree;
		if (comb_leaf) {
		    while (!done) {
			while (comb_leaf->tr_op != OP_DB_LEAF) {
			    bu_ptbl_ins(&stack, (long *)comb_leaf);
			    comb_leaf = comb_leaf->tr_b.tb_left;
			}

			if (BU_STR_EQUAL(comb_leaf->tr_l.tl_name, old_name)) {
			    bu_vls_printf(gedp->ged_result_str, "%s ", dp->d_namep);
			}

			if (BU_PTBL_END(&stack) < 1) {
			    done = 1;
			    break;
			}
			comb_leaf = (union tree *)BU_PTBL_GET(&stack, BU_PTBL_END(&stack)-1);
			if (comb_leaf->tr_op != OP_DB_LEAF) {
			    bu_ptbl_rm(&stack, (long *)comb_leaf);
			    comb_leaf = comb_leaf->tr_b.tb_right;
			}
		    }
		}
		rt_db_free_internal(&intern);
	    } else {
		int comb_mvall_status = db_comb_mvall(dp, gedp->ged_wdbp->dbip, old_name, new_name, &stack);
		if (!comb_mvall_status) continue;
		if (comb_mvall_status == 2) {
		    bu_ptbl_free(&stack);
		    bu_vls_printf(gedp->ged_result_str, "Database write error, aborting");
		    return GED_ERROR;
		}
	    }
	}
    }

    bu_ptbl_free(&stack);

    if (!nflag) {
	/* Change object name anywhere in the display list path. */
	for (BU_LIST_FOR(gdlp, ged_display_list, gedp->ged_gdp->gd_headDisplay)) {
	    int first = 1;
	    int found = 0;
	    struct bu_vls new_path = BU_VLS_INIT_ZERO;
	    char *dupstr = strdup(bu_vls_addr(&gdlp->gdl_path));
	    char *tok = strtok(dupstr, "/");

	    while (tok) {
		if (BU_STR_EQUAL(tok, old_name)) {
		    found = 1;

		    if (first) {
			first = 0;
			bu_vls_printf(&new_path, "%s", new_name);
		    } else
			bu_vls_printf(&new_path, "/%s", new_name);
		} else {
		    if (first) {
			first = 0;
			bu_vls_printf(&new_path, "%s", tok);
		    } else
			bu_vls_printf(&new_path, "/%s", tok);
		}

		tok = strtok((char *)NULL, "/");
	    }

	    if (found) {
		bu_vls_free(&gdlp->gdl_path);
		bu_vls_printf(&gdlp->gdl_path, "%s", bu_vls_addr(&new_path));
	    }

	    free((void *)dupstr);
	    bu_vls_free(&new_path);
	}
    }

    return GED_OK;
}
Пример #30
0
void
db_fullpath_to_vls(struct bu_vls *vls, const struct db_full_path *full_path, const struct db_i *dbip, int fp_flags)
{
    size_t i;
    int type;
    const struct bn_tol tol = {BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST * BN_TOL_DIST, 1e-6, 1.0 - 1e-6 };
    BU_CK_VLS(vls);
    RT_CK_FULL_PATH(full_path);

    if (!full_path->fp_names[0]) {
	bu_vls_strcat(vls, "**NULL**");
	return;
    }

    if ((fp_flags & DB_FP_PRINT_TYPE) && !dbip) {
	bu_log("Warning - requested object type printing, but dbip is NULL - object types will not be printed!");
    }

    for (i = 0; i < full_path->fp_len; i++) {
	bu_vls_putc(vls, '/');
	if (fp_flags & DB_FP_PRINT_BOOL) {
	    switch (full_path->fp_bool[i]) {
		case 2:
		    bu_vls_strcat(vls, "u ");
		    break;
		case 3:
		    bu_vls_strcat(vls, "+ ");
		    break;
		case 4:
		    bu_vls_strcat(vls, "- ");
		    break;
	    }
	}
	if (fp_flags & DB_FP_PRINT_MATRIX) {
	    if (full_path->fp_mat[i]) {
		bu_vls_strcat(vls, "(M)");
	    }
	}

	bu_vls_strcat(vls, full_path->fp_names[i]->d_namep);
	if ((fp_flags & DB_FP_PRINT_TYPE) && dbip) {
	    struct rt_db_internal intern;
	    if (!(rt_db_get_internal(&intern, full_path->fp_names[i], dbip, NULL, &rt_uniresource) < 0)) {
		if (intern.idb_meth->ft_label) {
		    bu_vls_putc(vls, '(');
		    switch (intern.idb_minor_type) {
			case DB5_MINORTYPE_BRLCAD_ARB8:
			    type = rt_arb_std_type(&intern, &tol);
			    switch (type) {
				case 4:
				    bu_vls_strcat(vls, "arb4");
				    break;
				case 5:
				    bu_vls_strcat(vls, "arb5");
				    break;
				case 6:
				    bu_vls_strcat(vls, "arb6");
				    break;
				case 7:
				    bu_vls_strcat(vls, "arb7");
				    break;
				case 8:
				    bu_vls_strcat(vls, "arb8");
				    break;
				default:
				    break;
			    }
			    break;
			case DB5_MINORTYPE_BRLCAD_COMBINATION:
			    if (full_path->fp_names[i]->d_flags & RT_DIR_REGION) {
				bu_vls_putc(vls, 'r');
			    } else {
				bu_vls_putc(vls, 'c');
			    }
			    break;
			default:
			    bu_vls_strcat(vls, intern.idb_meth->ft_label);
			    break;
		    }

		}
		bu_vls_putc(vls, ')');
		rt_db_free_internal(&intern);
	    }
	}

    }
}