int
rt_obj_describe(struct bu_vls *logstr, const struct rt_db_internal *ip, int verbose, double mm2local, struct resource *resp, struct db_i *dbip)
{
    int id;
    const struct rt_functab *ft;

    if (!logstr || !ip)
	return -1;

    BU_CK_VLS(logstr);
    RT_CK_DB_INTERNAL(ip);
    if (resp) RT_CK_RESOURCE(resp);
    if (dbip) RT_CK_DBI(dbip);

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

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

    return ft->ft_describe(logstr, ip, verbose, mm2local, resp, dbip);
}
HIDDEN void
edcodes_traverse_node(struct db_i *dbip, struct rt_comb_internal *UNUSED(comb), union tree *comb_leaf, void *user_ptr1, void *user_ptr2, void *user_ptr3, void *UNUSED(user_ptr4))
{
    int ret;
    int *pathpos;
    struct directory *nextdp;
    struct ged *gedp;

    RT_CK_DBI(dbip);
    RT_CK_TREE(comb_leaf);

    if ((nextdp=db_lookup(dbip, comb_leaf->tr_l.tl_name, LOOKUP_NOISY)) == RT_DIR_NULL)
	return;

    pathpos = (int *)user_ptr1;
    gedp = (struct ged *)user_ptr2;

    /* recurse on combinations */
    if (nextdp->d_flags & RT_DIR_COMB) {
	int *status = (int *)user_ptr3;
	ret = edcodes_collect_regnames(gedp, nextdp, (*pathpos)+1);
	if (status && ret == EDCODES_HALT)
	    *status = EDCODES_HALT;
    }
}
Beispiel #3
0
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;
}
Beispiel #4
0
int
db_ls(const struct db_i *dbip, int flags, struct directory ***dpv)
{
    int i;
    int objcount = 0;
    struct directory *dp;

    RT_CK_DBI(dbip);

    for (i = 0; i < RT_DBNHASH; i++) {
	for (dp = dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw) {
	    objcount += dp_eval_flags(dp, flags);
	}
    }
    if (objcount > 0) {
	(*dpv) = (struct directory **)bu_malloc(sizeof(struct directory *) * (objcount + 1), "directory pointer array");
	objcount = 0;
	for (i = 0; i < RT_DBNHASH; i++) {
	    for (dp = dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw) {
		if (dp_eval_flags(dp,flags)) {
		    (*dpv)[objcount] = dp;
		    objcount++;
		}
	    }
	}
	(*dpv)[objcount] = NULL;
    }
    return objcount;
}
Beispiel #5
0
int
db_argv_to_path(struct db_full_path *pp, struct db_i *dbip, int argc, const char *const *argv)
{
    struct directory *dp;
    int ret = 0;
    int i;

    RT_CK_DBI(dbip);

    /* Make a path structure just big enough */
    pp->magic = DB_FULL_PATH_MAGIC;
    pp->fp_maxlen = pp->fp_len = argc;
    pp->fp_names = (struct directory **)bu_malloc(
	pp->fp_maxlen * sizeof(struct directory *),
	"db_argv_to_path path array");
    pp->fp_bool = (int *)bu_calloc(pp->fp_maxlen, sizeof(int),
	"db_argv_to_path bool array");
    pp->fp_mat = (matp_t *)bu_calloc(pp->fp_maxlen, sizeof(matp_t),
	"db_string_to_path mat array");

    for (i = 0; i<argc; i++) {
	if ((dp = db_lookup(dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL) {
	    bu_log("db_argv_to_path() failed on element %d='%s'\n",
		   i, argv[i]);
	    ret = -1; /* FAILED */
	    /* Fall through, storing null dp in this location */
	}
	pp->fp_names[i] = dp;
    }
    return ret;
}
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);
}
/**
 * Builds a directory of the object names.
 *
 * Allocate and initialize information for this instance of an RT
 * model database.
 *
 * Returns -
 * (struct rt_i *) Success
 * RTI_NULL Fatal Error
 */
struct rt_i *
rt_dirbuild(const char *filename, char *buf, int len)
{
    register struct rt_i *rtip;
    register struct db_i *dbip;		/* Database instance ptr */

    if (rt_uniresource.re_magic == 0)
	rt_init_resource(&rt_uniresource, 0, NULL);

    if ((dbip = db_open(filename, DB_OPEN_READONLY)) == DBI_NULL)
	return RTI_NULL;		/* FAIL */
    RT_CK_DBI(dbip);

    if (db_dirbuild(dbip) < 0) {
	db_close(dbip);
	return RTI_NULL;		/* FAIL */
    }

    rtip = rt_new_rti(dbip);		/* clones dbip */
    db_close(dbip);				/* releases original dbip */

    if (buf != (char *)NULL)
	bu_strlcpy(buf, dbip->dbi_title, len);

    return rtip;				/* OK */
}
struct directory *
db_lookup(const struct db_i *dbip, const char *name, int noisy)
{
    struct directory *dp;
    char n0;
    char n1;

    if (!name || name[0] == '\0') {
	if (noisy || RT_G_DEBUG&DEBUG_DB)
	    bu_log("db_lookup received NULL or empty name\n");
	return RT_DIR_NULL;
    }

    n0 = name[0];
    n1 = name[1];

    RT_CK_DBI(dbip);

    dp = dbip->dbi_Head[db_dirhash(name)];
    for (; dp != RT_DIR_NULL; dp=dp->d_forw) {
	char *this_obj;

	/* first two checks are for speed */
	if ((n0 == *(this_obj=dp->d_namep)) && (n1 == this_obj[1]) && (BU_STR_EQUAL(name, this_obj))) {
	    if (RT_G_DEBUG&DEBUG_DB)
		bu_log("db_lookup(%s) %p\n", name, (void *)dp);
	    return dp;
	}
    }

    if (noisy || RT_G_DEBUG&DEBUG_DB)
	bu_log("db_lookup(%s) failed: %s does not exist\n", name, name);

    return RT_DIR_NULL;
}
Beispiel #9
0
/**
 * 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;
}
Beispiel #10
0
/**
 * 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 */
}
Beispiel #11
0
/**
 * Using a single call to db_put(), write multiple zeroed records out,
 * all with u_id field set to ID_FREE.
 * This will zap all records from "start" to the end of this entry.
 *
 * Returns:
 * 0 on success (from db_put())
 * non-zero on failure
 */
int
db_zapper(struct db_i *dbip, struct directory *dp, size_t start)
{
    union record *rp;
    size_t i;
    size_t todo;
    int ret;

    RT_CK_DBI(dbip);
    RT_CK_DIR(dp);
    if (RT_G_DEBUG&DEBUG_DB) bu_log("db_zapper(%s) %p, %p, start=%zu\n",
				    dp->d_namep, (void *)dbip, (void *)dp, start);

    if (dp->d_flags & RT_DIR_INMEM) bu_bomb("db_zapper() called on RT_DIR_INMEM object\n");

    if (dbip->dbi_read_only)
	return -1;

    BU_ASSERT_LONG(dbip->dbi_version, ==, 4);

    if (dp->d_len < start)
	return -1;

    if ((todo = dp->d_len - start) == 0)
	return 0;		/* OK -- trivial */

    rp = (union record *)bu_malloc(todo * sizeof(union record), "db_zapper buf");
    memset((char *)rp, 0, todo * sizeof(union record));

    for (i=0; i < todo; i++)
	rp[i].u_id = ID_FREE;
    ret = db_put(dbip, dp, rp, (off_t)start, todo);
    bu_free((char *)rp, "db_zapper buf");
    return ret;
}
Beispiel #12
0
/**
 * Delete the indicated database record(s).
 * Arrange to write "free storage" database markers in its place,
 * positively erasing what had been there before.
 *
 * Returns:
 * 0 on success
 * non-zero on failure
 */
int
db_delete(struct db_i *dbip, struct directory *dp)
{
    int i = 0;

    RT_CK_DBI(dbip);
    RT_CK_DIR(dp);
    if (RT_G_DEBUG&DEBUG_DB) bu_log("db_delete(%s) %p, %p\n",
				    dp->d_namep, (void *)dbip, (void *)dp);

    if (dp->d_flags & RT_DIR_INMEM) {
	bu_free(dp->d_un.ptr, "db_delete d_un.ptr");
	dp->d_un.ptr = NULL;
	dp->d_len = 0;
	return 0;
    }

    if (db_version(dbip) == 4) {
	i = db_zapper(dbip, dp, 0);
	rt_memfree(&(dbip->dbi_freep), (unsigned)dp->d_len, dp->d_addr/(sizeof(union record)));
    } else if (db_version(dbip) == 5) {
	i = db5_write_free(dbip, dp, dp->d_len);
	rt_memfree(&(dbip->dbi_freep), dp->d_len, dp->d_addr);
    } else {
	bu_bomb("db_delete() unsupported database version\n");
    }

    dp->d_len = 0;
    dp->d_addr = RT_DIR_PHONY_ADDR;
    return i;
}
Beispiel #13
0
int
rt_db_flip_endian(struct db_i *dbip)
{
    struct counter cnt = {0, 0};
    char *v4flip;

    RT_CK_DBI(dbip);

    /* does not apply to v5 geometry database */
    if (db_version(dbip) > 4)
	return 0;

    /* provide the user some means to override this automatic behavior */
    v4flip = getenv("LIBRT_V4FLIP");
    if (v4flip)
	return bu_str_true(v4flip);

    /* iterate over all database objects looking for signs of
     * corruption keeping a tally of whether flipping the record fixed
     * the problem.
     */
    db_scan(dbip, db_corrupt_handler, 0, &cnt);

    /* it has to help more than it hurts */
    if (cnt.found > 0 && (double)cnt.fixed > ((double)cnt.found / 2.0)) {
	if (cnt.fixed != cnt.found)
	    bu_log("%zu of %zu objects were NOT fixed by flipping endian interpretation.  Manual inspection and repair required.\n", cnt.found - cnt.fixed, cnt.found);
	return 1;
    }

    return 0;
}
Beispiel #14
0
/**
 * 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;
}
Beispiel #15
0
void
db_sync(struct db_i *dbip)
{
    RT_CK_DBI(dbip);

    bu_semaphore_acquire(BU_SEM_SYSCALL);

    /* make sure we have something to do */
    if (!dbip->dbi_fp) {
	bu_semaphore_release(BU_SEM_SYSCALL);
	return;
    }

    /* flush the file */
    (void)fflush(dbip->dbi_fp);

#if defined(HAVE_FSYNC) && !defined(STRICT_FLAGS)
    /* make sure it's written out */
    (void)fsync(fileno(dbip->dbi_fp));
#else
#  if defined(HAVE_SYNC) && !defined(STRICT_FLAGS)
    /* try the whole filesystem if sans fsync() */
    sync();
#  endif
#endif

    bu_semaphore_release(BU_SEM_SYSCALL);
}
HIDDEN void
find_ref(struct db_i *dbip,
	 struct rt_comb_internal *comb,
	 union tree *comb_leaf,
	 void *object,
	 void *comb_name_ptr,
	 void *user_ptr3,
	 void *UNUSED(user_ptr4))
{
    char *obj_name;
    char *comb_name;
    struct ged *gedp = (struct ged *)user_ptr3;

    if (dbip) RT_CK_DBI(dbip);
    if (comb) RT_CK_COMB(comb);
    RT_CK_TREE(comb_leaf);

    obj_name = (char *)object;
    if (!BU_STR_EQUAL(comb_leaf->tr_l.tl_name, obj_name))
	return;

    comb_name = (char *)comb_name_ptr;

    bu_vls_printf(gedp->ged_result_str, "%s ", comb_name);
}
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);
}
static void
dup_dir_check5(struct db_i *input_dbip,
	       const struct db5_raw_internal *rip,
	       off_t addr,
	       void *ptr)
{
    char *name;
    struct directory *dupdp;
    struct bu_vls local = BU_VLS_INIT_ZERO;
    struct dir_check_stuff *dcsp = (struct dir_check_stuff *)ptr;

    if (dcsp->main_dbip == DBI_NULL)
	return;

    RT_CK_DBI(input_dbip);
    RT_CK_RIP(rip);

    if (rip->h_dli == DB5HDR_HFLAGS_DLI_HEADER_OBJECT) return;
    if (rip->h_dli == DB5HDR_HFLAGS_DLI_FREE_STORAGE) return;

    name = (char *)rip->name.ext_buf;

    if (name == (char *)NULL) return;
    if (addr == 0) return;

    /* do not compare _GLOBAL */
    if (rip->major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY &&
	rip->minor_type == 0)
	return;

    /* Add the prefix, if any */
    if (db_version(dcsp->main_dbip) < 5) {
	if (dcsp->wdbp->wdb_ncharadd > 0) {
	    bu_vls_strncpy(&local, bu_vls_addr(&dcsp->wdbp->wdb_prestr), dcsp->wdbp->wdb_ncharadd);
	    bu_vls_strcat(&local, name);
	} else {
	    bu_vls_strncpy(&local, name, _GED_V4_MAXNAME);
	}
	bu_vls_trunc(&local, _GED_V4_MAXNAME);
    } else {
	if (dcsp->wdbp->wdb_ncharadd > 0) {
	    (void)bu_vls_vlscat(&local, &dcsp->wdbp->wdb_prestr);
	    (void)bu_vls_strcat(&local, name);
	} else {
	    (void)bu_vls_strcat(&local, name);
	}
    }

    /* Look up this new name in the existing (main) database */
    if ((dupdp = db_lookup(dcsp->main_dbip, bu_vls_addr(&local), LOOKUP_QUIET)) != RT_DIR_NULL) {
	/* Duplicate found, add it to the list */
	dcsp->wdbp->wdb_num_dups++;
	*dcsp->dup_dirp++ = dupdp;
    }

    bu_vls_free(&local);

    return;
}
Beispiel #19
0
/**
 * Creates one metaball object that includes all points from an
 * existing list (in 'av') of named metaballs.  This routine creates
 * an rt_metaball_internal object directly via LIBRT given it requires
 * reading existing metaballs from the database.
 */
static void
mix_balls(struct db_i *dbip, const char *name, int ac, const char *av[])
{
    int i;
    struct directory *dp;
    struct rt_metaball_internal *newmp;

    RT_CK_DBI(dbip);

    /* allocate a struct rt_metaball_internal object that we'll
     * manually fill in with points from the other metaballs being
     * joined together.
     */
    BU_ALLOC(newmp, struct rt_metaball_internal);
    newmp->magic = RT_METABALL_INTERNAL_MAGIC;
    newmp->threshold = 1.0;
    newmp->method = 1;
    BU_LIST_INIT(&newmp->metaball_ctrl_head);

    bu_log("Combining together the following metaballs:\n");

    for (i = 0; i < ac; i++) {
	struct rt_db_internal dir;
	struct rt_metaball_internal *mp;
	struct wdb_metaballpt *mpt;

	/* get a handle on the existing database object */
	bu_log("\t%s\n", av[i]);
	dp = db_lookup(dbip, av[i], 1);
	if (!dp) {
	    bu_log("Unable to find %s\n", av[i]);
	    continue;
	}

	/* load the existing database object */
	if (rt_db_get_internal(&dir, dp, dbip, NULL, &rt_uniresource) < 0) {
	    bu_log("Unable to load %s\n", av[i]);
	    continue;
	}

	/* access the metaball-specific internal structure */
	mp = (struct rt_metaball_internal *)dir.idb_ptr;
	RT_METABALL_CK_MAGIC(mp);

	/* iterate over each point in that database object and add it
	 * to our new metaball.
	 */
	for (BU_LIST_FOR(mpt, wdb_metaballpt, &mp->metaball_ctrl_head)) {
	    bu_log("Adding point (%lf %lf %lf)\n", V3ARGS(mpt->coord));
	    rt_metaball_add_point(newmp, (const point_t *)&mpt->coord, mpt->fldstr, mpt->sweat);
	}
    }

    bu_log("Joining balls together and creating [%s] object\n", name);

    /* write out new "mega metaball" out to disk */
    dbip->dbi_wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK);
    wdb_export(dbip->dbi_wdbp, name, newmp, ID_METABALL, 1.0);
}
Beispiel #20
0
/**
 * Find a block of database storage of "count" granules.
 *
 * Returns:
 * 0 OK
 * non-0 failure
 */
int
db_alloc(register struct db_i *dbip, register struct directory *dp, size_t count)
{
    size_t len;
    union record rec;

    RT_CK_DBI(dbip);
    RT_CK_DIR(dp);
    if (RT_G_DEBUG&DEBUG_DB) bu_log("db_alloc(%s) %p, %p, count=%zu\n",
				    dp->d_namep, (void *)dbip, (void *)dp, count);
    if (count <= 0) {
	bu_log("db_alloc(0)\n");
	return -1;
    }

    if (dp->d_flags & RT_DIR_INMEM) {
	if (dp->d_un.ptr) {
	    dp->d_un.ptr = bu_realloc(dp->d_un.ptr,
				      count * sizeof(union record), "db_alloc() d_un.ptr");
	} else {
	    dp->d_un.ptr = bu_malloc(count * sizeof(union record), "db_alloc() d_un.ptr");
	}
	dp->d_len = count;
	return 0;
    }

    if (dbip->dbi_read_only) {
	bu_log("db_alloc on READ-ONLY file\n");
	return -1;
    }
    while (1) {
	len = rt_memalloc(&(dbip->dbi_freep), (unsigned)count);
	if (len == 0L) {
	    /* No contiguous free block, append to file */
	    if ((dp->d_addr = dbip->dbi_eof) == RT_DIR_PHONY_ADDR) {
		bu_log("db_alloc: bad EOF\n");
		return -1;
	    }
	    dp->d_len = count;
	    dbip->dbi_eof += (off_t)(count * sizeof(union record));
	    dbip->dbi_nrec += count;
	    break;
	}
	dp->d_addr = (off_t)(len * sizeof(union record));
	dp->d_len = count;
	if (db_get(dbip, dp, &rec, 0, 1) < 0)
	    return -1;
	if (rec.u_id != ID_FREE) {
	    bu_log("db_alloc():  len %ld non-FREE (id %d), skipping\n",
		   len, rec.u_id);
	    continue;
	}
    }

    /* Clear out ALL the granules, for safety */
    return db_zapper(dbip, dp, 0);
}
Beispiel #21
0
struct db_i *
db_clone_dbi(struct db_i *dbip, long int *client)
{
    RT_CK_DBI(dbip);

    dbip->dbi_uses++;
    if (client) {
	bu_ptbl_ins_unique(&dbip->dbi_clients, client);
    }
    return dbip;
}
Beispiel #22
0
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 */
}
Beispiel #23
0
/**
 * Delete a specific record from database entry
 * No longer supported.
 */
int
db_delrec(struct db_i *dbip, register struct directory *dp, int recnum)
{

    RT_CK_DBI(dbip);
    RT_CK_DIR(dp);
    if (RT_G_DEBUG&DEBUG_DB) bu_log("db_delrec(%s) %p, %p, recnum=%d\n",
				    dp->d_namep, (void *)dbip, (void *)dp, recnum);

    bu_log("ERROR db_delrec() is no longer supported.  Use combination import/export routines.\n");
    return -1;
}
Beispiel #24
0
int
rt_pg_export5(struct bu_external *ep, const struct rt_db_internal *ip, double UNUSED(local2mm), const struct db_i *dbip)
{
    if (!ep)
	return -1;
    if (ip) RT_CK_DB_INTERNAL(ip);
    if (dbip) RT_CK_DBI(dbip);

    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");
    /* The rt_pg_to_bot() routine can also be used. */
    return -1;
}
Beispiel #25
0
int
rt_pg_import5(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
{
    if (ip) RT_CK_DB_INTERNAL(ip);
    if (!ep || !mat)
	return -1;
    if (dbip) RT_CK_DBI(dbip);

    bu_log("As of release 6.0 the polysolid is superceded by the BOT primitive.\n");
    bu_log("\tTo convert polysolids to BOT primitives, use 'dbupgrade'.\n");
    /* The rt_pg_to_bot() routine can also be used. */
    return -1;
}
int
db_is_directory_non_empty(const struct db_i *dbip)
{
    int i;

    RT_CK_DBI(dbip);

    for (i = 0; i < RT_DBNHASH; i++) {
	if (dbip->dbi_Head[i] != RT_DIR_NULL)
	    return 1;
    }
    return 0;
}
void
db_ck_directory(const struct db_i *dbip)
{
    struct directory *dp;
    int i;

    RT_CK_DBI(dbip);

    for (i = 0; i < RT_DBNHASH; i++) {
	for (dp = dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw)
	    RT_CK_DIR(dp);
    }
}
Beispiel #28
0
void
db_close_client(struct db_i *dbip, long int *client)
{
    if (!dbip)
	return;

    RT_CK_DBI(dbip);

    if (client) {
	(void)bu_ptbl_rm(&dbip->dbi_clients, client);
    }

    db_close(dbip);
}
Beispiel #29
0
void
incr_refs(struct db_i *dbip, struct rt_comb_internal *comb, union tree *tp, void *UNUSED(user_ptr1), void *UNUSED(user_ptr2), void *UNUSED(user_ptr3), void *UNUSED(user_ptr4))
{
    struct directory *dp;

    RT_CK_COMB(comb);
    RT_CK_DBI(dbip);
    RT_CK_TREE(tp);

    if ((dp = db_lookup(dbip, tp->tr_l.tl_name, LOOKUP_NOISY)) == RT_DIR_NULL)
	return;

    dp->d_nref++;
}
Beispiel #30
0
/**
 * 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;
}