示例#1
0
文件: db_diff.c 项目: kanzure/brlcad
int
db_avs_diff(const struct bu_attribute_value_set *left_set,
	    const struct bu_attribute_value_set *right_set,
            const struct bn_tol *diff_tol,
	    int (*add_func)(const char *attr_name, const char *attr_val, void *data),
	    int (*del_func)(const char *attr_name, const char *attr_val, void *data),
	    int (*chgd_func)(const char *attr_name, const char *attr_val_left, const char *attr_val_right, void *data),
	    int (*unchgd_func)(const char *attr_name, const char *attr_val, void *data),
	    void *client_data)
{
    int state = DIFF_EMPTY;
    struct bu_attribute_value_pair *avp;
    for (BU_AVS_FOR(avp, left_set)) {
	const char *val2 = bu_avs_get(right_set, avp->name);
	if (!val2) {
	    if (del_func) {state |= del_func(avp->name, avp->value, client_data);}
	} else {
	    if (avpp_val_compare(avp->value, val2, diff_tol)) {
		if (unchgd_func) {state |= unchgd_func(avp->name, avp->value, client_data);}
	    } else {
		if (chgd_func) {state |= chgd_func(avp->name, avp->value, val2, client_data);}
	    }
	}
    }
    for (BU_AVS_FOR(avp, right_set)) {
	const char *val1 = bu_avs_get(left_set, avp->name);
	if (!val1) {
	    if (add_func) {state |= add_func(avp->name, avp->value, client_data);}
	}
    }
    return state;
}
/**
 * This routine will be called by db_walk_tree() once all the solids
 * in this region have been visited.
 *
 * This routine must be prepared to run in parallel.  As a result,
 * note that the details of the solids pointed to by the soltab
 * pointers in the tree may not be filled in when this routine is
 * called (due to the way multiple instances of solids are handled).
 * Therefore, everything which referred to the tree has been moved out
 * into the serial section.  (_rt_tree_region_assign, rt_bound_tree)
 */
HIDDEN union tree *
_rt_gettree_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, union tree *curtree, void *client_data)
{
    struct region *rp;
    struct directory *dp = NULL;
    size_t shader_len=0;
    struct rt_i *rtip;
    Tcl_HashTable *tbl = (Tcl_HashTable *)client_data;
    Tcl_HashEntry *entry;
    matp_t inv_mat;
    struct bu_attribute_value_set avs;
    struct bu_attribute_value_pair *avpp;

    RT_CK_DBI(tsp->ts_dbip);
    RT_CK_FULL_PATH(pathp);
    RT_CK_TREE(curtree);
    rtip =  tsp->ts_rtip;
    RT_CK_RTI(rtip);
    RT_CK_RESOURCE(tsp->ts_resp);

    if (curtree->tr_op == OP_NOP) {
	/* Ignore empty regions */
	return curtree;
    }

    BU_ALLOC(rp, struct region);
    rp->l.magic = RT_REGION_MAGIC;
    rp->reg_regionid = tsp->ts_regionid;
    rp->reg_is_fastgen = tsp->ts_is_fastgen;
    rp->reg_aircode = tsp->ts_aircode;
    rp->reg_gmater = tsp->ts_gmater;
    rp->reg_los = tsp->ts_los;

    dp = (struct directory *)DB_FULL_PATH_CUR_DIR(pathp);
    if (!dp)
	return TREE_NULL;

    bu_avs_init_empty(&avs);
    if (db5_get_attributes(tsp->ts_dbip, &avs, dp) == 0) {
	/* copy avs */
	bu_avs_init_empty(&(rp->attr_values));
	for (BU_AVS_FOR(avpp, &(tsp->ts_attrs))) {
	    bu_avs_add(&(rp->attr_values), avpp->name, bu_avs_get(&avs, avpp->name));
	}
    }
/**
 * Get an attribute from a bu_avs, like bu_avs_get, but return "--" if
 * the item is missing, instead of NULL
 */
static const char *
get_attr(const struct bu_attribute_value_set *avp, const char *attribute)
{
    const char *value = bu_avs_get(avp, attribute);
    return value ? value : "--";
}
示例#4
0
文件: copy.c 项目: kanzure/brlcad
int
ged_dbcopy(struct ged *from_gedp, struct ged *to_gedp, const char *from, const char *to, int fflag)
{
    struct directory *from_dp;
    struct bu_external external;

    GED_CHECK_DATABASE_OPEN(from_gedp, GED_ERROR);
    GED_CHECK_DATABASE_OPEN(to_gedp, GED_ERROR);
    GED_CHECK_READ_ONLY(to_gedp, GED_ERROR);

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

    GED_DB_LOOKUP(from_gedp, from_dp, from, LOOKUP_NOISY, GED_ERROR & GED_QUIET);

    if (!fflag && db_lookup(to_gedp->ged_wdbp->dbip, to, LOOKUP_QUIET) != RT_DIR_NULL) {
	bu_vls_printf(from_gedp->ged_result_str, "%s already exists.", to);
	return GED_ERROR;
    }

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

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

    bu_free_external(&external);

    /* Need to do something extra for _GLOBAL */
    if (db_version(to_gedp->ged_wdbp->dbip) > 4 && BU_STR_EQUAL(to, DB5_GLOBAL_OBJECT_NAME)) {
	struct directory *to_dp;
	struct bu_attribute_value_set avs;
	const char *val;

	GED_DB_LOOKUP(to_gedp, to_dp, to, LOOKUP_NOISY, GED_ERROR & GED_QUIET);

	bu_avs_init_empty(&avs);
	if (db5_get_attributes(to_gedp->ged_wdbp->dbip, &avs, to_dp)) {
	    bu_vls_printf(from_gedp->ged_result_str, "Cannot get attributes for object %s\n", to_dp->d_namep);
	    return GED_ERROR;
	}

	if ((val = bu_avs_get(&avs, "title")) != NULL)
	    to_gedp->ged_wdbp->dbip->dbi_title = strdup(val);

	if ((val = bu_avs_get(&avs, "units")) != NULL) {
	    double loc2mm;

	    if ((loc2mm = bu_mm_value(val)) > 0) {
		to_gedp->ged_wdbp->dbip->dbi_local2base = loc2mm;
		to_gedp->ged_wdbp->dbip->dbi_base2local = 1.0 / loc2mm;
	    }
	}

	if ((val = bu_avs_get(&avs, "regionid_colortable")) != NULL) {
	    rt_color_free();
	    db5_import_color_table((char *)val);
	}

	bu_avs_free(&avs);
    }

    return GED_OK;
}
示例#5
0
文件: concat.c 项目: kanzure/brlcad
int
ged_concat(struct ged *gedp, int argc, const char *argv[])
{
    struct db_i *newdbp;
    struct directory *dp;
    Tcl_HashTable name_tbl;
    Tcl_HashTable used_names_tbl;
    Tcl_HashEntry *ptr;
    Tcl_HashSearch search;
    struct bu_attribute_value_set g_avs;
    const char *cp;
    char *colorTab;
    struct ged_concat_data cc_data;
    const char *oldfile;
    static const char *usage = "[-u] [-t] [-c] [-s|-p] file.g [suffix|prefix]";
    int importUnits = 0;
    int importTitle = 0;
    int importColorTable = 0;
    int saveGlobalAttrs = 0;
    int c;
    const char *commandName;

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

    bu_vls_init(&cc_data.affix);
    cc_data.copy_mode = 0;
    commandName = argv[0];

    /* process args */
    bu_optind = 1;
    bu_opterr = 0;
    while ((c=bu_getopt(argc, (char * const *)argv, "utcsp")) != -1) {
	switch (c) {
	    case 'u':
		importUnits = 1;
		break;
	    case 't':
		importTitle = 1;
		break;
	    case 'c':
		importColorTable = 1;
		break;
	    case 'p':
		cc_data.copy_mode |= AUTO_PREFIX;
		break;
	    case 's':
		cc_data.copy_mode |= AUTO_SUFFIX;
		break;
	    default: {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage);
		    bu_vls_free(&cc_data.affix);
		    return GED_ERROR;
		}
	}
    }
    argc -= bu_optind;
    argv += bu_optind;

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

    oldfile = argv[0];

    argc--;
    argv++;

    if (cc_data.copy_mode) {
	/* specified suffix or prefix explicitly */

	if (cc_data.copy_mode & AUTO_PREFIX) {

	    if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
		cc_data.copy_mode = NO_AFFIX | CUSTOM_PREFIX;
	    } else {
		(void)bu_vls_strcpy(&cc_data.affix, argv[0]);
		cc_data.copy_mode |= CUSTOM_PREFIX;
	    }

	} else if (cc_data.copy_mode & AUTO_SUFFIX) {

	    if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
		cc_data.copy_mode = NO_AFFIX | CUSTOM_SUFFIX;
	    } else {
		(void)bu_vls_strcpy(&cc_data.affix, argv[0]);
		cc_data.copy_mode |= CUSTOM_SUFFIX;
	    }

	} else {
	    bu_vls_free(&cc_data.affix);
	    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", commandName, usage);
	    return GED_ERROR;
	}

    } else {
	/* no prefix/suffix preference, use prefix */

	cc_data.copy_mode |= AUTO_PREFIX;

	if (argc == 0 || BU_STR_EQUAL(argv[0], "/")) {
	    cc_data.copy_mode = NO_AFFIX | CUSTOM_PREFIX;
	} else {
	    (void)bu_vls_strcpy(&cc_data.affix, argv[0]);
	    cc_data.copy_mode |= CUSTOM_PREFIX;
	}

    }

    if (db_version(gedp->ged_wdbp->dbip) < 5) {
	if (bu_vls_strlen(&cc_data.affix) > _GED_V4_MAXNAME-1) {
	    bu_log("ERROR: affix [%s] is too long for v%d\n", bu_vls_addr(&cc_data.affix), db_version(gedp->ged_wdbp->dbip));
	    bu_vls_free(&cc_data.affix);
	    return GED_ERROR;
	}
    }

    /* open the input file */
    if ((newdbp = db_open(oldfile, DB_OPEN_READONLY)) == DBI_NULL) {
	bu_vls_free(&cc_data.affix);
	perror(oldfile);
	bu_vls_printf(gedp->ged_result_str, "%s: Can't open geometry database file %s", commandName, oldfile);
	return GED_ERROR;
    }

    if (db_version(newdbp) > 4 && db_version(gedp->ged_wdbp->dbip) < 5) {
	bu_vls_free(&cc_data.affix);
	bu_vls_printf(gedp->ged_result_str, "%s: databases are incompatible, use dbupgrade on %s first",
		      commandName, gedp->ged_wdbp->dbip->dbi_filename);
	return GED_ERROR;
    }

    db_dirbuild(newdbp);

    cc_data.new_dbip = newdbp;
    cc_data.old_dbip = gedp->ged_wdbp->dbip;

    /* visit each directory pointer in the input database */
    Tcl_InitHashTable(&name_tbl, TCL_STRING_KEYS);
    Tcl_InitHashTable(&used_names_tbl, TCL_STRING_KEYS);

    if (importUnits || importTitle || importColorTable) {
	saveGlobalAttrs = 1;
    }
    FOR_ALL_DIRECTORY_START(dp, newdbp) {
	if (dp->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY) {
	    if (saveGlobalAttrs) {
		if (db5_get_attributes(newdbp, &g_avs, dp)) {
		    bu_vls_printf(gedp->ged_result_str, "%s: Can't get global attributes from %s", commandName, oldfile);
		    return GED_ERROR;
		}
	    }
	    continue;
	}
	copy_object(gedp, dp, newdbp, gedp->ged_wdbp->dbip, &name_tbl, &used_names_tbl, &cc_data);
    } FOR_ALL_DIRECTORY_END;

    bu_vls_free(&cc_data.affix);
    rt_mempurge(&(newdbp->dbi_freep));

    /* Free all the directory entries, and close the input database */
    db_close(newdbp);

    if (importColorTable) {
	colorTab = bu_strdup(bu_avs_get(&g_avs, "regionid_colortable"));
	db5_import_color_table(colorTab);
	bu_free(colorTab, "colorTab");
    } else if (saveGlobalAttrs) {
	bu_avs_remove(&g_avs, "regionid_colortable");
    }

    if (importTitle) {
	if ((cp = bu_avs_get(&g_avs, "title")) != NULL) {
	    char *oldTitle = gedp->ged_wdbp->dbip->dbi_title;
	    gedp->ged_wdbp->dbip->dbi_title = bu_strdup(cp);
	    if (oldTitle) {
		bu_free(oldTitle, "old title");
	    }
	}
    } else if (saveGlobalAttrs) {
	bu_avs_remove(&g_avs, "title");
    }

    if (importUnits) {
	if ((cp = bu_avs_get(&g_avs, "units")) != NULL) {
	    double dd;
	    if (sscanf(cp, "%lf", &dd) != 1 || NEAR_ZERO(dd, VUNITIZE_TOL)) {
		bu_log("copy_object(%s): improper database, %s object attribute 'units'=%s is invalid\n",
		       oldfile, DB5_GLOBAL_OBJECT_NAME, cp);
		bu_avs_remove(&g_avs, "units");
	    } else {
		gedp->ged_wdbp->dbip->dbi_local2base = dd;
		gedp->ged_wdbp->dbip->dbi_base2local = 1 / dd;
	    }
	}
    } else if (saveGlobalAttrs) {
	bu_avs_remove(&g_avs, "units");
    }

    if (saveGlobalAttrs) {
	dp = db_lookup(gedp->ged_wdbp->dbip, DB5_GLOBAL_OBJECT_NAME, LOOKUP_NOISY);
	db5_update_attributes(dp, &g_avs, gedp->ged_wdbp->dbip);
    }

    db_sync(gedp->ged_wdbp->dbip);	/* force changes to disk */

    /* Free the Hash tables */
    ptr = Tcl_FirstHashEntry(&name_tbl, &search);
    while (ptr) {
	bu_free((char *)Tcl_GetHashValue(ptr), "new name");
	ptr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&name_tbl);
    Tcl_DeleteHashTable(&used_names_tbl);

    return GED_OK;
}
示例#6
0
文件: tree.c 项目: cciechad/brlcad
/**
 * R T _ G E T T R E E _ R E G I O N _ E N D
 *
 * This routine will be called by db_walk_tree() once all the solids
 * in this region have been visited.
 *
 * This routine must be prepared to run in parallel.  As a result,
 * note that the details of the solids pointed to by the soltab
 * pointers in the tree may not be filled in when this routine is
 * called (due to the way multiple instances of solids are handled).
 * Therefore, everything which referred to the tree has been moved out
 * into the serial section.  (rt_tree_region_assign, rt_bound_tree)
 */
HIDDEN union tree *rt_gettree_region_end(register struct db_tree_state *tsp, struct db_full_path *pathp, union tree *curtree, genptr_t client_data)
{
    struct region		*rp;
    struct directory	*dp;
    int			shader_len=0;
    struct rt_i		*rtip;
    int			i;
    Tcl_HashTable		*tbl = (Tcl_HashTable *)client_data;
    Tcl_HashEntry		*entry;
    matp_t			inv_mat;

    RT_CK_DBI(tsp->ts_dbip);
    RT_CK_FULL_PATH(pathp);
    RT_CK_TREE(curtree);
    rtip =  tsp->ts_rtip;
    RT_CK_RTI(rtip);
    RT_CK_RESOURCE(tsp->ts_resp);

    if ( curtree->tr_op == OP_NOP )  {
	/* Ignore empty regions */
	return  curtree;
    }

    BU_GETSTRUCT( rp, region );
    rp->l.magic = RT_REGION_MAGIC;
    rp->reg_regionid = tsp->ts_regionid;
    rp->reg_is_fastgen = tsp->ts_is_fastgen;
    rp->reg_aircode = tsp->ts_aircode;
    rp->reg_gmater = tsp->ts_gmater;
    rp->reg_los = tsp->ts_los;

    if ( tsp->ts_attrs.count && tsp->ts_attrs.avp ) {
	rp->attr_values = (struct bu_mro **)bu_calloc( tsp->ts_attrs.count+1,
						       sizeof( struct bu_mro *), "regp->attr_values" );
	for ( i=0; i<tsp->ts_attrs.count; i++ ) {
	    rp->attr_values[i] = bu_malloc( sizeof( struct bu_mro ),
					    "rp->attr_values[i]" );
	    bu_mro_init_with_string( rp->attr_values[i], tsp->ts_attrs.avp[i].value );
	}
    } else {
	rp->attr_values = (struct bu_mro **)NULL;
    }

    rp->reg_mater = tsp->ts_mater; /* struct copy */
    if ( tsp->ts_mater.ma_shader )
	shader_len = strlen( tsp->ts_mater.ma_shader );
    if ( shader_len )
    {
	rp->reg_mater.ma_shader = bu_strdup( tsp->ts_mater.ma_shader );
    }
    else
	rp->reg_mater.ma_shader = (char *)NULL;

    rp->reg_name = db_path_to_string( pathp );

    dp = (struct directory *)DB_FULL_PATH_CUR_DIR(pathp);

    if (RT_G_DEBUG&DEBUG_TREEWALK)  {
	bu_log("rt_gettree_region_end() %s\n", rp->reg_name );
	rt_pr_tree( curtree, 0 );
    }

    rp->reg_treetop = curtree;
    rp->reg_all_unions = db_is_tree_all_unions( curtree );

    /* Determine material properties */
    rp->reg_mfuncs = (char *)0;
    rp->reg_udata = (char *)0;
    if ( rp->reg_mater.ma_color_valid == 0 )
	rt_region_color_map(rp);

    /* enter critical section */
    bu_semaphore_acquire( RT_SEM_RESULTS );

    rp->reg_instnum = dp->d_uses++;

    /*
     * Add the region to the linked list of regions.
     * Positions in the region bit vector are established at this time.
     */
    BU_LIST_INSERT( &(rtip->HeadRegion), &rp->l );

    /* Assign bit vector pos. */
    rp->reg_bit = rtip->nregions++;

    /* leave critical section */
    bu_semaphore_release( RT_SEM_RESULTS );

    if ( tbl && bu_avs_get( &tsp->ts_attrs, "ORCA_Comp" ) ) {
	int newentry;
	long int reg_bit = rp->reg_bit;

	inv_mat = (matp_t)bu_calloc( 16, sizeof( fastf_t ), "inv_mat" );
	if ( tsp->ts_mat )
	    bn_mat_inv( inv_mat, tsp->ts_mat );
	else
	    MAT_IDN( inv_mat );

	/* enter critical section */
	bu_semaphore_acquire( RT_SEM_RESULTS );

	entry = Tcl_CreateHashEntry(tbl, (char *)reg_bit, &newentry);
	Tcl_SetHashValue( entry, (ClientData)inv_mat );

	/* leave critical section */
	bu_semaphore_release( RT_SEM_RESULTS );
    }

    if ( RT_G_DEBUG & DEBUG_REGIONS )  {
	bu_log("Add Region %s instnum %d\n",
	       rp->reg_name, rp->reg_instnum);
    }

    /* Indicate that we have swiped 'curtree' */
    return(TREE_NULL);
}