コード例 #1
0
ファイル: wdb_comb_std.c プロジェクト: cciechad/brlcad
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);
}
コード例 #2
0
ファイル: comb_std.c プロジェクト: kanzure/brlcad
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;
}
コード例 #3
0
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;
}
コード例 #4
0
ファイル: db_comb.c プロジェクト: kanzure/brlcad
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;
}
コード例 #5
0
ファイル: tree.c プロジェクト: cciechad/brlcad
/**
 * 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);
}