示例#1
0
文件: superell.c 项目: kanzure/brlcad
/**
 * The external format is:
 * V point
 * A vector
 * B vector
 * C vector
 */
int
rt_superell_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
{
    struct rt_superell_internal *eip;

    /* must be double for import and export */
    double vec[ELEMENTS_PER_VECT*4 + 2];

    if (dbip) RT_CK_DBI(dbip);

    RT_CK_DB_INTERNAL(ip);
    if (ip->idb_type != ID_SUPERELL) return -1;
    eip = (struct rt_superell_internal *)ip->idb_ptr;
    RT_SUPERELL_CK_MAGIC(eip);

    BU_CK_EXTERNAL(ep);
    ep->ext_nbytes = SIZEOF_NETWORK_DOUBLE * (ELEMENTS_PER_VECT*4 + 2);
    ep->ext_buf = (uint8_t *)bu_malloc(ep->ext_nbytes, "superell external");

    /* scale 'em into local buffer */
    VSCALE(&vec[0*ELEMENTS_PER_VECT], eip->v, local2mm);
    VSCALE(&vec[1*ELEMENTS_PER_VECT], eip->a, local2mm);
    VSCALE(&vec[2*ELEMENTS_PER_VECT], eip->b, local2mm);
    VSCALE(&vec[3*ELEMENTS_PER_VECT], eip->c, local2mm);

    vec[4*ELEMENTS_PER_VECT] = eip->n;
    vec[4*ELEMENTS_PER_VECT + 1] = eip->e;

    /* Convert from internal (host) to database (network) format */
    bu_cv_htond(ep->ext_buf, (unsigned char *)vec, ELEMENTS_PER_VECT*4 + 2);

    return 0;
}
int
rt_obj_import(struct rt_db_internal *ip, const struct bu_external *ep, const mat_t mat, const struct db_i *dbip, struct resource *resp)
{
    int id;
    const struct rt_functab *ft;
    int (*import)(struct rt_db_internal *, const struct bu_external *, const mat_t, const struct db_i *, struct resource *);

    if (!ip || !ep || !dbip)
	return -1;

    RT_CK_DB_INTERNAL(ip);
    BU_CK_EXTERNAL(ep);
    RT_CK_DBI(dbip);
    if (resp) RT_CK_RESOURCE(resp);

    id = ip->idb_minor_type;
    if (id < 0)
	return -2;

    ft = &OBJ[id];
    if (!ft)
	return -3;

    if (dbip->dbi_version < 5) {
	import = ft->ft_import4;
    } else {
	import = ft->ft_import5;
    }

    if (!import)
	return -4;

    return import(ip, ep, mat, dbip, resp);
}
示例#3
0
文件: xxx.c 项目: kanzure/brlcad
/**
 * Export an XXX from internal form to external format.  Note that
 * this means converting all integers to Big-Endian format and
 * floating point data to IEEE double.
 *
 * Apply the transformation to mm units as well.
 */
int
rt_xxx_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
{
    struct rt_xxx_internal *xxx_ip;

    /* must be double for import and export */
    double vec[ELEMENTS_PER_VECT];

    RT_CK_DB_INTERNAL(ip);
    if (ip->idb_type != ID_XXX) return -1;
    xxx_ip = (struct rt_xxx_internal *)ip->idb_ptr;
    RT_XXX_CK_MAGIC(xxx_ip);
    if (dbip) RT_CK_DBI(dbip);

    BU_CK_EXTERNAL(ep);
    ep->ext_nbytes = SIZEOF_NETWORK_DOUBLE * ELEMENTS_PER_VECT;
    ep->ext_buf = (void *)bu_calloc(1, ep->ext_nbytes, "xxx external");

    /* Since libwdb users may want to operate in units other than mm,
     * we offer the opportunity to scale the solid (to get it into mm)
     * on the way out.
     */
    VSCALE(vec, xxx_ip->v, local2mm);

    /* Convert from internal (host) to database (network) format */
    bu_cv_htond(ep->ext_buf, (unsigned char *)vec, ELEMENTS_PER_VECT);

    return 0;
}
示例#4
0
文件: xxx.c 项目: kanzure/brlcad
/**
 * Import an XXX from the database format to the internal format.
 * Note that the data read will be in network order.  This means
 * Big-Endian integers and IEEE doubles for floating point.
 *
 * Apply modeling transformations as well.
 */
int
rt_xxx_import5(struct rt_db_internal *ip, const struct bu_external *ep, const mat_t mat, const struct db_i *dbip)
{
    struct rt_xxx_internal *xxx_ip;

    /* must be double for import and export */
    double vv[ELEMENTS_PER_VECT*1];

    RT_CK_DB_INTERNAL(ip);
    BU_CK_EXTERNAL(ep);
    if (dbip) RT_CK_DBI(dbip);

    BU_ASSERT_LONG(ep->ext_nbytes, ==, SIZEOF_NETWORK_DOUBLE * 3*4);

    /* set up the internal structure */
    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_XXX;
    ip->idb_meth = &OBJ[ID_XXX];
    BU_ALLOC(ip->idb_ptr, struct rt_xxx_internal);

    xxx_ip = (struct rt_xxx_internal *)ip->idb_ptr;
    xxx_ip->magic = RT_XXX_INTERNAL_MAGIC;

    /* Convert the data in ep->ext_buf into internal format.  Note the
     * conversion from network data (Big Endian ints, IEEE double
     * floating point) to host local data representations.
     */
    bu_cv_ntohd((unsigned char *)&vv, (unsigned char *)ep->ext_buf, ELEMENTS_PER_VECT*1);

    /* Apply the modeling transformation */
    if (mat == NULL) mat = bn_mat_identity;
    MAT4X3PNT(xxx_ip->v, mat, vv);

    return 0;			/* OK */
}
示例#5
0
文件: superell.c 项目: kanzure/brlcad
int
rt_superell_export4(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
{
    struct rt_superell_internal *tip;
    union record *rec;

    if (dbip) RT_CK_DBI(dbip);

    RT_CK_DB_INTERNAL(ip);
    if (ip->idb_type != ID_SUPERELL) return -1;
    tip = (struct rt_superell_internal *)ip->idb_ptr;
    RT_SUPERELL_CK_MAGIC(tip);

    BU_CK_EXTERNAL(ep);
    ep->ext_nbytes = sizeof(union record);
    ep->ext_buf = (uint8_t *)bu_calloc(1, ep->ext_nbytes, "superell external");
    rec = (union record *)ep->ext_buf;

    rec->s.s_id = ID_SOLID;
    rec->s.s_type = SUPERELL;

    /* NOTE: This also converts to dbfloat_t */
    VSCALE(&rec->s.s_values[0], tip->v, local2mm);
    VSCALE(&rec->s.s_values[3], tip->a, local2mm);
    VSCALE(&rec->s.s_values[6], tip->b, local2mm);
    VSCALE(&rec->s.s_values[9], tip->c, local2mm);

    printf("SUPERELL: %g %g\n", tip->n, tip->e);

    rec->s.s_values[12] = tip->n;
    rec->s.s_values[13] = tip->e;

    return 0;
}
int
rt_obj_export(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip, struct resource *resp)
{
    int id;
    const struct rt_functab *ft;
    int (*export_func)(struct bu_external *, const struct rt_db_internal *, double, const struct db_i *, struct resource *);

    if (!ep || !ip || !dbip || local2mm < 0.0)
	return -1;

    BU_CK_EXTERNAL(ep);
    RT_CK_DB_INTERNAL(ip);
    RT_CK_DBI(dbip);
    if (resp) RT_CK_RESOURCE(resp);

    id = ip->idb_minor_type;
    if (id < 0)
	return -2;

    ft = &OBJ[id];
    if (!ft)
	return -3;

    if (dbip->dbi_version < 5) {
	export_func = ft->ft_export4;
    } else {
	export_func = ft->ft_export5;
    }

    if (!export_func)
	return -4;

    return export_func(ep, ip, local2mm, dbip, resp);
}
示例#7
0
文件: arbn.c 项目: kanzure/brlcad
int
rt_arbn_export4(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
{
    struct rt_arbn_internal *aip;
    union record *rec;
    size_t ngrans;
    size_t i;

    /* scaling buffer must be double, not fastf_t */
    double *sbuf;
    double *sp;

    if (dbip) RT_CK_DBI(dbip);

    RT_CK_DB_INTERNAL(ip);
    if (ip->idb_type != ID_ARBN) return -1;
    aip = (struct rt_arbn_internal *)ip->idb_ptr;
    RT_ARBN_CK_MAGIC(aip);

    if (aip->neqn <= 0) return -1;

    /*
     * The network format for a double is 8 bytes and there are 4
     * doubles per plane equation.
     */
    ngrans = (aip->neqn * 8 * ELEMENTS_PER_PLANE + sizeof(union record)-1) /
	sizeof(union record);

    BU_CK_EXTERNAL(ep);
    ep->ext_nbytes = (ngrans + 1) * sizeof(union record);
    ep->ext_buf = (uint8_t *)bu_calloc(1, ep->ext_nbytes, "arbn external");
    rec = (union record *)ep->ext_buf;

    rec[0].n.n_id = DBID_ARBN;
    *(uint32_t *)rec[0].n.n_neqn = htonl(aip->neqn);
    *(uint32_t *)rec[0].n.n_grans = htonl(ngrans);

    /* Take the data from the caller, and scale it, into sbuf */
    sp = sbuf = (double *)bu_malloc(
	aip->neqn * sizeof(double) * ELEMENTS_PER_PLANE, "arbn temp");
    for (i = 0; i < aip->neqn; i++) {
	/* Normal is unscaled, should have unit length; d is scaled */
	*sp++ = aip->eqn[i][X];
	*sp++ = aip->eqn[i][Y];
	*sp++ = aip->eqn[i][Z];
	*sp++ = aip->eqn[i][W] * local2mm;
    }

    bu_cv_htond((unsigned char *)&rec[1], (unsigned char *)sbuf, aip->neqn * ELEMENTS_PER_PLANE);

    bu_free((char *)sbuf, "arbn temp");
    return 0;			/* OK */
}
示例#8
0
文件: poly.c 项目: cogitokat/brlcad
/**
 * R T _ P G _ E X P O R T
 *
 * The name will be added by the caller.
 * Generally, only libwdb will set conv2mm != 1.0
 */
int
rt_pg_export4(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
{
    struct rt_pg_internal *pgp;
    union record *rec;
    size_t i;
    size_t rno;		/* current record number */
    size_t p;		/* current polygon index */

    if (dbip) RT_CK_DBI(dbip);

    RT_CK_DB_INTERNAL(ip);
    if (ip->idb_type != ID_POLY) return -1;
    pgp = (struct rt_pg_internal *)ip->idb_ptr;
    RT_PG_CK_MAGIC(pgp);

    BU_CK_EXTERNAL(ep);
    ep->ext_nbytes = (1 + pgp->npoly) * sizeof(union record);
    ep->ext_buf = (genptr_t)bu_calloc(1, ep->ext_nbytes, "pg external");
    rec = (union record *)ep->ext_buf;

    rec[0].p.p_id = ID_P_HEAD;

    for (p=0; p < pgp->npoly; p++) {
	struct rt_pg_face_internal *pp;

	rno = p+1;
	pp = &pgp->poly[p];
	if (pp->npts < 3 || pp->npts > 5) {
	    bu_log("rt_pg_export4:  unable to support npts=%zu\n",
		   pp->npts);
	    return -1;
	}

	rec[rno].q.q_id = ID_P_DATA;
	rec[rno].q.q_count = pp->npts;
	for (i=0; i < pp->npts; i++) {
	    /* NOTE: type conversion to dbfloat_t */
	    VSCALE(rec[rno].q.q_verts[i],
		   &pp->verts[i*3], local2mm);
	    VMOVE(rec[rno].q.q_norms[i], &pp->norms[i*3]);
	}
    }

    bu_log("DEPRECATED:  The 'poly' primitive is no longer supported.  Use the 'bot' or 'nmg' polygonal mesh instead.\n");
    bu_log("\tTo convert polysolids to BOT primitives, use 'dbupgrade'.\n");

    return 0;
}
示例#9
0
文件: superell.c 项目: kanzure/brlcad
/**
 * Import an superellipsoid/sphere from the database format to the
 * internal structure.  Apply modeling transformations as wsuperell.
 */
int
rt_superell_import4(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
{
    struct rt_superell_internal *eip;
    union record *rp;
    fastf_t vec[3*4 + 2];

    if (dbip) RT_CK_DBI(dbip);

    BU_CK_EXTERNAL(ep);
    rp = (union record *)ep->ext_buf;
    /* Check record type */
    if (rp->u_id != ID_SOLID) {
        bu_log("rt_superell_import4():  defective record\n");
        return -1;
    }

    RT_CK_DB_INTERNAL(ip);
    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_SUPERELL;
    ip->idb_meth = &OBJ[ID_SUPERELL];
    BU_ALLOC(ip->idb_ptr, struct rt_superell_internal);

    eip = (struct rt_superell_internal *)ip->idb_ptr;
    eip->magic = RT_SUPERELL_INTERNAL_MAGIC;

    /* Convert from database to internal format */
    flip_fastf_float(vec, rp->s.s_values, 4, dbip->dbi_version < 0 ? 1 : 0);

    /* Apply modeling transformations */
    if (mat == NULL) mat = bn_mat_identity;
    MAT4X3PNT(eip->v, mat, &vec[0*3]);
    MAT4X3VEC(eip->a, mat, &vec[1*3]);
    MAT4X3VEC(eip->b, mat, &vec[2*3]);
    MAT4X3VEC(eip->c, mat, &vec[3*3]);

    if (dbip->dbi_version < 0) {
        eip->n = flip_dbfloat(rp->s.s_values[12]);
        eip->e = flip_dbfloat(rp->s.s_values[13]);
    } else {
        eip->n = rp->s.s_values[12];
        eip->e = rp->s.s_values[13];
    }

    return 0;		/* OK */
}
示例#10
0
文件: arbn.c 项目: kanzure/brlcad
int
rt_arbn_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
{
    struct rt_arbn_internal *aip;
    size_t i;
    int double_count;
    int byte_count;

    /* must be double for export */
    double *vec;
    double *sp;

    RT_CK_DB_INTERNAL(ip);
    if (dbip) RT_CK_DBI(dbip);

    if (ip->idb_type != ID_ARBN) return -1;
    aip = (struct rt_arbn_internal *)ip->idb_ptr;
    RT_ARBN_CK_MAGIC(aip);

    if (aip->neqn <= 0) return -1;

    double_count = aip->neqn * ELEMENTS_PER_PLANE;
    byte_count = double_count * SIZEOF_NETWORK_DOUBLE;

    BU_CK_EXTERNAL(ep);
    ep->ext_nbytes = SIZEOF_NETWORK_LONG + byte_count;
    ep->ext_buf = (uint8_t *)bu_malloc(ep->ext_nbytes, "arbn external");

    *(uint32_t *)ep->ext_buf = htonl(aip->neqn);

    /* Take the data from the caller, and scale it, into vec */
    sp = vec = (double *)bu_malloc(byte_count, "arbn temp");
    for (i = 0; i < aip->neqn; i++) {
	/* Normal is unscaled, should have unit length; d is scaled */
	*sp++ = aip->eqn[i][X];
	*sp++ = aip->eqn[i][Y];
	*sp++ = aip->eqn[i][Z];
	*sp++ = aip->eqn[i][W] * local2mm;
    }

    /* Convert from internal (host) to database (network) format */
    bu_cv_htond((unsigned char *)ep->ext_buf + SIZEOF_NETWORK_LONG, (unsigned char *)vec, double_count);

    bu_free((char *)vec, "arbn temp");
    return 0;			/* OK */
}
/**
 * Import an metaball/sphere from the database format to the internal
 * structure. Apply modeling transformations as well.
 */
int
rt_metaball_import5(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
{
    struct wdb_metaballpt *mbpt;
    struct rt_metaball_internal *mb;
    int metaball_count = 0, i;

    /* must be double for import and export */
    double *buf;

    if (dbip) RT_CK_DBI(dbip);

    BU_CK_EXTERNAL(ep);
    metaball_count = ntohl(*(uint32_t *)ep->ext_buf);
    buf = (double *)bu_malloc((metaball_count*5+1)*SIZEOF_NETWORK_DOUBLE, "rt_metaball_import5: buf");
    bu_cv_ntohd((unsigned char *)buf, (unsigned char *)ep->ext_buf+2*SIZEOF_NETWORK_LONG, metaball_count*5+1);

    RT_CK_DB_INTERNAL(ip);
    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_METABALL;
    ip->idb_meth = &OBJ[ID_METABALL];
    BU_ALLOC(ip->idb_ptr, struct rt_metaball_internal);

    mb = (struct rt_metaball_internal *)ip->idb_ptr;
    mb->magic = RT_METABALL_INTERNAL_MAGIC;
    mb->method = ntohl(*(uint32_t *)(ep->ext_buf + SIZEOF_NETWORK_LONG));
    mb->threshold = buf[0];

    BU_LIST_INIT(&mb->metaball_ctrl_head);
    if (mat == NULL) mat = bn_mat_identity;
    for (i = 1; i <= metaball_count * 5; i += 5) {
	/* Apply modeling transformations */
	BU_GET(mbpt, struct wdb_metaballpt);
	mbpt->l.magic = WDB_METABALLPT_MAGIC;
	MAT4X3PNT(mbpt->coord, mat, &buf[i]);
	mbpt->fldstr = buf[i+3] / mat[15];
	mbpt->sweat = buf[i+4];
	BU_LIST_INSERT(&mb->metaball_ctrl_head, &mbpt->l);
    }

    bu_free((void *)buf, "rt_metaball_import5: buf");
    return 0;		/* OK */
}
/**
 * storage is something like
 * long numpoints
 * long method
 * fastf_t threshold
 * fastf_t X1 (start point)
 * fastf_t Y1
 * fastf_t Z1
 * fastf_t fldstr1
 * fastf_t sweat1 (end point)
 * fastf_t X2 (start point)
 * ...
 */
int
rt_metaball_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
{
    struct rt_metaball_internal *mb;
    struct wdb_metaballpt *mbpt;
    int metaball_count = 0, i = 1;
    /* must be double for import and export */
    double *buf = NULL;

    if (dbip) RT_CK_DBI(dbip);

    RT_CK_DB_INTERNAL(ip);
    if (ip->idb_type != ID_METABALL)
	return -1;
    mb = (struct rt_metaball_internal *)ip->idb_ptr;
    RT_METABALL_CK_MAGIC(mb);
    if (mb->metaball_ctrl_head.magic == 0) return -1;

    /* Count number of points */
    for (BU_LIST_FOR(mbpt, wdb_metaballpt, &mb->metaball_ctrl_head)) metaball_count++;

    BU_CK_EXTERNAL(ep);
    ep->ext_nbytes = SIZEOF_NETWORK_DOUBLE*(1+5*metaball_count) + 2*SIZEOF_NETWORK_LONG;
    ep->ext_buf = (uint8_t *)bu_malloc(ep->ext_nbytes, "metaball external");
    if (ep->ext_buf == NULL)
	bu_bomb("Failed to allocate DB space!\n");
    *(uint32_t *)ep->ext_buf = htonl(metaball_count);
    *(uint32_t *)(ep->ext_buf + SIZEOF_NETWORK_LONG) = htonl(mb->method);

    /* pack the point data */
    buf = (double *)bu_malloc((metaball_count*5+1)*SIZEOF_NETWORK_DOUBLE, "rt_metaball_export5: buf");
    buf[0] = mb->threshold;
    for (BU_LIST_FOR(mbpt, wdb_metaballpt, &mb->metaball_ctrl_head), i+=5) {
	VSCALE(&buf[i], mbpt->coord, local2mm);
	buf[i+3] = mbpt->fldstr * local2mm;
	buf[i+4] = mbpt->sweat;
    }
    bu_cv_htond((unsigned char *)ep->ext_buf + 2*SIZEOF_NETWORK_LONG, (unsigned char *)buf, 1 + 5 * metaball_count);
    bu_free(buf, "rt_metaball_export5: buf");
    return 0;
}
示例#13
0
文件: revolve.c 项目: kanzure/brlcad
/**
 * Export an REVOLVE from internal form to external format.  Note that
 * this means converting all integers to Big-Endian format and
 * floating point data to IEEE double.
 *
 * Apply the transformation to mm units as well.
 */
int
rt_revolve_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
{
    struct rt_revolve_internal *rip;

    /* must be double for import and export */
    double vec[ELEMENTS_PER_VECT*3 + 1];

    unsigned char *ptr;

    if (dbip) RT_CK_DBI(dbip);

    RT_CK_DB_INTERNAL(ip);
    if (ip->idb_type != ID_REVOLVE) return -1;
    rip = (struct rt_revolve_internal *)ip->idb_ptr;
    RT_REVOLVE_CK_MAGIC(rip);

    BU_CK_EXTERNAL(ep);
    ep->ext_nbytes = SIZEOF_NETWORK_DOUBLE * (ELEMENTS_PER_VECT*3 + 1) + bu_vls_strlen(&rip->sketch_name) + 1;
    ep->ext_buf = (uint8_t *)bu_calloc(1, ep->ext_nbytes, "revolve external");

    ptr = (unsigned char *)ep->ext_buf;

    /* Since libwdb users may want to operate in units other than mm,
     * we offer the opportunity to scale the solid (to get it into mm)
     * on the way out.
     */
    VSCALE(&vec[0*3], rip->v3d, local2mm);
    VSCALE(&vec[1*3], rip->axis3d, local2mm);
    VSCALE(&vec[2*3], rip->r, local2mm);
    vec[9] = rip->ang;

    bu_cv_htond(ptr, (unsigned char *)vec, ELEMENTS_PER_VECT*3 + 1);
    ptr += (ELEMENTS_PER_VECT*3 + 1) * SIZEOF_NETWORK_DOUBLE;

    bu_strlcpy((char *)ptr, bu_vls_addr(&rip->sketch_name), bu_vls_strlen(&rip->sketch_name) + 1);

    return 0;
}
示例#14
0
int
rt_fwrite_internal(
    FILE *fp,
    const char *name,
    const struct rt_db_internal *ip,
    double conv2mm)
{
    struct bu_external ext;
    int ret;

    RT_CK_DB_INTERNAL(ip);
    RT_CK_FUNCTAB(ip->idb_meth);

    BU_EXTERNAL_INIT(&ext);

    ret = -1;
    if (ip->idb_meth->ft_export4) {
	ret = ip->idb_meth->ft_export4(&ext, ip, conv2mm, NULL /*dbip*/, &rt_uniresource);
    }
    if (ret < 0) {
	bu_log("rt_file_put_internal(%s): solid export failure\n",
	       name);
	bu_free_external(&ext);
	return -2;				/* FAIL */
    }
    BU_CK_EXTERNAL(&ext);

    if (db_fwrite_external(fp, name, &ext) < 0) {
	bu_log("rt_fwrite_internal(%s): db_fwrite_external() error\n",
	       name);
	bu_free_external(&ext);
	return -3;
    }
    bu_free_external(&ext);
    return 0;

}
示例#15
0
文件: superell.c 项目: kanzure/brlcad
/**
 * Import an superellipsoid/sphere from the database format to the
 * internal structure.  Apply modeling transformations as wsuperell.
 */
int
rt_superell_import5(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
{
    struct rt_superell_internal *eip;

    /* must be double for import and export */
    double vec[ELEMENTS_PER_VECT*4 + 2];

    if (dbip) RT_CK_DBI(dbip);

    RT_CK_DB_INTERNAL(ip);
    BU_CK_EXTERNAL(ep);

    BU_ASSERT_LONG(ep->ext_nbytes, ==, SIZEOF_NETWORK_DOUBLE * (ELEMENTS_PER_VECT*4 + 2));

    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_SUPERELL;
    ip->idb_meth = &OBJ[ID_SUPERELL];
    BU_ALLOC(ip->idb_ptr, struct rt_superell_internal);

    eip = (struct rt_superell_internal *)ip->idb_ptr;
    eip->magic = RT_SUPERELL_INTERNAL_MAGIC;

    /* Convert from database (network) to internal (host) format */
    bu_cv_ntohd((unsigned char *)vec, ep->ext_buf, ELEMENTS_PER_VECT*4 + 2);

    /* Apply modeling transformations */
    if (mat == NULL) mat = bn_mat_identity;
    MAT4X3PNT(eip->v, mat, &vec[0*ELEMENTS_PER_VECT]);
    MAT4X3VEC(eip->a, mat, &vec[1*ELEMENTS_PER_VECT]);
    MAT4X3VEC(eip->b, mat, &vec[2*ELEMENTS_PER_VECT]);
    MAT4X3VEC(eip->c, mat, &vec[3*ELEMENTS_PER_VECT]);
    eip->n = vec[4*ELEMENTS_PER_VECT];
    eip->e = vec[4*ELEMENTS_PER_VECT + 1];

    return 0;		/* OK */
}
示例#16
0
文件: table.c 项目: cciechad/brlcad
/**
 * R T _ I D _ S O L I D
 *
 * Given a database record, determine the proper rt_functab subscript.
 * Used by MGED as well as internally to librt.
 *
 * Returns ID_xxx if successful, or ID_NULL upon failure.
 */
int
rt_id_solid(struct bu_external *ep)
{
    register union record *rec;
    register int id;

    BU_CK_EXTERNAL( ep );
    rec = (union record *)ep->ext_buf;

    switch ( rec->u_id )  {
	case ID_SOLID:
	    id = idmap[(int)(rec->s.s_type)];
	    break;
	case ID_ARS_A:
	    id = ID_ARS;
	    break;
	case ID_P_HEAD:
	    id = ID_POLY;
	    break;
	case ID_BSOLID:
	    id = ID_BSPLINE;
	    break;
	case DBID_STRSOL:
	    /* XXX This really needs to be some kind of table */
	    if ( strcmp( rec->ss.ss_keyword, "ebm" ) == 0 )  {
		id = ID_EBM;
		break;
	    } else if ( strcmp( rec->ss.ss_keyword, "vol" ) == 0 )  {
		id = ID_VOL;
		break;
	    } else if ( strcmp( rec->ss.ss_keyword, "hf" ) == 0 )  {
		id = ID_HF;
		break;
	    } else if ( strcmp( rec->ss.ss_keyword, "dsp" ) == 0 )  {
		id = ID_DSP;
		break;
	    } else if ( strcmp( rec->ss.ss_keyword, "submodel" ) == 0 )  {
		id = ID_SUBMODEL;
		break;
	    }
	    bu_log("rt_id_solid(%s):  String solid type '%s' unknown\n",
		   rec->ss.ss_name, rec->ss.ss_keyword );
	    id = ID_NULL;		/* BAD */
	    break;
	case DBID_ARBN:
	    id = ID_ARBN;
	    break;
	case DBID_PIPE:
	    id = ID_PIPE;
	    break;
	case DBID_PARTICLE:
	    id = ID_PARTICLE;
	    break;
	case DBID_NMG:
	    id = ID_NMG;
	    break;
	case DBID_SKETCH:
	    id = ID_SKETCH;
	    break;
	case DBID_EXTR:
	    id = ID_EXTRUDE;
	    break;
	case DBID_CLINE:
	    id = ID_CLINE;
	    break;
	case DBID_BOT:
	    id = ID_BOT;
	    break;
	default:
	    bu_log("rt_id_solid:  u_id=x%x unknown\n", rec->u_id);
	    id = ID_NULL;		/* BAD */
	    break;
    }
    if ( id < ID_NULL || id > ID_MAX_SOLID )  {
	bu_log("rt_id_solid: internal error, id=%d?\n", id);
	id = ID_NULL;		/* very BAD */
    }
    return(id);
}
示例#17
0
文件: poly.c 项目: cogitokat/brlcad
/**
 * R T _ P G _ I M P O R T
 *
 * Read all the polygons in as a complex dynamic structure.
 * The caller is responsible for freeing the dynamic memory.
 * (vid rt_pg_ifree).
 */
int
rt_pg_import4(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
{
    struct rt_pg_internal *pgp;
    union record *rp;
    size_t i;
    size_t rno;		/* current record number */
    size_t p;		/* current polygon index */

    if (dbip) RT_CK_DBI(dbip);

    BU_CK_EXTERNAL(ep);
    rp = (union record *)ep->ext_buf;
    if (rp->u_id != ID_P_HEAD) {
	bu_log("rt_pg_import4: defective header record\n");
	return -1;
    }

    RT_CK_DB_INTERNAL(ip);
    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_POLY;
    ip->idb_meth = &rt_functab[ID_POLY];
    BU_ALLOC(ip->idb_ptr, struct rt_pg_internal);

    pgp = (struct rt_pg_internal *)ip->idb_ptr;
    pgp->magic = RT_PG_INTERNAL_MAGIC;

    pgp->npoly = (ep->ext_nbytes - sizeof(union record)) /
	sizeof(union record);
    if (pgp->npoly <= 0) {
	bu_log("rt_pg_import4: polysolid with no polygons!\n");
	return -1;
    }
    if (pgp->npoly)
	pgp->poly = (struct rt_pg_face_internal *)bu_malloc(
	    pgp->npoly * sizeof(struct rt_pg_face_internal), "rt_pg_face_internal");
    pgp->max_npts = 0;

    if (mat == NULL) mat = bn_mat_identity;
    for (p=0; p < pgp->npoly; p++) {
	struct rt_pg_face_internal *pp;

	pp = &pgp->poly[p];
	rno = p+1;
	if (rp[rno].q.q_id != ID_P_DATA) {
	    bu_log("rt_pg_import4: defective data record\n");
	    return -1;
	}
	pp->npts = rp[rno].q.q_count;
	pp->verts = (fastf_t *)bu_malloc(pp->npts * 3 * sizeof(fastf_t), "pg verts[]");
	pp->norms = (fastf_t *)bu_malloc(pp->npts * 3 * sizeof(fastf_t), "pg norms[]");
	for (i=0; i < pp->npts; i++) {
	    point_t pnt;
	    vect_t vec;

	    if (dbip->dbi_version < 0) {
		flip_fastf_float(pnt, rp[rno].q.q_verts[i], 1, 1);
		flip_fastf_float(vec, rp[rno].q.q_norms[i], 1, 1);
	    } else {
		VMOVE(pnt, rp[rno].q.q_verts[i]);
		VMOVE(vec, rp[rno].q.q_norms[i]);
	    }

	    /* Note:  side effect of importing dbfloat_t */
	    MAT4X3PNT(&pp->verts[i*3], mat, pnt);
	    MAT4X3VEC(&pp->norms[i*3], mat, vec);
	}
	if (pp->npts > pgp->max_npts) pgp->max_npts = pp->npts;
    }
    if (pgp->max_npts < 3) {
	bu_log("rt_pg_import4: polysolid with all polygons of less than %zu vertices!\n", pgp->max_npts);
	/* XXX free storage */
	return -1;
    }
    return 0;
}
示例#18
0
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 {
示例#19
0
文件: revolve.c 项目: kanzure/brlcad
/**
 * Import an REVOLVE from the database format to the internal format.
 * Note that the data read will be in network order.  This means
 * Big-Endian integers and IEEE doubles for floating point.
 *
 * Apply modeling transformations as well.
 */
int
rt_revolve_import5(struct rt_db_internal *ip, const struct bu_external *ep, const mat_t mat, const struct db_i *dbip, struct resource *resp)
{
    struct rt_revolve_internal *rip;

    /* must be double for import and export */
    double vv[ELEMENTS_PER_VECT*3 + 1];

    char *sketch_name;
    unsigned char *ptr;
    struct directory *dp;
    struct rt_db_internal tmp_ip;

    if (dbip) RT_CK_DBI(dbip);

    RT_CK_DB_INTERNAL(ip);
    BU_CK_EXTERNAL(ep);

    /* set up the internal structure */
    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_REVOLVE;
    ip->idb_meth = &OBJ[ID_REVOLVE];
    BU_ALLOC(ip->idb_ptr, struct rt_revolve_internal);

    rip = (struct rt_revolve_internal *)ip->idb_ptr;
    rip->magic = RT_REVOLVE_INTERNAL_MAGIC;

    /* Convert the data in ep->ext_buf into internal format.  Note the
     * conversion from network data (Big Endian ints, IEEE double
     * floating point) to host local data representations.
     */

    ptr = (unsigned char *)ep->ext_buf;
    sketch_name = (char *)ptr + (ELEMENTS_PER_VECT*3 + 1)*SIZEOF_NETWORK_DOUBLE;
    if (!dbip)
	rip->skt = (struct rt_sketch_internal *)NULL;
    else if ((dp=db_lookup(dbip, sketch_name, LOOKUP_NOISY)) == RT_DIR_NULL) {
	bu_log("ERROR: Cannot find sketch (%s) for extrusion\n",
	       sketch_name);
	rip->skt = (struct rt_sketch_internal *)NULL;
    } else {
	if (rt_db_get_internal(&tmp_ip, dp, dbip, bn_mat_identity, resp) != ID_SKETCH) {
	    bu_log("ERROR: Cannot import sketch (%s) for extrusion\n",
		   sketch_name);
	    bu_free(ip->idb_ptr, "extrusion");
	    return -1;
	} else
	    rip->skt = (struct rt_sketch_internal *)tmp_ip.idb_ptr;
    }

    bu_cv_ntohd((unsigned char *)&vv, (unsigned char *)ep->ext_buf, ELEMENTS_PER_VECT*3 + 1);

    /* Apply the modeling transformation */
    if (mat == NULL) mat = bn_mat_identity;
    MAT4X3PNT(rip->v3d, mat, &vv[0*3]);
    MAT4X3PNT(rip->axis3d, mat, &vv[1*3]);
    MAT4X3PNT(rip->r, mat, &vv[2*3]);
    rip->ang = vv[9];

    /* convert name of data location */
    bu_vls_init(&rip->sketch_name);
    bu_vls_strcpy(&rip->sketch_name, (char *)ep->ext_buf + (ELEMENTS_PER_VECT * 3 + 1) * SIZEOF_NETWORK_DOUBLE);

    return 0;			/* OK */
}
示例#20
0
文件: arbn.c 项目: kanzure/brlcad
/**
 * Convert from "network" doubles to machine specific.
 * Transform
 */
int
rt_arbn_import4(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
{
    union record *rp;
    struct rt_arbn_internal *aip;
    size_t i;

    /* must be double for import and export */
    double *scan;

    if (dbip) RT_CK_DBI(dbip);

    BU_CK_EXTERNAL(ep);
    rp = (union record *)ep->ext_buf;
    if (rp->u_id != DBID_ARBN) {
	bu_log("rt_arbn_import4: defective record, id=x%x\n", rp->u_id);
	return -1;
    }

    RT_CK_DB_INTERNAL(ip);
    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_ARBN;
    ip->idb_meth = &OBJ[ID_ARBN];
    BU_ALLOC(ip->idb_ptr, struct rt_arbn_internal);

    aip = (struct rt_arbn_internal *)ip->idb_ptr;
    aip->magic = RT_ARBN_INTERNAL_MAGIC;
    aip->neqn = ntohl(*(uint32_t *)rp->n.n_neqn);
    if (aip->neqn <= 0) return -1;

    aip->eqn = (plane_t *)bu_malloc(aip->neqn*sizeof(plane_t), "arbn plane eqn[]");
    scan = (double *)bu_malloc(aip->neqn*sizeof(double)*ELEMENTS_PER_PLANE, "scan array");

    bu_cv_ntohd((unsigned char *)scan, (unsigned char *)(&rp[1]), aip->neqn*ELEMENTS_PER_PLANE);
    for (i = 0; i < aip->neqn; i++) {
	aip->eqn[i][X] = scan[(i*ELEMENTS_PER_PLANE)+0]; /* convert double to fastf_t */
	aip->eqn[i][Y] = scan[(i*ELEMENTS_PER_PLANE)+1]; /* convert double to fastf_t */
	aip->eqn[i][Z] = scan[(i*ELEMENTS_PER_PLANE)+2]; /* convert double to fastf_t */
	aip->eqn[i][W] = scan[(i*ELEMENTS_PER_PLANE)+3]; /* convert double to fastf_t */
    }
    bu_free(scan, "scan array");

    /* Transform by the matrix */
    if (mat == NULL) mat = bn_mat_identity;
    for (i = 0; i < aip->neqn; i++) {
	point_t orig_pt;
	point_t pt;
	vect_t norm;
	fastf_t factor;

	/* unitize the plane equation first */
	factor = 1.0 / MAGNITUDE(aip->eqn[i]);
	VSCALE(aip->eqn[i], aip->eqn[i], factor);
	aip->eqn[i][W] = aip->eqn[i][W] * factor;


	/* Pick a point on the original halfspace */
	VSCALE(orig_pt, aip->eqn[i], aip->eqn[i][W]);

	/* Transform the point, and the normal */
	MAT4X3VEC(norm, mat, aip->eqn[i]);
	MAT4X3PNT(pt, mat, orig_pt);

	/* Measure new distance from origin to new point */
	VUNITIZE(norm);
	VMOVE(aip->eqn[i], norm);
	aip->eqn[i][W] = VDOT(pt, norm);
    }

    return 0;
}
示例#21
0
文件: arbn.c 项目: kanzure/brlcad
/**
 * Convert from "network" doubles to machine specific.
 * Transform
 */
int
rt_arbn_import5(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
{
    struct rt_arbn_internal *aip;
    size_t i;
    unsigned long neqn;
    int double_count;
    size_t byte_count;

    /* must be double for import and export */
    double *eqn;

    RT_CK_DB_INTERNAL(ip);
    BU_CK_EXTERNAL(ep);
    if (dbip) RT_CK_DBI(dbip);

    neqn = ntohl(*(uint32_t *)ep->ext_buf);
    double_count = neqn * ELEMENTS_PER_PLANE;
    byte_count = double_count * SIZEOF_NETWORK_DOUBLE;

    BU_ASSERT_LONG(ep->ext_nbytes, ==, 4+ byte_count);

    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_ARBN;
    ip->idb_meth = &OBJ[ID_ARBN];
    BU_ALLOC(ip->idb_ptr, struct rt_arbn_internal);

    aip = (struct rt_arbn_internal *)ip->idb_ptr;
    aip->magic = RT_ARBN_INTERNAL_MAGIC;
    aip->neqn = neqn;
    if (aip->neqn <= 0) return -1;

    eqn = (double *)bu_malloc(byte_count, "arbn plane eqn[] temp buf");
    bu_cv_ntohd((unsigned char *)eqn, (unsigned char *)ep->ext_buf + ELEMENTS_PER_PLANE, double_count);
    aip->eqn = (plane_t *)bu_malloc(double_count * sizeof(fastf_t), "arbn plane eqn[]");
    for (i = 0; i < aip->neqn; i++) {
	HMOVE(aip->eqn[i], &eqn[i*ELEMENTS_PER_PLANE]);
    }
    bu_free(eqn, "arbn plane eqn[] temp buf");

    /* Transform by the matrix, if we have one that is not the identity */
    if (mat && !bn_mat_is_identity(mat)) {
	for (i = 0; i < aip->neqn; i++) {
	    point_t orig_pt;
	    point_t pt;
	    vect_t norm;
	    fastf_t factor;

	    /* unitize the plane equation first */
	    factor = 1.0 / MAGNITUDE(aip->eqn[i]);
	    VSCALE(aip->eqn[i], aip->eqn[i], factor);
	    aip->eqn[i][W] = aip->eqn[i][W] * factor;

	    /* Pick a point on the original halfspace */
	    VSCALE(orig_pt, aip->eqn[i], aip->eqn[i][W]);

	    /* Transform the point, and the normal */
	    MAT4X3VEC(norm, mat, aip->eqn[i]);
	    MAT4X3PNT(pt, mat, orig_pt);

	    /* Measure new distance from origin to new point */
	    VUNITIZE(norm);
	    VMOVE(aip->eqn[i], norm);
	    aip->eqn[i][W] = VDOT(pt, norm);
	}
    }

    return 0;
}
示例#22
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;
}
示例#23
0
文件: db5_bin.c 项目: cciechad/brlcad
/**
 * R T _ B I N U N I F _ I M P O R T 5
 *
 * Import a uniform-array binary object from the database format to
 * the internal structure.
 */
int
rt_binunif_import5( struct rt_db_internal	*ip,
		    const struct bu_external	*ep,
		    const mat_t			mat,
		    const struct db_i		*dbip,
		    struct resource		*resp,
		    const int			minor_type)
{
    struct rt_binunif_internal	*bip;
    int				i;
    unsigned char			*srcp;
    unsigned long			*ldestp;
    int				in_cookie, out_cookie;
    int				gotten;

    BU_CK_EXTERNAL( ep );

    /*
     * There's no particular size to expect
     *
     * BU_ASSERT_LONG( ep->ext_nbytes, ==, SIZEOF_NETWORK_DOUBLE * 3*4 );
     */

    RT_CK_DB_INTERNAL( ip );
    ip->idb_major_type = DB5_MAJORTYPE_BINARY_UNIF;
    ip->idb_minor_type = minor_type;
    ip->idb_meth = &rt_functab[ID_BINUNIF];
    ip->idb_ptr = bu_malloc( sizeof(struct rt_binunif_internal),
			     "rt_binunif_internal");

    bip = (struct rt_binunif_internal *)ip->idb_ptr;
    bip->magic = RT_BINUNIF_INTERNAL_MAGIC;
    bip->type = minor_type;

    /*
     * Convert from database (network) to internal (host) format
     */
    switch (bip->type) {
	case DB5_MINORTYPE_BINU_FLOAT:
	    bip->count = ep->ext_nbytes/SIZEOF_NETWORK_FLOAT;
	    bip->u.uint8 = (unsigned char *) bu_malloc( bip->count * sizeof(float),
							"rt_binunif_internal" );
	    ntohf( (unsigned char *) bip->u.uint8,
		   ep->ext_buf, bip->count );
	    break;
	case DB5_MINORTYPE_BINU_DOUBLE:
	    bip->count = ep->ext_nbytes/SIZEOF_NETWORK_DOUBLE;
	    bip->u.uint8 = (unsigned char *) bu_malloc( bip->count * sizeof(double),
							"rt_binunif_internal" );
	    ntohd( (unsigned char *) bip->u.uint8,
		   ep->ext_buf, bip->count );
	    break;
	case DB5_MINORTYPE_BINU_8BITINT:
	case DB5_MINORTYPE_BINU_8BITINT_U:
	    bip->count = ep->ext_nbytes;
	    bip->u.uint8 = (unsigned char *) bu_malloc( ep->ext_nbytes,
							"rt_binunif_internal" );
	    memcpy((char *) bip->u.uint8, (char *) ep->ext_buf, ep->ext_nbytes);
	    break;
	case DB5_MINORTYPE_BINU_16BITINT:
	case DB5_MINORTYPE_BINU_16BITINT_U:
	    bip->count = ep->ext_nbytes/2;
	    bip->u.uint8 = (unsigned char *) bu_malloc( ep->ext_nbytes,
							"rt_binunif_internal" );
#if 0
	    srcp = (unsigned char *) ep->ext_buf;
	    sdestp = (unsigned short *) bip->u.uint8;
	    for (i = 0; i < bip->count; ++i, ++sdestp, srcp += 2) {
		*sdestp = bu_gshort( srcp );
		bu_log("Just got %d", *sdestp);
	    }
#endif
	    in_cookie = bu_cv_cookie("nus");
	    out_cookie = bu_cv_cookie("hus");
	    if (bu_cv_optimize(in_cookie) != bu_cv_optimize(out_cookie)) {
		gotten =
		    bu_cv_w_cookie((genptr_t)bip->u.uint8, out_cookie,
				   ep->ext_nbytes,
				   ep->ext_buf, in_cookie, bip->count);
		if (gotten != bip->count) {
		    bu_log("%s:%d: Tried to convert %d, did %d",
			   __FILE__, __LINE__, bip->count, gotten);
		    bu_bomb("\n");
		}
	    } else
		memcpy((char *) bip->u.uint8,
		       (char *) ep->ext_buf,
		       ep->ext_nbytes );
	    break;
	case DB5_MINORTYPE_BINU_32BITINT:
	case DB5_MINORTYPE_BINU_32BITINT_U:
	    bip->count = ep->ext_nbytes/4;
	    bip->u.uint8 = (unsigned char *) bu_malloc( ep->ext_nbytes,
							"rt_binunif_internal" );
	    srcp = (unsigned char *) ep->ext_buf;
	    ldestp = (unsigned long *) bip->u.uint8;
	    for (i = 0; i < bip->count; ++i, ++ldestp, srcp += 4) {
		*ldestp = bu_glong( srcp );
	    }
	    break;
	case DB5_MINORTYPE_BINU_64BITINT:
	case DB5_MINORTYPE_BINU_64BITINT_U:
	    bu_log("rt_binunif_import5() Can't handle 64-bit integers yet\n");
	    return -1;
    }

    return 0;		/* OK */
}