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