Ejemplo n.º 1
0
static const char *
save_comb(struct ged *gedp, struct directory *dpold)
{
    /* Save a combination under a temporary name */

    struct directory *dp;
    struct rt_db_internal intern;

    /* Make a new name */
    const char *name = mktemp_comb(gedp, tmpcomb);

    if (rt_db_get_internal(&intern, dpold, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
	bu_vls_printf(gedp->ged_result_str, "save_comb: Database read error, aborting\n");
	return NULL;
    }

    if ((dp = db_diradd(gedp->ged_wdbp->dbip, name, RT_DIR_PHONY_ADDR, 0, dpold->d_flags, (genptr_t)&intern.idb_type)) == RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "save_comb: Cannot save copy of %s, no changed made\n", dpold->d_namep);
	return NULL;
    }

    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
	bu_vls_printf(gedp->ged_result_str, "save_comb: Cannot save copy of %s, no changed made\n", dpold->d_namep);
	return NULL;
    }

    return name;
}
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);
    }
}
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;
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
/**
 * make n copies of a v5 combination.
 */
static struct directory *
copy_v5_comb(struct db_i *_dbip, struct directory *proto, struct clone_state *state, int idx)
{
    struct directory *dp = (struct directory *)NULL;
    struct bu_vls *name;
    size_t i;

    /* sanity */
    if (!proto) {
	bu_log("ERROR: clone internal consistency error\n");
	return (struct directory *)NULL;
    }

    /* make n copies */
    for (i = 0; i < state->n_copies; i++) {
	if (i==0)
	    name = get_name(_dbip, proto, state, i);
	else {
	    dp = db_lookup(_dbip, bu_vls_addr(&obj_list.names[idx].dest[i-1]), LOOKUP_QUIET);
	    if (!dp) {
		continue;
	    }
	    name = get_name(_dbip, dp, state, i);
	}
	bu_vls_strcpy(&obj_list.names[idx].dest[i], bu_vls_addr(name));

	/* we have a before and an after, do the copy */
	if (proto->d_namep && bu_vls_addr(name)) {
	    struct rt_db_internal dbintern;
	    struct rt_comb_internal *comb;

	    dp = db_lookup(_dbip, proto->d_namep, LOOKUP_QUIET);
	    if (!dp) {
		bu_vls_free(name);
		continue;
	    }
	    if (rt_db_get_internal(&dbintern, dp, _dbip, bn_mat_identity, &rt_uniresource) < 0) {
		bu_log("ERROR: clone internal error copying %s\n", proto->d_namep);
		return NULL;
	    }

	    if ((dp=db_diradd(wdbp->dbip, bu_vls_addr(name), -1, 0, proto->d_flags, (genptr_t)&proto->d_minor_type)) == RT_DIR_NULL) {
		bu_log("An error has occurred while adding a new object to the database.");
		return NULL;
	    }

	    RT_CK_DB_INTERNAL(&dbintern);
	    comb = (struct rt_comb_internal *)dbintern.idb_ptr;
	    RT_CK_COMB(comb);
	    RT_CK_TREE(comb->tree);

	    /* recursively update the tree */
	    copy_v5_comb_tree(comb->tree, i);

	    if (rt_db_put_internal(dp, wdbp->dbip, &dbintern, &rt_uniresource) < 0) {
		bu_log("ERROR: clone internal error copying %s\n", proto->d_namep);
		bu_vls_free(name);
		return NULL;
	    }
	    bu_vls_free(name);
	    rt_db_free_internal(&dbintern);
	}

	/* done with this name */
	bu_vls_free(name);
    }

    return dp;
}
Ejemplo n.º 8
0
/**
 * make a copy of a v5 solid by adding it to our book-keeping list,
 * adding it to the db directory, and writing it out to disk.
 */
static void
copy_v5_solid(struct db_i *_dbip, struct directory *proto, struct clone_state *state, int idx)
{
    size_t i;
    mat_t matrix;

    MAT_IDN(matrix);

    /* mirror */
    if (state->miraxis != W) {
	matrix[state->miraxis*5] = -1.0;
	matrix[3 + state->miraxis*4] -= 2 * (matrix[3 + state->miraxis*4] - state->mirpos);
    }

    /* translate */
    if (state->trans[W] > SMALL_FASTF)
	MAT_DELTAS_ADD_VEC(matrix, state->trans);

    /* rotation */
    if (state->rot[W] > SMALL_FASTF) {
	mat_t m2, t;

	bn_mat_angles(m2, state->rot[X], state->rot[Y], state->rot[Z]);
	if (state->rpnt[W] > SMALL_FASTF) {
	    mat_t m3;

	    bn_mat_xform_about_pt(m3, m2, state->rpnt);
	    bn_mat_mul(t, matrix, m3);
	} else
	    bn_mat_mul(t, matrix, m2);

	MAT_COPY(matrix, t);
    }

    /* make n copies */
    for (i = 0; i < state->n_copies; i++) {
	char *argv[6] = {"wdb_copy", (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL};
	struct bu_vls *name;
	int ret;
	struct directory *dp = (struct directory *)NULL;
	struct rt_db_internal intern;

	if (i==0)
	    dp = proto;
	else
	    dp = db_lookup(_dbip, bu_vls_addr(&obj_list.names[idx].dest[i-1]), LOOKUP_QUIET);

	if (!dp) {
	    continue;
	}

	name = get_name(_dbip, dp, state, i); /* get new name */
	bu_vls_strcpy(&obj_list.names[idx].dest[i], bu_vls_addr(name));

	/* actually copy the primitive to the new name */
	argv[1] = proto->d_namep;
	argv[2] = bu_vls_addr(name);
	ret = wdb_copy_cmd(_dbip->dbi_wdbp, 3, (const char **)argv);
	if (ret != TCL_OK)
	    bu_log("WARNING: failure cloning \"%s\" to \"%s\"\n", proto->d_namep, bu_vls_addr(name));

	/* get the original objects matrix */
	if (rt_db_get_internal(&intern, dp, _dbip, matrix, &rt_uniresource) < 0) {
	    bu_log("ERROR: clone internal error copying %s\n", proto->d_namep);
	    bu_vls_free(name);
	    return;
	}
	RT_CK_DB_INTERNAL(&intern);
	/* pull the new name */
	dp = db_lookup(_dbip, bu_vls_addr(name), LOOKUP_QUIET);
	bu_vls_free(name);
	if (!dp) {
	    bu_vls_free(name);
	    continue;
	}

	/* write the new matrix to the new object */
	if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0)
	    bu_log("ERROR: clone internal error copying %s\n", proto->d_namep);
	rt_db_free_internal(&intern);
    } /* end iteration over each copy */

    return;
}
Ejemplo n.º 9
0
int
ged_shells(struct ged *gedp, int argc, const char *argv[])
{
    struct directory *old_dp, *new_dp;
    struct rt_db_internal old_intern, new_intern;
    struct model *m_tmp, *m;
    struct nmgregion *r_tmp, *r;
    struct shell *s_tmp, *s;
    int shell_count=0;
    struct bu_vls shell_name = BU_VLS_INIT_ZERO;
    long **trans_tbl;
    static const char *usage = "nmg_model";

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);

    /* initialize result */
    bu_vls_trunc(gedp->ged_result_str, 0);

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

    if (argc != 2) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

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

    if (rt_db_get_internal(&old_intern, old_dp, gedp->ged_wdbp->dbip, bn_mat_identity, &rt_uniresource) < 0) {
	bu_vls_printf(gedp->ged_result_str, "rt_db_get_internal() error\n");
	return GED_ERROR;
    }

    if (old_intern.idb_type != ID_NMG) {
	bu_vls_printf(gedp->ged_result_str, "Object is not an NMG!!!\n");
	return GED_ERROR;
    }

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

    for (BU_LIST_FOR(r, nmgregion, &m->r_hd)) {
	for (BU_LIST_FOR(s, shell, &r->s_hd)) {
	    s_tmp = nmg_dup_shell(s, &trans_tbl, &gedp->ged_wdbp->wdb_tol);
	    bu_free((void *)trans_tbl, "trans_tbl");

	    m_tmp = nmg_mmr();
	    r_tmp = BU_LIST_FIRST(nmgregion, &m_tmp->r_hd);

	    BU_LIST_DEQUEUE(&s_tmp->l);
	    BU_LIST_APPEND(&r_tmp->s_hd, &s_tmp->l);
	    s_tmp->r_p = r_tmp;
	    nmg_m_reindex(m_tmp, 0);
	    nmg_m_reindex(m, 0);

	    bu_vls_printf(&shell_name, "shell.%d", shell_count);
	    while (db_lookup(gedp->ged_wdbp->dbip, bu_vls_addr(&shell_name), 0) != RT_DIR_NULL) {
		bu_vls_trunc(&shell_name, 0);
		shell_count++;
		bu_vls_printf(&shell_name, "shell.%d", shell_count);
	    }

	    /* Export NMG as a new solid */
	    RT_DB_INTERNAL_INIT(&new_intern);
	    new_intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
	    new_intern.idb_type = ID_NMG;
	    new_intern.idb_meth = &OBJ[ID_NMG];
	    new_intern.idb_ptr = (void *)m_tmp;

	    new_dp=db_diradd(gedp->ged_wdbp->dbip, bu_vls_addr(&shell_name), RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&new_intern.idb_type);
	    if (new_dp == RT_DIR_NULL) {
		bu_vls_printf(gedp->ged_result_str, "An error has occurred while adding a new object to the database.\n");
		return GED_ERROR;
	    }

	    /* make sure the geometry/bounding boxes are up to date */
	    nmg_rebound(m_tmp, &gedp->ged_wdbp->wdb_tol);

	    if (rt_db_put_internal(new_dp, gedp->ged_wdbp->dbip, &new_intern, &rt_uniresource) < 0) {
		/* Free memory */
		nmg_km(m_tmp);
		bu_vls_printf(gedp->ged_result_str, "rt_db_put_internal() failure\n");
		return GED_ERROR;
	    }
	    /* Internal representation has been freed by rt_db_put_internal */
	    new_intern.idb_ptr = (void *)NULL;
	}
    }
    bu_vls_free(&shell_name);

    return GED_OK;
}
Ejemplo n.º 10
0
static int
copy_object(struct ged *gedp,
	    struct directory *input_dp,
	    struct db_i *input_dbip,
	    struct db_i *curr_dbip,
	    Tcl_HashTable *name_tbl,
	    Tcl_HashTable *used_names_tbl,
	    struct ged_concat_data *cc_data)
{
    struct rt_db_internal ip;
    struct rt_extrude_internal *extr;
    struct rt_dsp_internal *dsp;
    struct rt_comb_internal *comb;
    struct directory *new_dp;
    char *new_name;

    if (rt_db_get_internal(&ip, input_dp, input_dbip, NULL, &rt_uniresource) < 0) {
	bu_vls_printf(gedp->ged_result_str,
		      "Failed to get internal form of object (%s) - aborting!!!\n",
		      input_dp->d_namep);
	return GED_ERROR;
    }

    if (ip.idb_major_type == DB5_MAJORTYPE_BRLCAD) {
	/* adjust names of referenced object in any object that reference other objects */
	switch (ip.idb_minor_type) {
	    case DB5_MINORTYPE_BRLCAD_COMBINATION:
		comb = (struct rt_comb_internal *)ip.idb_ptr;
		RT_CK_COMB(comb);
		adjust_names(comb->tree, curr_dbip, name_tbl, used_names_tbl, cc_data);
		break;
	    case DB5_MINORTYPE_BRLCAD_EXTRUDE:
		extr = (struct rt_extrude_internal *)ip.idb_ptr;
		RT_EXTRUDE_CK_MAGIC(extr);

		new_name = get_new_name(extr->sketch_name, curr_dbip, name_tbl, used_names_tbl, cc_data);
		if (new_name) {
		    bu_free(extr->sketch_name, "sketch name");
		    extr->sketch_name = bu_strdup(new_name);
		}
		break;
	    case DB5_MINORTYPE_BRLCAD_DSP:
		dsp = (struct rt_dsp_internal *)ip.idb_ptr;
		RT_DSP_CK_MAGIC(dsp);

		if (dsp->dsp_datasrc == RT_DSP_SRC_OBJ) {
		    /* This dsp references a database object, may need to change its name */
		    new_name = get_new_name(bu_vls_addr(&dsp->dsp_name), curr_dbip,
						name_tbl, used_names_tbl, cc_data);
		    if (new_name) {
			bu_vls_free(&dsp->dsp_name);
			bu_vls_strcpy(&dsp->dsp_name, new_name);
		    }
		}
		break;
	}
    }

    new_name = get_new_name(input_dp->d_namep, curr_dbip, name_tbl, used_names_tbl, cc_data);
    if (!new_name) {
	new_name = input_dp->d_namep;
    }
    if ((new_dp = db_diradd(curr_dbip, new_name, RT_DIR_PHONY_ADDR, 0, input_dp->d_flags,
			    (void *)&input_dp->d_minor_type)) == RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str,
		      "Failed to add new object name (%s) to directory - aborting!!\n",
		      new_name);
	return GED_ERROR;
    }

    if (rt_db_put_internal(new_dp, curr_dbip, &ip, &rt_uniresource) < 0) {
	bu_vls_printf(gedp->ged_result_str,
		      "Failed to write new object (%s) to database - aborting!!\n",
		      new_name);
	return GED_ERROR;
    }

    return GED_OK;
}
Ejemplo n.º 11
0
static int
make_tree(struct ged *gedp, struct rt_comb_internal *comb, struct directory *dp, size_t node_count, const char *old_name, const char *new_name, struct rt_tree_array *rt_tree_array, int tree_index)
{
    struct rt_db_internal intern;
    union tree *final_tree;

    if (tree_index)
	final_tree = (union tree *)db_mkgift_tree(rt_tree_array, node_count, &rt_uniresource);
    else
	final_tree = (union tree *)NULL;

    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;
    comb->tree = final_tree;

    if (!BU_STR_EQUAL(new_name, old_name)) {
	int flags;

	if (comb->region_flag)
	    flags = RT_DIR_COMB | RT_DIR_REGION;
	else
	    flags = RT_DIR_COMB;

	if (dp != RT_DIR_NULL) {
	    if (db_delete(gedp->ged_wdbp->dbip, dp) || db_dirdelete(gedp->ged_wdbp->dbip, dp)) {
		bu_vls_printf(gedp->ged_result_str, "make_tree: Unable to delete directory entry for %s\n", old_name);
		intern.idb_meth->ft_ifree(&intern);
		return GED_ERROR;
	    }
	}

	if ((dp=db_diradd(gedp->ged_wdbp->dbip, new_name, RT_DIR_PHONY_ADDR, 0, flags, (genptr_t)&intern.idb_type)) == RT_DIR_NULL) {
	    bu_vls_printf(gedp->ged_result_str, "make_tree: Cannot add %s to directory, no changes made\n", new_name);
	    intern.idb_meth->ft_ifree(&intern);
	    return 1;
	}
    } else if (dp == RT_DIR_NULL) {
	int flags;

	if (comb->region_flag)
	    flags = RT_DIR_COMB | RT_DIR_REGION;
	else
	    flags = RT_DIR_COMB;

	if ((dp=db_diradd(gedp->ged_wdbp->dbip, new_name, RT_DIR_PHONY_ADDR, 0, flags, (genptr_t)&intern.idb_type)) == RT_DIR_NULL) {
	    bu_vls_printf(gedp->ged_result_str, "make_tree: Cannot add %s to directory, no changes made\n", new_name);
	    intern.idb_meth->ft_ifree(&intern);
	    return GED_ERROR;
	}
    } else {
	if (comb->region_flag)
	    dp->d_flags |= RT_DIR_REGION;
	else
	    dp->d_flags &= ~RT_DIR_REGION;
    }

    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
	bu_vls_printf(gedp->ged_result_str, "make_tree: Unable to write new combination into database.\n");
	return GED_ERROR;
    }

    return GED_OK;
}
Ejemplo n.º 12
0
int
ged_remove(struct ged *gedp, int argc, const char *argv[])
{
    struct directory *dp;
    int i;
    int num_deleted;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    int ret;
    static const char *usage = "comb object(s)";

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_DRAWABLE(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 ((dp->d_flags & RT_DIR_COMB) == 0) {
	bu_vls_printf(gedp->ged_result_str, "rm: %s is not a combination", dp->d_namep);
	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;
    }

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

    /* Process each argument */
    num_deleted = 0;
    ret = TCL_OK;
    for (i = 2; i < argc; i++) {
	if (db_tree_del_dbleaf(&(comb->tree), argv[i], &rt_uniresource, 0) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "ERROR: Failure deleting %s/%s\n", dp->d_namep, argv[i]);
	    ret = GED_ERROR;
	} else {
	    struct bu_vls path = BU_VLS_INIT_ZERO;

	    bu_vls_printf(&path, "%s/%s", dp->d_namep, argv[i]);
	    _ged_eraseAllPathsFromDisplay(gedp, bu_vls_addr(&path), 0);
	    bu_vls_free(&path);
	    bu_vls_printf(gedp->ged_result_str, "deleted %s/%s\n", dp->d_namep, argv[i]);
	    num_deleted++;
	}
    }

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

    return ret;
}
Ejemplo n.º 13
0
int
ged_mirror(struct ged *gedp, int argc, const char *argv[])
{
    /* trailing x|y|z intentionally not documented */
    static const char *usage = "[-h] [-p \"point\"] [-d \"dir\"] [-x|-y|-z] [-o offset] old new";

    int k;

    point_t mirror_pt = {0.0, 0.0, 0.0};
    vect_t mirror_dir = {1.0, 0.0, 0.0};

    /* intentionally double for scanning */
    double scanpt[3];
    double scandir[3];
    double mirror_offset = 0.0;

    int ret;
    struct rt_db_internal *ip;
    struct rt_db_internal internal;
    struct directory *dp;

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

    bu_optind = 1;
    while ((k = bu_getopt(argc, (char * const *)argv, (const char *)"d:D:hHo:O:p:P:xXyYzZ")) != -1) {
	switch (k) {
	    case 'p':
	    case 'P':
		if (sscanf(bu_optarg, "%lf %lf %lf",
			   &scanpt[X],
			   &scanpt[Y],
			   &scanpt[Z]) != 3) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}

		/* convert from double to fastf_t */
		VMOVE(mirror_pt, scanpt);

		break;
	    case 'd':
	    case 'D':
		if (sscanf(bu_optarg, "%lf %lf %lf",
			   &scandir[X],
			   &scandir[Y],
			   &scandir[Z]) != 3) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}

		/* convert from double to fastf_t */
		VMOVE(mirror_dir, scandir);

		break;
	    case 'o':
	    case 'O':
		if (sscanf(bu_optarg, "%lf", &mirror_offset) != 1) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}
		break;
	    case 'x':
	    case 'X':
		VSET(mirror_dir, 1.0, 0.0, 0.0);
		break;
	    case 'y':
	    case 'Y':
		VSET(mirror_dir, 0.0, 1.0, 0.0);
		break;
	    case 'z':
	    case 'Z':
		VSET(mirror_dir, 0.0, 0.0, 1.0);
		break;
	    case 'h':
	    case 'H':
		bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		return GED_HELP;
	    default:
		bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		return GED_ERROR;
		break;
	}
    }

    argc -= bu_optind;

    if (argc < 2 || argc > 4) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    } else if (argc == 3) {
	/* support a trailing x|y|z option as classic command
	 * behavior.  THIS IS INTENTIONALLY UNDOCUMENTED.  if users
	 * have to read the usage, they can learn the new form.
	 */
	switch (argv[bu_optind+2][0]) {
	    case 'x':
	    case 'X':
		VSET(mirror_dir, 1.0, 0.0, 0.0);
		break;
	    case 'y':
	    case 'Y':
		VSET(mirror_dir, 0.0, 1.0, 0.0);
		break;
	    case 'z':
	    case 'Z':
		VSET(mirror_dir, 0.0, 0.0, 1.0);
		break;
	    default:
		bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		return GED_ERROR;
		break;
	}
    }

    /* make sure object mirroring to does not already exist */
    if (db_lookup(gedp->ged_wdbp->dbip, argv[bu_optind+1], LOOKUP_QUIET) != RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s already exists\n", argv[bu_optind+1]);
	return GED_ERROR;
    }

    /* look up the object being mirrored */
    if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[bu_optind], LOOKUP_NOISY)) == RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "Unable to find solid [%s]\n", argv[bu_optind]);
	return GED_ERROR;
    }

    /* get object being mirrored */
    ret = rt_db_get_internal(&internal, dp, gedp->ged_wdbp->dbip, NULL, gedp->ged_wdbp->wdb_resp);
    if (ret < 0) {
	bu_vls_printf(gedp->ged_result_str, "Unable to load solid [%s]\n", argv[bu_optind]);
	return GED_ERROR;
    }

    mirror_offset *= gedp->ged_wdbp->dbip->dbi_local2base;
    VUNITIZE(mirror_dir);
    VJOIN1(mirror_pt, mirror_pt, mirror_offset, mirror_dir);

    /* mirror the object */
    ip = rt_mirror(gedp->ged_wdbp->dbip,
		   &internal,
		   mirror_pt,
		   mirror_dir,
		   gedp->ged_wdbp->wdb_resp);
    if (ip == NULL) {
	bu_vls_printf(gedp->ged_result_str, "Unable to mirror [%s]", argv[bu_optind]);
	return GED_ERROR;
    }

    /* add the mirrored object to the directory */
    dp = db_diradd(gedp->ged_wdbp->dbip, argv[bu_optind+1], RT_DIR_PHONY_ADDR, 0, dp->d_flags, (void *)&ip->idb_type);
    if (dp == RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "Unable to add [%s] to the database directory", argv[bu_optind+1]);
	return GED_ERROR;
    }
    /* save the mirrored object to disk */
    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, ip, gedp->ged_wdbp->wdb_resp) < 0) {
	bu_vls_printf(gedp->ged_result_str, "Unable to store [%s] to the database", argv[bu_optind+1]);
	return GED_ERROR;
    }

    {
	/* draw the new object */
	const char *object = (const char *)argv[bu_optind+1];
	const char *e_argv[3] = {0, 0, 0};

	e_argv[0] = "draw";
	e_argv[1] = object;
	e_argv[2] = NULL;

	(void)ged_draw(gedp, 2, e_argv);
	ged_view_update(gedp->ged_gvp);
    }

    return GED_OK;
}
Ejemplo n.º 14
0
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);
}
Ejemplo n.º 15
0
void
pop_functree(struct db_i *dbi_p, struct db_i *dbi_c,
	     union tree *tp,
	     struct resource *resp,
	     char *name
    )
{
    struct directory *dp;
    struct rt_db_internal in;
    char shape[256];

    if ( !tp ) {
	return;
    }
    if (crossover) {
	if (node_idx > crossover_node) return;
	if (node_idx == crossover_node) {
	    crossover_point = tp;
	    ++node_idx;
	    return;
	}
	else
	    ++node_idx;
    } else if (mutate)
	++node_idx;

    switch ( tp->tr_op )  {

	case OP_DB_LEAF:
	    /* dont need to do any processing if crossing over */
	    if (crossover) {
		return;
	    }


	    /* if we aren't crossing over, we copy the individual into the
	     * new database. If we're mutating, mutate the object after loading
	     * the internal object */

	    if ( !rt_db_lookup_internal(dbi_p, tp->tr_l.tl_name, &dp, &in, LOOKUP_NOISY, resp))
		bu_exit(EXIT_FAILURE, "Failed to read parent");

	    /* rename leaf based on individual it belongs to */
	    snprintf(shape, 256, "%s-%.3d", name, shape_number++);
	    bu_free(tp->tr_l.tl_name, "bu_strdup");
	    tp->tr_l.tl_name = bu_strdup(shape);

	    /* if we're mutating, and this is the node we've chosen
	     * to modify. mutate this node */
	    if ( mutate && node_idx == crossover_node )
		pop_mutate(in.idb_minor_type, in.idb_ptr);


	    /* write child to new database */
	    if ((dp=db_diradd(dbi_c, shape, -1, 0, dp->d_flags, (genptr_t)&dp->d_minor_type)) == RT_DIR_NULL)
		bu_exit(EXIT_FAILURE, "Failed to add new object to the database");
	    if (rt_db_put_internal(dp, dbi_c, &in, resp) < 0)
		bu_exit(EXIT_FAILURE, "Failed to write new individual to database");
	    rt_db_free_internal(&in);

	    break;

	case OP_UNION:
	case OP_INTERSECT:
	case OP_SUBTRACT:
	case OP_XOR:
	    /* mutate CSG operation */
	    if (mutate)
		if (node_idx == crossover_node) {
		    /*  tp->tr_op = (int)(2+pop_rand()*3);//FIXME: pop_rand() can be 1!*/
		}

	    /* if we're performing, save parent as its right or left pointer will need
	     * to be modified to point to the new child node */
	    if (crossover && node_idx == crossover_node)
		crossover_parent = &tp->tr_b.tb_left;
	    pop_functree( dbi_p, dbi_c, tp->tr_b.tb_left, resp, name);
	    if (crossover && node_idx == crossover_node)
		crossover_parent = &tp->tr_b.tb_right;
	    pop_functree( dbi_p, dbi_c, tp->tr_b.tb_right, resp, name);
	    break;

	default:
	    bu_exit(EXIT_FAILURE,  "pop_functree: unrecognized operator\n" );
    }
}
Ejemplo n.º 16
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;
}
Ejemplo n.º 17
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;
}
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;
}