HIDDEN int wdb_add_operand(Tcl_Interp *interp, struct bu_list *hp, char *name) { char *ptr_lparen; char *ptr_rparen; int name_len; union tree *node; struct tokens *tok; BU_CK_LIST_HEAD(hp); ptr_lparen = strchr(name, '('); ptr_rparen = strchr(name, ')'); RT_GET_TREE( node, &rt_uniresource ); node->magic = RT_TREE_MAGIC; node->tr_op = OP_DB_LEAF; node->tr_l.tl_mat = (matp_t)NULL; if (ptr_lparen || ptr_rparen) { int tmp1, tmp2; if (ptr_rparen) tmp1 = ptr_rparen - name; else tmp1 = (-1); if (ptr_lparen) tmp2 = ptr_lparen - name; else tmp2 = (-1); if (tmp2 == (-1) && tmp1 > 0) name_len = tmp1; else if (tmp1 == (-1) && tmp2 > 0) name_len = tmp2; else if (tmp1 > 0 && tmp2 > 0) { if (tmp1 < tmp2) name_len = tmp1; else name_len = tmp2; } else { Tcl_AppendResult(interp, "Cannot determine length of operand name: ", name, ", aborting\n", (char *)NULL); return (0); } } else name_len = strlen( name ); node->tr_l.tl_name = (char *)bu_malloc(name_len+1, "node name"); bu_strlcpy(node->tr_l.tl_name, name, name_len+1); tok = (struct tokens *)bu_malloc(sizeof(struct tokens), "tok"); tok->type = WDB_TOK_TREE; tok->tp = node; BU_LIST_INSERT(hp, &tok->l); return (name_len); }
HIDDEN int add_operand(struct ged *gedp, struct bu_list *hp, char *name) { char *ptr_lparen; char *ptr_rparen; int name_len; union tree *node; struct tokens *tok; BU_CK_LIST_HEAD(hp); ptr_lparen = strchr(name, '('); ptr_rparen = strchr(name, ')'); RT_GET_TREE(node, &rt_uniresource); node->tr_op = OP_DB_LEAF; node->tr_l.tl_mat = (matp_t)NULL; if (ptr_lparen || ptr_rparen) { int tmp1, tmp2; if (ptr_rparen) tmp1 = ptr_rparen - name; else tmp1 = (-1); if (ptr_lparen) tmp2 = ptr_lparen - name; else tmp2 = (-1); if (tmp2 == (-1) && tmp1 > 0) name_len = tmp1; else if (tmp1 == (-1) && tmp2 > 0) name_len = tmp2; else if (tmp1 > 0 && tmp2 > 0) { if (tmp1 < tmp2) name_len = tmp1; else name_len = tmp2; } else { bu_vls_printf(gedp->ged_result_str, "Cannot determine length of operand name: %s, aborting\n", name); return 0; } } else name_len = (int)strlen(name); node->tr_l.tl_name = (char *)bu_malloc(name_len+1, "node name"); bu_strlcpy(node->tr_l.tl_name, name, name_len+1); BU_ALLOC(tok, struct tokens); tok->type = TOK_TREE; tok->tp = node; BU_LIST_INSERT(hp, &tok->l); return name_len; }
static union tree * draw_check_leaf(struct db_tree_state *tsp, const struct db_full_path *pathp, struct rt_db_internal *ip, void *client_data) { union tree *curtree; struct _ged_client_data *dgcdp = (struct _ged_client_data *)client_data; /* Indicate success by returning something other than TREE_NULL */ RT_GET_TREE(curtree, tsp->ts_resp); curtree->tr_op = OP_NOP; switch (dgcdp->dmode) { case _GED_SHADED_MODE_BOTS: if (ip->idb_major_type == DB5_MAJORTYPE_BRLCAD && (ip->idb_minor_type == DB5_MINORTYPE_BRLCAD_BOT || ip->idb_minor_type == DB5_MINORTYPE_BRLCAD_POLY || ip->idb_minor_type == DB5_MINORTYPE_BRLCAD_BREP)) { plot_shaded(tsp, pathp, ip, dgcdp); } else { draw_forced_wireframe(pathp, dgcdp); } break; case _GED_SHADED_MODE_ALL: if (ip->idb_major_type == DB5_MAJORTYPE_BRLCAD && ip->idb_minor_type != DB5_MINORTYPE_BRLCAD_PIPE) { plot_shaded(tsp, pathp, ip, dgcdp); } else { draw_forced_wireframe(pathp, dgcdp); } break; } return curtree; }
int rt_comb_import4( struct rt_db_internal *ip, const struct bu_external *ep, const mat_t matrix, /* NULL if identity */ const struct db_i *dbip, struct resource *resp) { union record *rp; struct rt_tree_array *rt_tree_array; union tree *tree; struct rt_comb_internal *comb; size_t j; size_t node_count; BU_CK_EXTERNAL(ep); rp = (union record *)ep->ext_buf; if (dbip) RT_CK_DBI(dbip); if (rp[0].u_id != ID_COMB) { bu_log("rt_comb_import4: Attempt to import a non-combination\n"); return -1; } /* Compute how many granules of MEMBER records follow */ node_count = ep->ext_nbytes/sizeof(union record) - 1; if (node_count) rt_tree_array = (struct rt_tree_array *)bu_calloc(node_count, sizeof(struct rt_tree_array), "rt_tree_array"); else rt_tree_array = (struct rt_tree_array *)NULL; for (j = 0; j < node_count; j++) { if (rp[j+1].u_id != ID_MEMB) { bu_free((void *)rt_tree_array, "rt_comb_import4: rt_tree_array"); bu_log("rt_comb_import4(): granule in external buffer is not ID_MEMB, id=%d\n", rp[j+1].u_id); return -1; } switch (rp[j+1].M.m_relation) { case '+': rt_tree_array[j].tl_op = OP_INTERSECT; break; case '-': rt_tree_array[j].tl_op = OP_SUBTRACT; break; default: bu_log("rt_comb_import4() unknown op=x%x, assuming UNION\n", rp[j+1].M.m_relation); /* Fall through */ case 'u': rt_tree_array[j].tl_op = OP_UNION; break; } /* Build leaf node for in-memory tree */ { union tree *tp; mat_t diskmat; char namebuf[NAMESIZE+1]; RT_GET_TREE(tp, resp); rt_tree_array[j].tl_tree = tp; tp->tr_l.tl_op = OP_DB_LEAF; /* bu_strlcpy not safe here, buffer size mismatch */ memset(namebuf, 0, NAMESIZE+1); memcpy(namebuf, rp[j+1].M.m_instname, sizeof(rp[j+1].M.m_instname)); tp->tr_l.tl_name = bu_strdup(namebuf); flip_mat_dbmat(diskmat, rp[j+1].M.m_mat, dbip->dbi_version < 0 ? 1 : 0); /* Verify that rotation part is pure rotation */ if (fabs(diskmat[0]) > 1 || fabs(diskmat[1]) > 1 || fabs(diskmat[2]) > 1 || fabs(diskmat[4]) > 1 || fabs(diskmat[5]) > 1 || fabs(diskmat[6]) > 1 || fabs(diskmat[8]) > 1 || fabs(diskmat[9]) > 1 || fabs(diskmat[10]) > 1) { bu_log("ERROR: %s/%s improper scaling, rotation matrix elements > 1\n", rp[0].c.c_name, namebuf); } /* Verify that perspective isn't used as a modeling transform */ if (!ZERO(diskmat[12]) || !ZERO(diskmat[13]) || !ZERO(diskmat[14])) { bu_log("ERROR: %s/%s has perspective transform\n", rp[0].c.c_name, namebuf); } /* See if disk record is identity matrix */ if (bn_mat_is_identity(diskmat)) { if (matrix == NULL) { tp->tr_l.tl_mat = NULL; /* identity */ } else { tp->tr_l.tl_mat = bn_mat_dup(matrix); } } else { if (matrix == NULL) { tp->tr_l.tl_mat = bn_mat_dup(diskmat); } else { mat_t prod; bn_mat_mul(prod, matrix, diskmat); tp->tr_l.tl_mat = bn_mat_dup(prod); } } /* bu_log("M_name=%s, matp=x%x\n", tp->tr_l.tl_name, tp->tr_l.tl_mat); */ } } if (node_count) tree = db_mkgift_tree(rt_tree_array, node_count, &rt_uniresource); else tree = (union tree *)NULL; RT_DB_INTERNAL_INIT(ip); ip->idb_major_type = DB5_MAJORTYPE_BRLCAD; ip->idb_type = ID_COMBINATION; ip->idb_meth = &OBJ[ID_COMBINATION]; BU_ALLOC(comb, struct rt_comb_internal); RT_COMB_INTERNAL_INIT(comb); comb->tree = tree; ip->idb_ptr = (void *)comb; switch (rp[0].c.c_flags) { case DBV4_NON_REGION_NULL: case DBV4_NON_REGION: comb->region_flag = 0; break; case DBV4_REGION: comb->region_flag = 1; comb->is_fastgen = REGION_NON_FASTGEN; break; case DBV4_REGION_FASTGEN_PLATE: comb->region_flag = 1; comb->is_fastgen = REGION_FASTGEN_PLATE; break; case DBV4_REGION_FASTGEN_VOLUME: comb->region_flag = 1; comb->is_fastgen = REGION_FASTGEN_VOLUME; break; default: bu_log("WARNING: combination %s has illegal c_flag=x%x\n", rp[0].c.c_name, rp[0].c.c_flags); break; } if (comb->region_flag) { if (dbip->dbi_version < 0) { comb->region_id = flip_short(rp[0].c.c_regionid); comb->aircode = flip_short(rp[0].c.c_aircode); comb->GIFTmater = flip_short(rp[0].c.c_material); comb->los = flip_short(rp[0].c.c_los); } else { comb->region_id = rp[0].c.c_regionid; comb->aircode = rp[0].c.c_aircode; comb->GIFTmater = rp[0].c.c_material; comb->los = rp[0].c.c_los; } } else { /* set some reasonable defaults */ comb->region_id = 0; comb->aircode = 0; comb->GIFTmater = 0; comb->los = 0; } comb->rgb_valid = rp[0].c.c_override; if (comb->rgb_valid) { comb->rgb[0] = rp[0].c.c_rgb[0]; comb->rgb[1] = rp[0].c.c_rgb[1]; comb->rgb[2] = rp[0].c.c_rgb[2]; } if (rp[0].c.c_matname[0] != '\0') { #define MAX_SS 128 char shader_str[MAX_SS]; memset(shader_str, 0, MAX_SS); /* copy shader info to a static string */ /* write shader name. c_matname is a buffer, bu_strlcpy not * safe here. */ memcpy(shader_str, rp[0].c.c_matname, sizeof(rp[0].c.c_matname)); bu_strlcat(shader_str, " ", MAX_SS); /* write shader parameters. c_matparm is a buffer, bu_strlcpy * not safe here. */ memcpy(shader_str+strlen(shader_str), rp[0].c.c_matparm, sizeof(rp[0].c.c_matparm)); /* convert to TCL format and place into comb->shader */ if (bu_shader_to_list(shader_str, &comb->shader)) { bu_log("rt_comb_import4: Error: Cannot convert following shader to TCL format:\n"); bu_log("\t%s\n", shader_str); bu_vls_free(&comb->shader); return -1; } } /* XXX Separate flags for color inherit, shader inherit, (new) material inherit? */ /* XXX cf: ma_cinherit, ma_minherit */ /* This ? is necessary to clean up old databases with grunge here */ comb->inherit = (rp[0].c.c_inherit == DB_INH_HIGHER) ? 1 : 0; /* Automatic material table lookup here? */ if (comb->region_flag) bu_vls_printf(&comb->material, "gift%ld", comb->GIFTmater); if (rt_tree_array) bu_free((void *)rt_tree_array, "rt_tree_array"); return 0; }
/** * R T _ G E T T R E E _ L E A F * * This routine must be prepared to run in parallel. */ HIDDEN union tree *rt_gettree_leaf(struct db_tree_state *tsp, struct db_full_path *pathp, struct rt_db_internal *ip, genptr_t client_data) /*const*/ /*const*/ { register struct soltab *stp; union tree *curtree; struct directory *dp; register matp_t mat; int i; struct rt_i *rtip; RT_CK_DBTS(tsp); RT_CK_DBI(tsp->ts_dbip); RT_CK_FULL_PATH(pathp); RT_CK_DB_INTERNAL(ip); rtip = tsp->ts_rtip; RT_CK_RTI(rtip); RT_CK_RESOURCE(tsp->ts_resp); dp = DB_FULL_PATH_CUR_DIR(pathp); /* Determine if this matrix is an identity matrix */ if ( !bn_mat_is_equal(tsp->ts_mat, bn_mat_identity, &rtip->rti_tol)) { /* Not identity matrix */ mat = (matp_t)tsp->ts_mat; } else { /* Identity matrix */ mat = (matp_t)0; } /* * Check to see if this exact solid has already been processed. * Match on leaf name and matrix. Note that there is a race here * between having st_id filled in a few lines below (which is * necessary for calling ft_prep), and ft_prep filling in * st_aradius. Fortunately, st_aradius starts out as zero, and * will never go down to -1 unless this soltab structure has * become a dead solid, so by testing against -1 (instead of <= 0, * like before, oops), it isn't a problem. */ stp = rt_find_identical_solid( mat, dp, rtip ); if ( stp->st_id != 0 ) { /* stp is an instance of a pre-existing solid */ if ( stp->st_aradius <= -1 ) { /* It's dead, Jim. st_uses was not incremented. */ return( TREE_NULL ); /* BAD: instance of dead solid */ } goto found_it; } if ( rtip->rti_add_to_new_solids_list ) { bu_ptbl_ins( &rtip->rti_new_solids, (long *)stp ); } stp->st_id = ip->idb_type; stp->st_meth = &rt_functab[ip->idb_type]; if ( mat ) { mat = stp->st_matp; } else { mat = (matp_t)bn_mat_identity; } RT_CK_DB_INTERNAL( ip ); /* init solid's maxima and minima */ VSETALL( stp->st_max, -INFINITY ); VSETALL( stp->st_min, INFINITY ); /* * If the ft_prep routine wants to keep the internal structure, * that is OK, as long as idb_ptr is set to null. Note that the * prep routine may have changed st_id. */ if ( stp->st_meth->ft_prep( stp, ip, rtip ) ) { int hash; /* Error, solid no good */ bu_log("rt_gettree_leaf(%s): prep failure\n", dp->d_namep ); /* Too late to delete soltab entry; mark it as "dead" */ hash = db_dirhash( dp->d_namep ); ACQUIRE_SEMAPHORE_TREE(hash); stp->st_aradius = -1; stp->st_uses--; RELEASE_SEMAPHORE_TREE(hash); return( TREE_NULL ); /* BAD */ } if ( rtip->rti_dont_instance ) { /* * If instanced solid refs are not being compressed, then * memory isn't an issue, and the application (such as * solids_on_ray) probably cares about the full path of this * solid, from root to leaf. So make it available here. * (stp->st_dp->d_uses could be the way to discriminate * references uniquely, if the path isn't enough. To locate * given dp and d_uses, search dp->d_use_hd list. Question * is, where to stash current val of d_uses?) */ db_full_path_init( &stp->st_path ); db_dup_full_path( &stp->st_path, pathp ); } else { /* * If there is more than just a direct reference to this leaf * from it's containing region, copy that below-region path * into st_path. Otherwise, leave st_path's magic number 0. * * XXX nothing depends on this behavior yet, and this whole * XXX 'else' clause might well be deleted. -Mike */ i = pathp->fp_len-1; if ( i > 0 && !(pathp->fp_names[i-1]->d_flags & DIR_REGION) ) { /* Search backwards for region. If no region, use whole path */ for ( --i; i > 0; i-- ) { if ( pathp->fp_names[i-1]->d_flags & DIR_REGION ) break; } if ( i < 0 ) i = 0; db_full_path_init( &stp->st_path ); db_dup_path_tail( &stp->st_path, pathp, i ); } } if (RT_G_DEBUG&DEBUG_TREEWALK && stp->st_path.magic == DB_FULL_PATH_MAGIC) { char *sofar = db_path_to_string(&stp->st_path); bu_log("rt_gettree_leaf() st_path=%s\n", sofar ); bu_free(sofar, "path string"); } if (RT_G_DEBUG&DEBUG_SOLIDS) { struct bu_vls str; bu_log("\n---Primitive %d: %s\n", stp->st_bit, dp->d_namep); bu_vls_init( &str ); /* verbose=1, mm2local=1.0 */ if ( stp->st_meth->ft_describe( &str, ip, 1, 1.0, tsp->ts_resp, tsp->ts_dbip ) < 0 ) { bu_log("rt_gettree_leaf(%s): solid describe failure\n", dp->d_namep ); } bu_log( "%s: %s", dp->d_namep, bu_vls_addr( &str ) ); bu_vls_free( &str ); } found_it: RT_GET_TREE( curtree, tsp->ts_resp ); curtree->magic = RT_TREE_MAGIC; curtree->tr_op = OP_SOLID; curtree->tr_a.tu_stp = stp; /* regionp will be filled in later by rt_tree_region_assign() */ curtree->tr_a.tu_regionp = (struct region *)0; if (RT_G_DEBUG&DEBUG_TREEWALK) { char *sofar = db_path_to_string(pathp); bu_log("rt_gettree_leaf() %s\n", sofar ); bu_free(sofar, "path string"); } return(curtree); }