Exemple #1
0
int
ged_copy(struct ged *gedp, int argc, const char *argv[])
{
    struct directory *from_dp;
    struct bu_external external;
    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;
    }

    GED_DB_LOOKUP(gedp, from_dp, argv[1], LOOKUP_NOISY, GED_ERROR & GED_QUIET);
    GED_CHECK_EXISTS(gedp, argv[2], LOOKUP_QUIET, GED_ERROR);

    if (db_get_external(&external, from_dp, gedp->ged_wdbp->dbip)) {
	bu_vls_printf(gedp->ged_result_str, "Database read error, aborting\n");
	return GED_ERROR;
    }

    if (wdb_export_external(gedp->ged_wdbp, &external, argv[2],
			    from_dp->d_flags,  from_dp->d_minor_type) < 0) {
	bu_free_external(&external);
	bu_vls_printf(gedp->ged_result_str,
		      "Failed to write new object (%s) to database - aborting!!\n",
		      argv[2]);
	return GED_ERROR;
    }

    bu_free_external(&external);

    return GED_OK;
}
Exemple #2
0
int
ged_bev(struct ged *gedp, int argc, const char *argv[])
{
    static const char *usage = "[P|t] new_obj obj1 op obj2 op obj3 ...";

    int i;
    int c;
    int ncpu;
    char *cmdname;
    char *newname;
    struct rt_db_internal intern;
    struct directory *dp;
    char op;
    int failed;

    /* static due to longjmp */
    static int triangulate = 0;
    static union tree *tmp_tree = NULL;

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

    cmdname = (char *)argv[0];

    /* Establish tolerances */
    gedp->ged_wdbp->wdb_initial_tree_state.ts_ttol = &gedp->ged_wdbp->wdb_ttol;
    gedp->ged_wdbp->wdb_initial_tree_state.ts_tol = &gedp->ged_wdbp->wdb_tol;

    gedp->ged_wdbp->wdb_ttol.magic = RT_TESS_TOL_MAGIC;

    /* Initial values for options, must be reset each time */
    ncpu = 1;
    triangulate = 0;

    /* Parse options. */
    bu_optind = 1;		/* re-init bu_getopt() */
    while ((c=bu_getopt(argc, (char * const *)argv, "tP:")) != -1) {
	switch (c) {
	    case 'P':
#if 0
		/* not yet supported */
		ncpu = atoi(bu_optarg);
#endif
		break;
	    case 't':
		triangulate = 1;
		break;
	    default: {
		bu_vls_printf(gedp->ged_result_str, "%s: option '%c' unknown\n", cmdname, c);
	    }

		break;
	}
    }
    argc -= bu_optind;
    argv += bu_optind;

    newname = (char *)argv[0];
    argv++;
    argc--;

    if (argc < 1) {
	bu_vls_printf(gedp->ged_result_str, "%s: Nothing to evaluate!!!\n", cmdname);
	return GED_ERROR;
    }

    GED_CHECK_EXISTS(gedp, newname, LOOKUP_QUIET, GED_ERROR);

    bu_vls_printf(gedp->ged_result_str,
		  "%s:  tessellating primitives with tolerances a=%g, r=%g, n=%g\n",
		  argv[0],
		  gedp->ged_wdbp->wdb_ttol.abs,
		  gedp->ged_wdbp->wdb_ttol.rel,
		  gedp->ged_wdbp->wdb_ttol.norm);

    bev_facetize_tree = (union tree *)0;
    bev_nmg_model = nmg_mm();
    gedp->ged_wdbp->wdb_initial_tree_state.ts_m = &bev_nmg_model;

    op = ' ';
    tmp_tree = (union tree *)NULL;

    while (argc) {
	i = db_walk_tree(gedp->ged_wdbp->dbip, 1, (const char **)argv,
			 ncpu,
			 &gedp->ged_wdbp->wdb_initial_tree_state,
			 0,			/* take all regions */
			 bev_facetize_region_end,
			 nmg_booltree_leaf_tess,
			 (genptr_t)gedp);

	if (i < 0) {
	    bu_vls_printf(gedp->ged_result_str, "%s: error in db_walk_tree()\n", cmdname);
	    /* Destroy NMG */
	    nmg_km(bev_nmg_model);
	    return GED_ERROR;
	}
	argc--;
	argv++;

	if (tmp_tree && op != ' ') {
	    union tree *new_tree;

	    BU_ALLOC(new_tree, union tree);
	    RT_TREE_INIT(new_tree);

	    new_tree->tr_b.tb_regionp = REGION_NULL;
	    new_tree->tr_b.tb_left = tmp_tree;
	    new_tree->tr_b.tb_right = bev_facetize_tree;

	    switch (op) {
		case 'u':
		case 'U':
		    new_tree->tr_op = OP_UNION;
		    break;
		case '-':
		    new_tree->tr_op = OP_SUBTRACT;
		    break;
		case '+':
		    new_tree->tr_op = OP_INTERSECT;
		    break;
		default: {
		    bu_vls_printf(gedp->ged_result_str, "%s: Unrecognized operator: (%c)\nAborting\n",
				  argv[0], op);
		    db_free_tree(bev_facetize_tree, &rt_uniresource);
		    nmg_km(bev_nmg_model);
		    return GED_ERROR;
		}
	    }

	    tmp_tree = new_tree;
	    bev_facetize_tree = (union tree *)NULL;
	} else if (!tmp_tree && op == ' ') {
	    /* just starting out */
	    tmp_tree = bev_facetize_tree;
	    bev_facetize_tree = (union tree *)NULL;
	}

	if (argc) {
	    op = *argv[0];
	    argc--;
	    argv++;
	} else
	    op = ' ';

    }

    if (tmp_tree) {
	/* Now, evaluate the boolean tree into ONE region */
	bu_vls_printf(gedp->ged_result_str, "%s: evaluating boolean expressions\n", cmdname);

	if (BU_SETJUMP) {
	    BU_UNSETJUMP;

	    bu_vls_printf(gedp->ged_result_str, "%s: WARNING: Boolean evaluation failed!!!\n", cmdname);
	    if (tmp_tree)
		db_free_tree(tmp_tree, &rt_uniresource);
	    tmp_tree = (union tree *)NULL;
	    nmg_km(bev_nmg_model);
	    bev_nmg_model = (struct model *)NULL;
	    return GED_ERROR;
	}

	failed = nmg_boolean(tmp_tree, bev_nmg_model, &gedp->ged_wdbp->wdb_tol, &rt_uniresource);
	BU_UNSETJUMP;
    } else
	failed = 1;

    if (failed) {
	bu_vls_printf(gedp->ged_result_str, "%s: no resulting region, aborting\n", cmdname);
	if (tmp_tree)
	    db_free_tree(tmp_tree, &rt_uniresource);
	tmp_tree = (union tree *)NULL;
	nmg_km(bev_nmg_model);
	bev_nmg_model = (struct model *)NULL;
	return GED_ERROR;
    }
    /* New region remains part of this nmg "model" */
    NMG_CK_REGION(tmp_tree->tr_d.td_r);
    bu_vls_printf(gedp->ged_result_str, "%s: facetize %s\n", cmdname, tmp_tree->tr_d.td_name);

    nmg_vmodel(bev_nmg_model);

    /* Triangulate model, if requested */
    if (triangulate) {
	bu_vls_printf(gedp->ged_result_str, "%s: triangulating resulting object\n", cmdname);
	if (BU_SETJUMP) {
	    BU_UNSETJUMP;
	    bu_vls_printf(gedp->ged_result_str, "%s: WARNING: Triangulation failed!!!\n", cmdname);
	    if (tmp_tree)
		db_free_tree(tmp_tree, &rt_uniresource);
	    tmp_tree = (union tree *)NULL;
	    nmg_km(bev_nmg_model);
	    bev_nmg_model = (struct model *)NULL;
	    return GED_ERROR;
	}
	nmg_triangulate_model(bev_nmg_model, &gedp->ged_wdbp->wdb_tol);
	BU_UNSETJUMP;
    }

    bu_vls_printf(gedp->ged_result_str, "%s: converting NMG to database format\n", cmdname);

    /* 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 = &rt_functab[ID_NMG];
    intern.idb_ptr = (genptr_t)bev_nmg_model;
    bev_nmg_model = (struct model *)NULL;

    GED_DB_DIRADD(gedp, dp, newname, RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (genptr_t)&intern.idb_type, GED_ERROR);
    GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);

    tmp_tree->tr_d.td_r = (struct nmgregion *)NULL;

    /* Free boolean tree, and the regions in it. */
    db_free_tree(tmp_tree, &rt_uniresource);

    return GED_OK;
}
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;
}
Exemple #5
0
/*
 * 'make_pnts' command for importing point-cloud data into a 'pnts'
 * primitive.
 *
 * Input values:
 * argv[1] object name
 * argv[2] filename with path
 * argv[3] point data file format string
 * argv[4] point data file units string or conversion factor to millimeters
 * argv[5] default size of each point
 *
 */
int
ged_make_pnts(struct ged *gedp, int argc, const char *argv[])
{
    struct directory *dp;
    struct rt_db_internal internal;

    rt_pnt_type type;
    double local2base;
    unsigned long numPoints = 0;
    struct rt_pnts_internal *pnts;

    double defaultSize = 0.0;
    void *headPoint = NULL;

    FILE *fp;

    int temp_string_index = 0; /* index into temp_string, set to first character in temp_string, i.e. the start */
    unsigned long int num_doubles_read = 0; /* counters of double read from file */

    int current_character_double = 0; /* flag indicating if current character read is part of a double or delimiter */
    int previous_character_double = 0; /* flag indicating if previously read character was part of a double or delimiter */

    unsigned long int num_characters_read_from_file = 0;  /* counter of number of characters read from file */
    unsigned long int start_offset_of_current_double = 0; /* character offset from start of file for current double */
    int found_double = 0; /* flag indicating if double encountered in file and needs to be processed */
    int found_eof = 0; /* flag indicating if end-of-file encountered when reading file */
    int done_processing_format_string = 0; /* flag indicating if loop processing format string should be exited */

    char *temp_char_ptr = (char *)NULL;

    int buf = 0; /* raw character read from file */
    double temp_double = 0.0;
    char temp_string[1024];
    int temp_string_size = 1024;  /* number of characters that can be stored in temp_string including null terminator character */
    /* it is expected that the character representation of a double will never exceed this size string */
    char *endp = (char *)NULL;

    struct bu_vls format_string = BU_VLS_INIT_ZERO;
    size_t format_string_index = 0;

    unsigned int num_doubles_per_point = 0;

    void *point = NULL;

    char **prompt;

    static const char *usage = "point_cloud_name filename_with_path file_format file_data_units default_point_size";

    prompt = &p_make_pnts[0];

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

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

    /* prompt for point-cloud name */
    if (argc < 2) {
        bu_vls_printf(gedp->ged_result_str, "%s", prompt[0]);
        return GED_MORE;
    }

    GED_CHECK_EXISTS(gedp, argv[1], LOOKUP_QUIET, GED_ERROR);

    /* prompt for data file name with path */
    if (argc < 3) {
        bu_vls_printf(gedp->ged_result_str, "%s", prompt[1]);
        return GED_MORE;
    }

    /* prompt for data file format */
    if (argc < 4) {
        bu_vls_printf(gedp->ged_result_str, "%s", prompt[2]);
        return GED_MORE;
    }

    /* Validate 'point file data format string' and return point-cloud type. */
    if (str2type(argv[3], &type, gedp->ged_result_str) == GED_ERROR) {
        return GED_ERROR;
    }

    /* prompt for data file units */
    if (argc < 5) {
        bu_vls_printf(gedp->ged_result_str, "%s", prompt[3]);
        return GED_MORE;
    }

    /* Validate the unit string and return conversion factor to millimeters. */
    if (str2mm(argv[4], &local2base, gedp->ged_result_str) == GED_ERROR) {
        return GED_ERROR;
    }

    /* prompt for default point size */
    if (argc < 6) {
        bu_vls_printf(gedp->ged_result_str, "%s", prompt[4]);
        return GED_MORE;
    }

    defaultSize = strtod(argv[5], &endp);
    if ((endp != argv[5]) && (*endp == '\0')) {
        /* convert to double success */
        if (defaultSize < 0.0) {
            bu_vls_printf(gedp->ged_result_str, "Default point size '%lf' must be non-negative.\n", defaultSize);
            return GED_ERROR;
        }
    } else {
        bu_vls_printf(gedp->ged_result_str, "Invalid default point size '%s'\n", argv[5]);
        return GED_ERROR;
    }

    bu_vls_strcat(&format_string, argv[3]);
    bu_vls_trimspace(&format_string);

    /* init database structure */
    RT_DB_INTERNAL_INIT(&internal);
    internal.idb_major_type = DB5_MAJORTYPE_BRLCAD;
    internal.idb_type = ID_PNTS;
    internal.idb_meth = &OBJ[ID_PNTS];
    BU_ALLOC(internal.idb_ptr, struct rt_pnts_internal);

    /* init internal structure */
    pnts = (struct rt_pnts_internal *) internal.idb_ptr;
    pnts->magic = RT_PNTS_INTERNAL_MAGIC;
    pnts->scale = defaultSize;
    pnts->type = type;
    pnts->count = numPoints;  /* set again later */
    pnts->point = NULL;

    /* empty list head */
    switch (type) {
    case RT_PNT_TYPE_PNT:
        BU_ALLOC(headPoint, struct pnt);
        BU_LIST_INIT(&(((struct pnt *)headPoint)->l));
        num_doubles_per_point = 3;
        break;
    case RT_PNT_TYPE_COL:
        BU_ALLOC(headPoint, struct pnt_color);
        BU_LIST_INIT(&(((struct pnt_color *)headPoint)->l));
        num_doubles_per_point = 6;
        break;
    case RT_PNT_TYPE_SCA:
        BU_ALLOC(headPoint, struct pnt_scale);
        BU_LIST_INIT(&(((struct pnt_scale *)headPoint)->l));
        num_doubles_per_point = 4;
        break;
    case RT_PNT_TYPE_NRM:
        BU_ALLOC(headPoint, struct pnt_normal);
        BU_LIST_INIT(&(((struct pnt_normal *)headPoint)->l));
        num_doubles_per_point = 6;
        break;
    case RT_PNT_TYPE_COL_SCA:
        BU_ALLOC(headPoint, struct pnt_color_scale);
        BU_LIST_INIT(&(((struct pnt_color_scale *)headPoint)->l));
        num_doubles_per_point = 7;
        break;
    case RT_PNT_TYPE_COL_NRM:
        BU_ALLOC(headPoint, struct pnt_color_normal);
        BU_LIST_INIT(&(((struct pnt_color_normal *)headPoint)->l));
        num_doubles_per_point = 9;
        break;
    case RT_PNT_TYPE_SCA_NRM:
        BU_ALLOC(headPoint, struct pnt_scale_normal);
        BU_LIST_INIT(&(((struct pnt_scale_normal *)headPoint)->l));
        num_doubles_per_point = 7;
        break;
    case RT_PNT_TYPE_COL_SCA_NRM:
        BU_ALLOC(headPoint, struct pnt_color_scale_normal);
        BU_LIST_INIT(&(((struct pnt_color_scale_normal *)headPoint)->l));
        num_doubles_per_point = 10;
        break;
    }
    BU_ASSERT_PTR(headPoint, !=, NULL);
    pnts->point = headPoint;

    if ((fp=fopen(argv[2], "rb")) == NULL) {
        bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]);
        bu_vls_printf(gedp->ged_result_str, "Could not open file '%s'.\n", argv[2]);
        bu_vls_free(&format_string);
        rt_db_free_internal(&internal);
        return GED_ERROR;
    }

    while (!found_eof) {
        /* points_loop */
        /* allocate memory for single point structure for current point-cloud type */
        switch (type) {
        case RT_PNT_TYPE_PNT:
            BU_ALLOC(point, struct pnt);
            break;
        case RT_PNT_TYPE_COL:
            BU_ALLOC(point, struct pnt_color);
            break;
        case RT_PNT_TYPE_SCA:
            BU_ALLOC(point, struct pnt_scale);
            break;
        case RT_PNT_TYPE_NRM:
            BU_ALLOC(point, struct pnt_normal);
            break;
        case RT_PNT_TYPE_COL_SCA:
            BU_ALLOC(point, struct pnt_color_scale);
            break;
        case RT_PNT_TYPE_COL_NRM:
            BU_ALLOC(point, struct pnt_color_normal);
            break;
        case RT_PNT_TYPE_SCA_NRM:
            BU_ALLOC(point, struct pnt_scale_normal);
            break;
        case RT_PNT_TYPE_COL_SCA_NRM:
            BU_ALLOC(point, struct pnt_color_scale_normal);
            break;
        }

        /* make sure we have something */
        BU_ASSERT_PTR(point, !=, NULL);

        while (!found_eof && !done_processing_format_string) {
            /* format_string_loop */
            char format = '\0';

            while (!found_eof  && !found_double) {
                /* find_doubles_loop */
                format = bu_vls_addr(&format_string)[format_string_index];

                buf = fgetc(fp);

                num_characters_read_from_file++;

                if (feof(fp)) {
                    if (ferror(fp)) {
                        perror("ERROR: Problem reading file, system error message");
                        fclose(fp);
                        bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]);
                        bu_vls_printf(gedp->ged_result_str, "Unable to read file at byte '%lu'.\n", num_characters_read_from_file);
                        bu_vls_free(&format_string);
                        rt_db_free_internal(&internal);
                        return GED_ERROR;
                    } else {
                        found_eof = 1;
                    }
                }

                if (found_eof) {
                    fclose(fp);
                    current_character_double = 0;
                    if (num_doubles_read == 0) {
                        bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]);
                        bu_vls_printf(gedp->ged_result_str, "No data in file '%s'.\n", argv[2]);
                        bu_vls_free(&format_string);
                        rt_db_free_internal(&internal);
                        return GED_ERROR;
                    }
                } else {
                    temp_char_ptr = strchr("0123456789.+-eE", buf);
                    if (temp_char_ptr != NULL) {
                        /* character read is part of a double */
                        current_character_double = 1;
                    } else {
                        current_character_double = 0;
                    }
                }

                if (previous_character_double && current_character_double) {
                    if (temp_string_index >= temp_string_size) {
                        fclose(fp);
                        bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]);
                        bu_vls_printf(gedp->ged_result_str, "String representing double too large, exceeds '%d' character limit. ", temp_string_size - 1);
                        report_import_error_location(num_doubles_read, num_doubles_per_point, start_offset_of_current_double,
                                                     format, gedp->ged_result_str);
                        bu_vls_free(&format_string);
                        rt_db_free_internal(&internal);
                        return GED_ERROR;
                    }
                    temp_string[temp_string_index] = (char)buf;
                    temp_string_index++;
                }

                if (previous_character_double && !current_character_double) {
                    if (temp_string_index >= temp_string_size) {
                        fclose(fp);
                        bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]);
                        bu_vls_printf(gedp->ged_result_str, "String representing double too large, exceeds '%d' character limit. ", temp_string_size - 1);
                        report_import_error_location(num_doubles_read, num_doubles_per_point, start_offset_of_current_double,
                                                     format, gedp->ged_result_str);
                        bu_vls_free(&format_string);
                        rt_db_free_internal(&internal);
                        return GED_ERROR;
                    }
                    temp_string[temp_string_index] = '\0';

                    /* do not convert string to double for format character '?' */
                    if (format != '?') {
                        temp_double = strtod(temp_string, &endp);
                        if (!((endp != temp_string) && (*endp == '\0'))) {
                            fclose(fp);
                            bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]);
                            bu_vls_printf(gedp->ged_result_str, "Unable to convert string '%s' to double. ", temp_string);
                            report_import_error_location(num_doubles_read, num_doubles_per_point, start_offset_of_current_double,
                                                         format, gedp->ged_result_str);
                            bu_vls_free(&format_string);
                            rt_db_free_internal(&internal);
                            return GED_ERROR;
                        }
                        num_doubles_read++;
                    } else {
                        temp_double = 0.0;
                    }

                    temp_string_index = 0;
                    found_double = 1;
                    previous_character_double = current_character_double;
                }

                if (!previous_character_double && current_character_double) {
                    temp_string[temp_string_index] = (char)buf;
                    temp_string_index++;
                    start_offset_of_current_double = num_characters_read_from_file;
                    previous_character_double = current_character_double;
                }

            } /* loop exits when eof encountered (and/or) double found */

            if (found_double) {

                /* insert double into point structure for current point-cloud type */
                /* do not attempt to insert double into point structure for format character '?' */
                if (format != '?') {
                    switch (type) {
                    case RT_PNT_TYPE_PNT:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt, format, (temp_double * local2base));
                        break;
                    case RT_PNT_TYPE_COL:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt_color, format, (temp_double * local2base));
                        INSERT_COLOR_INTO_STRUCTURE(pnt_color, format, temp_double);
                        break;
                    case RT_PNT_TYPE_SCA:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt_scale, format, (temp_double * local2base));
                        INSERT_SCALE_INTO_STRUCTURE(pnt_scale, format, (temp_double * local2base));
                        break;
                    case RT_PNT_TYPE_NRM:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt_normal, format, (temp_double * local2base));
                        INSERT_NORMAL_INTO_STRUCTURE(pnt_normal, format, (temp_double * local2base));
                        break;
                    case RT_PNT_TYPE_COL_SCA:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt_color_scale, format, (temp_double * local2base));
                        INSERT_COLOR_INTO_STRUCTURE(pnt_color_scale, format, temp_double);
                        INSERT_SCALE_INTO_STRUCTURE(pnt_color_scale, format, (temp_double * local2base));
                        break;
                    case RT_PNT_TYPE_COL_NRM:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt_color_normal, format, (temp_double * local2base));
                        INSERT_COLOR_INTO_STRUCTURE(pnt_color_normal, format, temp_double);
                        INSERT_NORMAL_INTO_STRUCTURE(pnt_color_normal, format, (temp_double * local2base));
                        break;
                    case RT_PNT_TYPE_SCA_NRM:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt_scale_normal, format, (temp_double * local2base));
                        INSERT_SCALE_INTO_STRUCTURE(pnt_scale_normal, format, (temp_double * local2base));
                        INSERT_NORMAL_INTO_STRUCTURE(pnt_scale_normal, format, (temp_double * local2base));
                        break;
                    case RT_PNT_TYPE_COL_SCA_NRM:
                        INSERT_COORDINATE_INTO_STRUCTURE(pnt_color_scale_normal, format, (temp_double * local2base));
                        INSERT_COLOR_INTO_STRUCTURE(pnt_color_scale_normal, format, temp_double);
                        INSERT_SCALE_INTO_STRUCTURE(pnt_color_scale_normal, format, (temp_double * local2base));
                        INSERT_NORMAL_INTO_STRUCTURE(pnt_color_scale_normal, format, (temp_double * local2base));
                        break;
                    }
                }
                found_double = 0;  /* allows loop to continue */
                format_string_index++;
                if (format_string_index >= bu_vls_strlen(&format_string)) {
                    done_processing_format_string = 1;
                }
            }

        } /* loop exits when eof encountered (and/or) all doubles for
	   * a single point are stored in point structure
	   */

        if (done_processing_format_string) {
            /* push single point structure onto linked-list of points
             * which makeup the point-cloud.
             */
            switch (type) {
            case RT_PNT_TYPE_PNT:
                BU_LIST_PUSH(&(((struct pnt *)headPoint)->l), &((struct pnt *)point)->l);
                break;
            case RT_PNT_TYPE_COL:
                BU_LIST_PUSH(&(((struct pnt_color *)headPoint)->l), &((struct pnt_color *)point)->l);
                break;
            case RT_PNT_TYPE_SCA:
                BU_LIST_PUSH(&(((struct pnt_scale *)headPoint)->l), &((struct pnt_scale *)point)->l);
                break;
            case RT_PNT_TYPE_NRM:
                BU_LIST_PUSH(&(((struct pnt_normal *)headPoint)->l), &((struct pnt_normal *)point)->l);
                break;
            case RT_PNT_TYPE_COL_SCA:
                BU_LIST_PUSH(&(((struct pnt_color_scale *)headPoint)->l), &((struct pnt_color_scale *)point)->l);
                break;
            case RT_PNT_TYPE_COL_NRM:
                BU_LIST_PUSH(&(((struct pnt_color_normal *)headPoint)->l), &((struct pnt_color_normal *)point)->l);
                break;
            case RT_PNT_TYPE_SCA_NRM:
                BU_LIST_PUSH(&(((struct pnt_scale_normal *)headPoint)->l), &((struct pnt_scale_normal *)point)->l);
                break;
            case RT_PNT_TYPE_COL_SCA_NRM:
                BU_LIST_PUSH(&(((struct pnt_color_scale_normal *)headPoint)->l), &((struct pnt_color_scale_normal *)point)->l);
                break;
            }
            numPoints++;
            format_string_index = 0;
            done_processing_format_string = 0;
        }

    } /* loop exits when eof encountered */

    if (num_doubles_read < num_doubles_per_point) {
        bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. Number of values read inconsistent with point-cloud type ", argv[1]);
        bu_vls_printf(gedp->ged_result_str, "defined by format string '%V'. The number of values read must be an even ", format_string);
        bu_vls_printf(gedp->ged_result_str, "multiple of %d but read %lu values.\n", num_doubles_per_point, num_doubles_read);
        bu_vls_free(&format_string);
        rt_db_free_internal(&internal);
        return GED_ERROR;
    }

    if (num_doubles_read % num_doubles_per_point) {
        bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. Number of values read inconsistent with point-cloud type ", argv[1]);
        bu_vls_printf(gedp->ged_result_str, "defined by format string '%V'. The number of values read must be an even ", format_string);
        bu_vls_printf(gedp->ged_result_str, "multiple of %d but read %lu values.\n", num_doubles_per_point, num_doubles_read);
        bu_vls_free(&format_string);
        rt_db_free_internal(&internal);
        return GED_ERROR;
    }

    pnts->count = numPoints;

    GED_DB_DIRADD(gedp, dp, argv[1], RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&internal.idb_type, GED_ERROR);
    GED_DB_PUT_INTERNAL(gedp, dp, &internal, &rt_uniresource, GED_ERROR);

    bu_vls_free(&format_string);

    bu_vls_printf(gedp->ged_result_str, "Make '%s' success, %lu values read, %lu points imported.\n", argv[1], num_doubles_read, numPoints);

    return GED_OK;
}
Exemple #6
0
int
ged_bot_smooth(struct ged *gedp, int argc, const char *argv[])
{
    char *new_bot_name, *old_bot_name;
    struct directory *dp_old, *dp_new;
    struct rt_bot_internal *old_bot;
    struct rt_db_internal intern;
    fastf_t tolerance_angle=180.0;
    int arg_index=1;
    static const char *usage = "[-t ntol] new_bot old_bot";

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

    dp_old = dp_new = RT_DIR_NULL;

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

    /* 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 BOT surface normals.\nUse \"dbupgrade\" to upgrade this database to the current version.\n");
	return GED_ERROR;
    }

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

    while (*argv[arg_index] == '-') {
	/* this is an option */
	if (BU_STR_EQUAL(argv[arg_index], "-t")) {
	    arg_index++;
	    tolerance_angle = atof(argv[arg_index]);
	} else {
	    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	    return GED_ERROR;
	}
	arg_index++;
    }

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

    new_bot_name = (char *)argv[arg_index++];
    old_bot_name = (char *)argv[arg_index];

    GED_DB_LOOKUP(gedp, dp_old, old_bot_name, LOOKUP_QUIET, GED_ERROR);

    if (!BU_STR_EQUAL(old_bot_name, new_bot_name)) {
	GED_CHECK_EXISTS(gedp, new_bot_name, LOOKUP_QUIET, GED_ERROR);
    } else {
	dp_new = dp_old;
    }

    GED_DB_GET_INTERNAL(gedp, &intern, dp_old, NULL, gedp->ged_wdbp->wdb_resp, 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, "%s is not a BOT primitive\n", old_bot_name);
	rt_db_free_internal(&intern);
	return GED_ERROR;
    }

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

    if (rt_bot_smooth(old_bot, old_bot_name, gedp->ged_wdbp->dbip, tolerance_angle*DEG2RAD)) {
	bu_vls_printf(gedp->ged_result_str, "Failed to smooth %s\n", old_bot_name);
	rt_db_free_internal(&intern);
	return GED_ERROR;
    }

    if (dp_new == RT_DIR_NULL) {
	GED_DB_DIRADD(gedp, dp_new, new_bot_name, RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&intern.idb_type, GED_ERROR);
    }

    GED_DB_PUT_INTERNAL(gedp, dp_new, &intern, gedp->ged_wdbp->wdb_resp, GED_ERROR);
    rt_db_free_internal(&intern);

    return GED_OK;
}
Exemple #7
0
int
ged_make(struct ged *gedp, int argc, const char *argv[])
{
    size_t i;
    int k;
    int save_bu_optind;
    struct directory *dp;

    /* intentionally double for sscanf */
    double scale = 1.0;
    double origin[3] = {0.0, 0.0, 0.0};

    struct rt_db_internal internal;
    struct rt_arb_internal *arb_ip;
    struct rt_ars_internal *ars_ip;
    struct rt_tgc_internal *tgc_ip;
    struct rt_ell_internal *ell_ip;
    struct rt_tor_internal *tor_ip;
    struct rt_grip_internal *grp_ip;
    struct rt_half_internal *half_ip;
    struct rt_rpc_internal *rpc_ip;
    struct rt_rhc_internal *rhc_ip;
    struct rt_epa_internal *epa_ip;
    struct rt_ehy_internal *ehy_ip;
    struct rt_eto_internal *eto_ip;
    struct rt_part_internal *part_ip;
    struct rt_pipe_internal *pipe_ip;
    struct rt_sketch_internal *sketch_ip;
    struct rt_extrude_internal *extrude_ip;
    struct rt_bot_internal *bot_ip;
    struct rt_arbn_internal *arbn_ip;
    struct rt_superell_internal *superell_ip;
    struct rt_metaball_internal *metaball_ip;
    struct rt_pnts_internal *pnts_ip;

    static const char *usage = "-h | -t | -o origin -s sf name <arb8|arb7|arb6|arb5|arb4|arbn|ars|bot|ehy|ell|ell1|epa|eto|extrude|grip|half|hyp|nmg|part|pipe|pnts|rcc|rec|rhc|rpc|rpp|sketch|sph|tec|tgc|tor|trc>";

    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;

    /* Process arguments */
    while ((k = bu_getopt(argc, (char * const *)argv, "hHo:O:s:S:tT")) != -1) {
	switch (k) {
	    case 'o':
	    case 'O':
		if (sscanf(bu_optarg, "%lf %lf %lf",
			   &origin[X],
			   &origin[Y],
			   &origin[Z]) != 3) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}
		break;
	    case 's':
	    case 'S':
		if (sscanf(bu_optarg, "%lf", &scale) != 1) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}
		break;
	    case 't':
	    case 'T':
		if (argc == 2) {
		    bu_vls_printf(gedp->ged_result_str, "arb8 arb7 arb6 arb5 arb4 arbn ars bot ehy ell ell1 epa eto extrude grip half hyp nmg part pipe pnts rcc rec rhc rpc rpp sketch sph tec tgc tor trc superell metaball");
		    return GED_HELP;
		}

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

    argc -= bu_optind;

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

    save_bu_optind = bu_optind;

    GED_CHECK_EXISTS(gedp, argv[bu_optind], LOOKUP_QUIET, GED_ERROR);
    RT_DB_INTERNAL_INIT(&internal);

    if (BU_STR_EQUAL(argv[bu_optind+1], "arb8") ||
	BU_STR_EQUAL(argv[bu_optind+1],  "rpp")) {
	internal.idb_major_type = DB5_MAJORTYPE_BRLCAD;
	internal.idb_type = ID_ARB8;
	internal.idb_meth = &OBJ[ID_ARB8];
	BU_ALLOC(internal.idb_ptr, struct rt_arb_internal);
	arb_ip = (struct rt_arb_internal *)internal.idb_ptr;
	arb_ip->magic = RT_ARB_INTERNAL_MAGIC;
	VSET(arb_ip->pt[0] ,
	     origin[X] + 0.5*scale,
	     origin[Y] - 0.5*scale,
	     origin[Z] - 0.5*scale);
	for (i = 1; i < 8; i++)
	    VMOVE(arb_ip->pt[i], arb_ip->pt[0]);
	arb_ip->pt[1][Y] += scale;
	arb_ip->pt[2][Y] += scale;
	arb_ip->pt[2][Z] += scale;
	arb_ip->pt[3][Z] += scale;
	for (i = 4; i < 8; i++)
	    arb_ip->pt[i][X] -= scale;
	arb_ip->pt[5][Y] += scale;
	arb_ip->pt[6][Y] += scale;
	arb_ip->pt[6][Z] += scale;
	arb_ip->pt[7][Z] += scale;
    } else if (BU_STR_EQUAL(argv[bu_optind+1], "arb7")) {
Exemple #8
0
int
ged_comb_std(struct ged *gedp, int argc, const char *argv[])
{
    char *comb_name;
    int ch;
    int region_flag = -1;
    struct directory *dp = RT_DIR_NULL;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb = NULL;
    struct tokens tok_hd;
    short last_tok;
    int i;
    union tree *final_tree;
    static const char *usage = "[-cr] comb_name <boolean_expr>";

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

    /* Parse options */
    bu_optind = 1;	/* re-init bu_getopt() */
    while ((ch = bu_getopt(argc, (char * const *)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:
		bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		return GED_OK;
	}
    }
    argc -= (bu_optind + 1);
    argv += bu_optind;

    comb_name = (char *)*argv++;
    if (argc == -1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_OK;
    }

    if ((region_flag != -1) && (argc == 0)) {
	/*
	 * Set/Reset the REGION flag of an existing combination
	 */
	GED_DB_LOOKUP(gedp, dp, comb_name, LOOKUP_NOISY, GED_ERROR & GED_QUIET);

	if (!(dp->d_flags & RT_DIR_COMB)) {
	    bu_vls_printf(gedp->ged_result_str, "%s is not a combination\n", comb_name);
	    return GED_ERROR;
	}

	GED_DB_GET_INTERNAL(gedp, &intern, dp, (fastf_t *)NULL, &rt_uniresource, GED_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 = gedp->ged_wdbp->wdb_item_default++;
		comb->aircode = gedp->ged_wdbp->wdb_air_default;
		comb->GIFTmater = gedp->ged_wdbp->wdb_mat_default;
		comb->los = gedp->ged_wdbp->wdb_los_default;
	    }
	    comb->region_flag = 1;
	} else
	    comb->region_flag = 0;

	GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);

	return GED_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.
     */

    GED_CHECK_EXISTS(gedp, comb_name, LOOKUP_QUIET, GED_ERROR);
    dp = RT_DIR_NULL;

    /* parse Boolean expression */
    BU_LIST_INIT(&tok_hd.l);
    tok_hd.type = TOK_NULL;

    last_tok = TOK_LPAREN;
    for (i = 0; i < argc; i++) {
	char *ptr;

	ptr = (char *)argv[i];
	while (*ptr) {
	    while (*ptr == '(' || *ptr == ')') {
		switch (*ptr) {
		    case '(':
			append_lparen(&tok_hd.l);
			last_tok = TOK_LPAREN;
			break;
		    case ')':
			append_rparen(&tok_hd.l);
			last_tok = TOK_RPAREN;
			break;
		}
		ptr++;
	    }

	    if (*ptr == '\0')
		continue;

	    if (last_tok == TOK_RPAREN) {
		/* next token MUST be an operator */
		if (add_operator(gedp, &tok_hd.l, *ptr, &last_tok) == GED_ERROR) {
		    free_tokens(&tok_hd.l);
		    return GED_ERROR;
		}
		ptr++;
	    } else if (last_tok == TOK_LPAREN) {
		/* next token MUST be an operand */
		int name_len;

		name_len = add_operand(gedp, &tok_hd.l, ptr);
		if (name_len < 1) {
		    free_tokens(&tok_hd.l);
		    return GED_ERROR;
		}
		last_tok = TOK_TREE;
		ptr += name_len;
	    } else if (last_tok == TOK_TREE) {
		/* must be an operator */
		if (add_operator(gedp, &tok_hd.l, *ptr, &last_tok) == GED_ERROR) {
		    free_tokens(&tok_hd.l);
		    return GED_ERROR;
		}
		ptr++;
	    } else if (last_tok == TOK_UNION ||
		       last_tok == TOK_INTER ||
		       last_tok == TOK_SUBTR) {
		/* must be an operand */
		int name_len;

		name_len = add_operand(gedp, &tok_hd.l, ptr);
		if (name_len < 1) {
		    free_tokens(&tok_hd.l);
		    return GED_ERROR;
		}
		last_tok = TOK_TREE;
		ptr += name_len;
	    }
	}
    }

    if (check_syntax(gedp, &tok_hd.l, comb_name, dp)) {
	free_tokens(&tok_hd.l);
	return GED_ERROR;
    }

    final_tree = 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) {
	    comb->region_flag = 1;
	    comb->region_id = gedp->ged_wdbp->wdb_item_default++;
	    comb->aircode = gedp->ged_wdbp->wdb_air_default;
	    comb->los = gedp->ged_wdbp->wdb_los_default;
	    comb->GIFTmater = gedp->ged_wdbp->wdb_mat_default;

	    bu_vls_printf(gedp->ged_result_str, "Creating region with attrs: region_id=%d, ", comb->region_id);
	    if (comb->aircode)
		bu_vls_printf(gedp->ged_result_str, "air=%d, ", comb->aircode);
	    bu_vls_printf(gedp->ged_result_str, "los=%d, material_id=%d\n",
			  comb->los,
			  comb->GIFTmater);

	    flags |= RT_DIR_REGION;
	}

	RT_DB_INTERNAL_INIT(&intern);
	intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
	intern.idb_type = ID_COMBINATION;
	intern.idb_meth = &OBJ[ID_COMBINATION];
	intern.idb_ptr = (void *)comb;

	GED_DB_DIRADD(gedp, dp, comb_name, RT_DIR_PHONY_ADDR, 0, flags, (void *)&intern.idb_type, GED_ERROR);
	GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
    }

    return GED_OK;
}