コード例 #1
0
ファイル: db_diff.c プロジェクト: kanzure/brlcad
/* Exposed as private function to librt, but not (currently) beyond librt -
 * see librt_private.h */
int
tcl_list_to_avs(const char *tcl_list, struct bu_attribute_value_set *avs, int offset)
{
    int i = 0;
    int list_c = 0;
    const char **listv = (const char **)NULL;

    if (Tcl_SplitList(NULL, tcl_list, &list_c, (const char ***)&listv) != TCL_OK) {
	return -1;
    }

    if (!BU_AVS_IS_INITIALIZED(avs)) BU_AVS_INIT(avs);

    if (!list_c) {
	Tcl_Free((char *)listv);
	return 0;
    }

    if (list_c > 2) {
	for (i = offset; i < list_c; i += 2) {
	    (void)bu_avs_add(avs, listv[i], listv[i+1]);
	}
    } else {
	return -1;
    }

    Tcl_Free((char *)listv);
    return 0;
}
コード例 #2
0
/**
 * 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));
	}
    }
コード例 #3
0
HIDDEN int
constraint_set(void *datap, int argc, const char *argv[])
{
    struct directory *dp;
    struct bu_attribute_value_set avs = BU_AVS_INIT_ZERO;
    struct bu_vls expression = BU_VLS_INIT_ZERO;
    struct ged *gedp = (struct ged *)datap;

    if (!gedp || argc < 3 || !argv)
	return BRLCAD_ERROR;

    GED_CHECK_READ_ONLY(gedp, GED_ERROR);

    dp = db_lookup(gedp->ged_wdbp->dbip, argv[2], LOOKUP_QUIET);
    if (!dp) {
	/* TODO: need to create the object here */
	return BRLCAD_ERROR;
    }

    if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) {
	bu_vls_printf(gedp->ged_result_str, "Cannot get constraints for %s\n", dp->d_namep);
	bu_avs_free(&avs);
	return BRLCAD_ERROR;
    }

    bu_vls_from_argv(&expression, argc-4, &argv[4]);
    (void)bu_avs_add(&avs, argv[3], bu_vls_addr(&expression));
    bu_vls_free(&expression);

    if (db5_update_attributes(dp, &avs, gedp->ged_wdbp->dbip)) {
	bu_vls_printf(gedp->ged_result_str, "Failed to set constraints on %s\n", dp->d_namep);
	bu_avs_free(&avs);
	return GED_ERROR;
    }

    bu_avs_free(&avs);

    return BRLCAD_OK;
}
コード例 #4
0
ファイル: attributes.c プロジェクト: kanzure/brlcad
int
db5_import_attributes(struct bu_attribute_value_set *avs, const struct bu_external *ap)
{
    const char *cp;
    const char *ep;
    int count = 0;
#if defined(USE_BINARY_ATTRIBUTES)
    int bcount = 0; /* for the subset of binary attributes */
#endif

    BU_CK_EXTERNAL(ap);

    BU_ASSERT_LONG(ap->ext_nbytes, >=, 4);

    /* First pass -- count number of attributes */
    cp = (const char *)ap->ext_buf;
    ep = (const char *)ap->ext_buf+ap->ext_nbytes;

    /* Null "name" string (a pair of NULLs) indicates end of attribute
     * list (for the original ASCII-valued attributes) */
    while (*cp != '\0') {
	if (cp >= ep) {
	    bu_log("db5_import_attributes() ran off end of buffer, database is probably corrupted\n");
	    return -1;
	}
	cp += strlen(cp)+1;	/* value */
	cp += strlen(cp)+1;	/* next name */
	count++;
    }
#if defined(USE_BINARY_ATTRIBUTES)
    /* Do we have binary attributes?  If so, they are after the last
     * ASCII attribute. */
    if (ep > (cp+1)) {
	/* Count binary attrs. */
	/* format is: <ascii name> NULL <binary length [network order, must be decoded]> <bytes...> */
	size_t abinlen;
	cp += 2; /* We are now at the first byte of the first binary attribute... */
	while (cp != ep) {
	    ++bcount
	    cp += strlen(cp)+1;	/* name */
	    /* The next value is an unsigned integer of variable width
	     * (a_width: DB5HDR_WIDTHCODE_x) so how do we get its
	     * width?  We now have a new member of struct bu_external:
	     * 'unsigned char intwid'.  Note that the integer
	     * is in network order and must be properly decoded for
	     * the local architecture.
	     */
	    cp += db5_decode_length(&abinlen, cp, ap->intwid);
	    /* account for the abinlen bytes */
	    cp += abinlen;
	}
	/* now cp should be at the end */
	count += bcount;
    } else {
	/* step to the end for the sanity check */
	++cp;
    }
    /* Ensure we're exactly at the end */
    BU_ASSERT_PTR(cp, ==, ep);
#else
    /* Ensure we're exactly at the end */
    BU_ASSERT_PTR(cp+1, ==, ep);
#endif

    /* not really needed for AVS_ADD since bu_avs_add will
     * incrementally allocate as it needs it. but one alloc is better
     * than many in case there are many attributes.
     */
    bu_avs_init(avs, count, "db5_import_attributes");

    /* Second pass -- populate attributes. */

    /* Copy the values from the external buffer instead of using them
     * directly without copying.  This presumes ap will not get free'd
     * before we're done with the avs.
     */

    cp = (const char *)ap->ext_buf;
    while (*cp != '\0') {
	const char *name = cp;  /* name */
	cp += strlen(cp)+1; /* value */
	bu_avs_add(avs, name, cp);
	cp += strlen(cp)+1; /* next name */
    }
#if defined(USE_BINARY_ATTRIBUTES)
    /* Do we have binary attributes?  If so, they are after the last
     * ASCII attribute. */
    if (ep > (cp+1)) {
	/* Count binary attrs. */
	/* format is: <ascii name> NULL <binary length [network order, must be decoded]> <bytes...> */
	size_t abinlen;
	cp += 2; /* We are now at the first byte of the first binary attribute... */
	while (cp != ep) {
	    const char *name = cp;  /* name */
	    cp += strlen(cp)+1;	/* name */
	    cp += db5_decode_length(&abinlen, cp, ap->intwid);
	    /* now decode for the abinlen bytes */
	    decode_binary_attribute(const size_t len, const char *cp)
	    decod
	    cp += abinlen;
	}
	/* now cp should be at the end */
    } else {
コード例 #5
0
int
ged_draw_guts(struct ged *gedp, int argc, const char *argv[], int kind)
{
    size_t i;
    int drawtrees_retval;
    int flag_A_attr=0;
    int flag_o_nonunique=1;
    int last_opt=0;
    struct bu_vls vls = BU_VLS_INIT_ZERO;
    static const char *usage = "<[-R -C#/#/# -s] objects> | <-o -A attribute name/value pairs>";

/* #define DEBUG_TIMING 1 */

#ifdef DEBUG_TIMING
    int64_t elapsedtime;
#endif

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

#ifdef DEBUG_TIMING
    elapsedtime = bu_gettime();
#endif

    /* skip past cmd */
    --argc;
    ++argv;

    /* check args for "-A" (attributes) and "-o" */
    for (i = 0; i < (size_t)argc; i++) {
	char *ptr_A=NULL;
	char *ptr_o=NULL;
	char *c;

	if (*argv[i] != '-') {
	    /* Done checking options. If our display is non-empty,
	     * add -R to keep current view.
	     */
	    if (BU_LIST_NON_EMPTY(gedp->ged_gdp->gd_headDisplay)) {
		bu_vls_strcat(&vls, " -R");
	    }
	    break;
	}

	ptr_A=strchr(argv[i], 'A');
	if (ptr_A)
	    flag_A_attr = 1;

	ptr_o=strchr(argv[i], 'o');
	if (ptr_o)
	    flag_o_nonunique = 2;

	last_opt = i;

	if (!ptr_A && !ptr_o) {
	    bu_vls_putc(&vls, ' ');
	    bu_vls_strcat(&vls, argv[i]);
	    continue;
	}

	if (strlen(argv[i]) == ((size_t)1 + (ptr_A != NULL) + (ptr_o != NULL))) {
	    /* argv[i] is just a "-A" or "-o" */
	    continue;
	}

	/* copy args other than "-A" or "-o" */
	bu_vls_putc(&vls, ' ');
	c = (char *)argv[i];
	while (*c != '\0') {
	    if (*c != 'A' && *c != 'o') {
		bu_vls_putc(&vls, *c);
	    }
	    c++;
	}
    }

    if (flag_A_attr) {
	/* args are attribute name/value pairs */
	struct bu_attribute_value_set avs;
	int max_count=0;
	int remaining_args=0;
	int new_argc=0;
	char **new_argv=NULL;
	struct bu_ptbl *tbl;

	remaining_args = argc - last_opt - 1;
	if (remaining_args < 2 || remaining_args%2) {
	    bu_vls_printf(gedp->ged_result_str, "Error: must have even number of arguments (name/value pairs)\n");
	    bu_vls_free(&vls);
	    return GED_ERROR;
	}

	bu_avs_init(&avs, (argc - last_opt)/2, "ged_draw_guts avs");
	i = 0;
	while (i < (size_t)argc) {
	    if (*argv[i] == '-') {
		i++;
		continue;
	    }

	    /* this is a name/value pair */
	    if (flag_o_nonunique == 2) {
		bu_avs_add_nonunique(&avs, argv[i], argv[i+1]);
	    } else {
		bu_avs_add(&avs, argv[i], argv[i+1]);
	    }
	    i += 2;
	}

	tbl = db_lookup_by_attr(gedp->ged_wdbp->dbip, RT_DIR_REGION | RT_DIR_SOLID | RT_DIR_COMB, &avs, flag_o_nonunique);
	bu_avs_free(&avs);
	if (!tbl) {
	    bu_log("Error: db_lookup_by_attr() failed!!\n");
	    bu_vls_free(&vls);
	    return TCL_ERROR;
	}
	if (BU_PTBL_LEN(tbl) < 1) {
	    /* nothing matched, just return */
	    bu_vls_free(&vls);
	    return TCL_OK;
	}
	for (i = 0; i < BU_PTBL_LEN(tbl); i++) {
	    struct directory *dp;

	    dp = (struct directory *)BU_PTBL_GET(tbl, i);
	    bu_vls_putc(&vls, ' ');
	    bu_vls_strcat(&vls, dp->d_namep);
	}

	max_count = BU_PTBL_LEN(tbl) + last_opt + 1;
	bu_ptbl_free(tbl);
	bu_free((char *)tbl, "ged_draw_guts ptbl");
	new_argv = (char **)bu_calloc(max_count+1, sizeof(char *), "ged_draw_guts new_argv");
	new_argc = bu_argv_from_string(new_argv, max_count, bu_vls_addr(&vls));

	/* First, delete any mention of these objects.
	 * Silently skip any leading options (which start with minus signs).
	 */
	for (i = 0; i < (size_t)new_argc; ++i) {
	    /* Skip any options */
	    if (new_argv[i][0] == '-') {
		/* If this option requires an argument which was
		 * provided separately (e.g. '-C 0/255/0' instead of
		 * '-C0/255/0'), skip the argument too.
		 */
		if (strlen(argv[i]) == 2 && strchr("mxCP", argv[i][1])) {
		    i++;
		}
		continue;
	    }

	    dl_erasePathFromDisplay(gedp->ged_gdp->gd_headDisplay, gedp->ged_wdbp->dbip, gedp->ged_free_vlist_callback, new_argv[i], 0, gedp->freesolid);
	}

	drawtrees_retval = _ged_drawtrees(gedp, new_argc, (const char **)new_argv, kind, (struct _ged_client_data *)0);
	bu_vls_free(&vls);
	bu_free((char *)new_argv, "ged_draw_guts new_argv");
	if (drawtrees_retval) {
	    return GED_ERROR;
	}
    } else {
	int empty_display;
	bu_vls_free(&vls);

	empty_display = 1;
	if (BU_LIST_NON_EMPTY(gedp->ged_gdp->gd_headDisplay)) {
	    empty_display = 0;
	}

	/* First, delete any mention of these objects.
	 * Silently skip any leading options (which start with minus signs).
	 */
	for (i = 0; i < (size_t)argc; ++i) {
	    /* Skip any options */
	    if (argv[i][0] == '-') {
		/* If this option requires an argument which was
		 * provided separately (e.g. '-C 0/255/0' instead of
		 * '-C0/255/0'), skip the argument too.
		 */
		if (strlen(argv[i]) == 2 && strchr("mxCP", argv[i][1])) {
		    i++;
		}
		continue;
	    }

	    dl_erasePathFromDisplay(gedp->ged_gdp->gd_headDisplay, gedp->ged_wdbp->dbip, gedp->ged_free_vlist_callback, argv[i], 0, gedp->freesolid);
	}

	/* if our display is non-empty add -R to keep current view */
	if (!empty_display) {
	    int new_argc;
	    char **new_argv;

	    new_argc = argc + 1;
	    new_argv = (char **)bu_malloc(new_argc * sizeof(char *), "ged_draw_guts new_argv");

	    new_argv[0] = bu_strdup("-R");
	    for (i = 0; i < (size_t)argc; ++i) {
		new_argv[i + 1] = bu_strdup(argv[i]);
	    }

	    drawtrees_retval = _ged_drawtrees(gedp, new_argc, (const char **)new_argv, kind, (struct _ged_client_data *)0);

	    for (i = 0; i < (size_t)new_argc; ++i) {
		bu_free(new_argv[i], "ged_draw_guts new_argv[i] - bu_strdup(argv[i])");
	    }
	    bu_free(new_argv, "ged_draw_guts new_argv");
	} else {
	    drawtrees_retval = _ged_drawtrees(gedp, argc, argv, kind, (struct _ged_client_data *)0);
	}
	if (drawtrees_retval) {
	    return GED_ERROR;
	}
    }

#ifdef DEBUG_TIMING
    elapsedtime = bu_gettime() - elapsedtime;
    {
	int seconds = elapsedtime / 1000000;
	int minutes = seconds / 60;
	int hours = minutes / 60;

	minutes = minutes % 60;
	seconds = seconds %60;

	bu_vls_printf(gedp->ged_result_str, "Elapsed time: %02d:%02d:%02d\n", hours, minutes, seconds);
    }
#endif

    return GED_OK;
}
コード例 #6
0
ファイル: tree.c プロジェクト: cciechad/brlcad
/**
 * R T _ G E T T R E E S _ M U V E S
 *
 * User-called function to add a set of tree hierarchies to the active
 * set. Includes getting the indicated list of attributes and a
 * Tcl_HashTable for use with the ORCA man regions. (stashed in the
 * rt_i structure).
 *
 * This function may run in parallel, but is not multiply re-entrant
 * itself, because db_walk_tree() isn't multiply re-entrant.
 *
 * Semaphores used for critical sections in parallel mode:
 *	RT_SEM_TREE*	protects rti_solidheads[] lists, d_uses(solids)
 *	RT_SEM_RESULTS	protects HeadRegion, mdl_min/max, d_uses(reg), nregions
 *	RT_SEM_WORKER	(db_walk_dispatcher, from db_walk_tree)
 *	RT_SEM_STATS	nsolids
 *
 * INPUTS
 *	rtip	- RT instance pointer
 *	attrs	- array of pointers (NULL terminated) to strings (attribute names). A corresponding
 *		  array of "bu_mro" objects containing the attribute values will be attached to region
 *		  structures ("attr_values")
 *	argc	- number of trees to get
 *	argv	- array of char pointers to the names of the tree tops
 *	ncpus	- number of cpus to use
 *
 * Returns -
 *  	0	Ordinarily
 *	-1	On major error
 */
int
rt_gettrees_muves(struct rt_i *rtip, const char **attrs, int argc, const char **argv, int ncpus)
{
    register struct soltab	*stp;
    register struct region	*regp;
    Tcl_HashTable		*tbl;
    int			prev_sol_count;
    int			i;
    int			num_attrs=0;
    point_t			region_min, region_max;

    RT_CHECK_RTI(rtip);
    RT_CK_DBI(rtip->rti_dbip);

    if (!rtip->needprep)  {
	bu_log("ERROR: rt_gettree() called again after rt_prep!\n");
	return(-1);		/* FAIL */
    }

    if ( argc <= 0 )  return(-1);	/* FAIL */

    tbl = (Tcl_HashTable *)bu_malloc( sizeof( Tcl_HashTable ), "rtip->Orca_hash_tbl" );
    Tcl_InitHashTable( tbl, TCL_ONE_WORD_KEYS );
    rtip->Orca_hash_tbl = (genptr_t)tbl;

    prev_sol_count = rtip->nsolids;

    {
	struct db_tree_state	tree_state;

	tree_state = rt_initial_tree_state;	/* struct copy */
	tree_state.ts_dbip = rtip->rti_dbip;
	tree_state.ts_rtip = rtip;
	tree_state.ts_resp = NULL;	/* sanity.  Needs to be updated */

	if ( attrs ) {
	    if ( rtip->rti_dbip->dbi_version < 5 ) {
		bu_log( "WARNING: requesting attributes from an old database version (ignored)\n" );
		bu_avs_init_empty( &tree_state.ts_attrs );
	    } else {
		while ( attrs[num_attrs] ) {
		    num_attrs++;
		}
		if ( num_attrs ) {
		    bu_avs_init( &tree_state.ts_attrs,
				 num_attrs,
				 "avs in tree_state" );
		    num_attrs = 0;
		    while ( attrs[num_attrs] ) {
			bu_avs_add( &tree_state.ts_attrs,
				    attrs[num_attrs],
				    NULL );
			num_attrs++;
		    }
		} else {
		    bu_avs_init_empty( &tree_state.ts_attrs );
		}
	    }
	} else {
	    bu_avs_init_empty( &tree_state.ts_attrs );
	}

	/* ifdef this out for now, it is only using memory.  perhaps a
	 * better way of initiating ORCA stuff can be found.
	 */
#if 0
	bu_avs_add( &tree_state.ts_attrs, "ORCA_Comp", (char *)NULL );
#endif
	i = db_walk_tree( rtip->rti_dbip, argc, argv, ncpus,
			  &tree_state,
			  rt_gettree_region_start,
			  rt_gettree_region_end,
			  rt_gettree_leaf, (genptr_t)tbl );
	bu_avs_free( &tree_state.ts_attrs );
    }

    /* DEBUG:  Ensure that all region trees are valid */
    for ( BU_LIST_FOR( regp, region, &(rtip->HeadRegion) ) )  {
	RT_CK_REGION(regp);
	db_ck_tree(regp->reg_treetop);
    }

    /*
     * Eliminate any "dead" solids that parallel code couldn't change.
     * First remove any references from the region tree, then remove
     * actual soltab structs from the soltab list.
     */
    for ( BU_LIST_FOR( regp, region, &(rtip->HeadRegion) ) )  {
	RT_CK_REGION(regp);
	rt_tree_kill_dead_solid_refs( regp->reg_treetop );
	(void)rt_tree_elim_nops( regp->reg_treetop, &rt_uniresource );
    }
 again:
    RT_VISIT_ALL_SOLTABS_START( stp, rtip )  {
	RT_CK_SOLTAB(stp);
	if ( stp->st_aradius <= 0 )  {
	    bu_log("rt_gettrees() cleaning up dead solid '%s'\n",
		   stp->st_dp->d_namep );
	    rt_free_soltab(stp);
	    /* Can't do rtip->nsolids--, that doubles as max bit number! */
	    /* The macro makes it hard to regain place, punt */
	    goto again;
	}
    } RT_VISIT_ALL_SOLTABS_END