int
db_dirdelete(struct db_i *dbip, struct directory *dp)
{
    struct directory *findp;
    struct directory **headp;

    RT_CK_DBI(dbip);
    RT_CK_DIR(dp);

    headp = &(dbip->dbi_Head[db_dirhash(dp->d_namep)]);

    if (dp->d_flags & RT_DIR_INMEM) {
	if (dp->d_un.ptr != NULL)
	    bu_free(dp->d_un.ptr, "db_dirdelete() inmem ptr");
    }

    if (*headp == dp) {
	RT_DIR_FREE_NAMEP(dp);	/* frees d_namep */
	*headp = dp->d_forw;

	/* Put 'dp' back on the freelist */
	dp->d_forw = rt_uniresource.re_directory_hd;
	rt_uniresource.re_directory_hd = dp;
	return 0;
    }
    for (findp = *headp; findp != RT_DIR_NULL; findp = findp->d_forw) {
	if (findp->d_forw != dp)
	    continue;
	RT_DIR_FREE_NAMEP(dp);	/* frees d_namep */
	findp->d_forw = dp->d_forw;

	/* Put 'dp' back on the freelist */
	dp->d_forw = rt_uniresource.re_directory_hd;
	rt_uniresource.re_directory_hd = dp;
	return 0;
    }
    return -1;
}
int
bw_write(icv_image_t *bif, const char *filename)
{

    unsigned char *data;
    FILE *fp;
    size_t ret, size;

    if (bif->color_space == ICV_COLOR_SPACE_RGB) {
	icv_rgb2gray_ntsc(bif);
    } else if (bif->color_space != ICV_COLOR_SPACE_GRAY) {
	bu_log("bw_write : Color Space conflict");
	return -1;
    }
    data = data2uchar(bif);
    size = bif->height*bif->width;

    if (filename == NULL) {
	fp = stdout;
    } else {
	fp = fopen(filename, "wb");
	if (fp == NULL) {
	    bu_log("bw_write: Cannot open file for saving\n");
	    return -1;
	}
    }

    ret = fwrite(data, 1, size, fp);
    fclose(fp);
    bu_free(data, "bw_write : Unsigned Char data");

    if (ret != size) {
	bu_log("bw_write : Short Write\n");
	return -1;
    }

    return 0;
}
示例#3
0
文件: process.c 项目: cciechad/brlcad
void 
process_point(point_line_t *plt) {
    static int code_state = INT32_MAX;
    static int points = 0;
    static point_line_t *plta = NULL;

    if (!plt) {
	printf("WARNING: Unexpected call to process_point with a NULL point structure\n");
	return;
    }

    /* state change, we're either starting or ending */
    if (code_state != plt->code) {
	if (points > 0) {
	    process_multi_group(&plta, points, TOL);
	    printf("END OF BLOCK %d\n", code_state);

	    /* finish up this batch */
	    bu_free((genptr_t)plta, "end point_line_t group");
	    plta = NULL;
	}

	if (plt->type)
	    printf("BEGIN OF BLOCK %s (%d)\n", plt->type, plt->code);

	/* get ready for the new batch */
	code_state = plt->code;
	points = 0;
    }

    /* allocate room for the new point */
    if (!plta)
	plta = (point_line_t *) bu_malloc(sizeof(point_line_t), "begin point_line_t group");
    else
	plta = (point_line_t *) bu_realloc(plta, sizeof(point_line_t) * (points + 1), "add point_line_t");
    COPY_POINT_LINE_T(plta[points], *plt);
    points++;
}
static int
process_triangulation(struct db_tree_state *tsp, const struct db_full_path *pathp, struct _ged_client_data *dgcdp)
{
    int result = 1;

    if (!BU_SETJUMP) {
	/* try */

	nmg_triangulate_model(*tsp->ts_m, tsp->ts_tol);
	result = 0;

    } else {
	/* catch */

	char *sofar = db_path_to_string(pathp);

	bu_vls_printf(dgcdp->gedp->ged_result_str, "WARNING: Triangulation of %s failed!\n", sofar);
	bu_free((void *)sofar, "path string");

    } BU_UNSETJUMP;

    return result;
}
示例#5
0
文件: db_diff.c 项目: kanzure/brlcad
void
diff_free_result(struct diff_result *result)
{
    unsigned int i = 0;
    if (result->obj_name) {
	bu_free(result->obj_name, "free name copy in diff result");
    }
    BU_PUT(result->diff_tol, struct bn_tol);
    for (i = 0; i < BU_PTBL_LEN(result->param_diffs); i++) {
	struct diff_avp *avp = (struct diff_avp *)BU_PTBL_GET(result->param_diffs, i);
	diff_free_avp(avp);
	BU_PUT(avp, struct diff_avp);
    }
    bu_ptbl_free(result->param_diffs);
    BU_PUT(result->param_diffs, struct bu_ptbl);
    for (i = 0; i < BU_PTBL_LEN(result->attr_diffs); i++) {
	struct diff_avp *avp = (struct diff_avp *)BU_PTBL_GET(result->attr_diffs, i);
	diff_free_avp(avp);
	BU_PUT(avp, struct diff_avp);
    }
    bu_ptbl_free(result->attr_diffs);
    BU_PUT(result->attr_diffs, struct bu_ptbl);
}
示例#6
0
HIDDEN union tree *
wdb_eval_bool(struct bu_list *hp)
{
    int done=0;
    union tree *final_tree;
    struct tokens *tok;

    while (done != 1) {
	wdb_do_inter(hp);
	wdb_do_union_subtr(hp);
	done = wdb_do_paren(hp);
    }

    if (done == 1) {
	tok = BU_LIST_NEXT(tokens, hp);
	final_tree = tok->tp;
	BU_LIST_DEQUEUE(&tok->l);
	bu_free((char *)tok, "tok");
	return(final_tree);
    }

    return (union tree *)NULL;
}
示例#7
0
static void
process_triangulation(struct nmgregion *r, const struct db_full_path *pathp, struct db_tree_state *tsp)
{
    if (!BU_SETJUMP) {
	/* try */

	/* Write the facetized region to the output file */
	output_nmg(r, pathp, tsp->ts_regionid, tsp->ts_gmater);

    } else {
	/* catch */

	char *sofar;

	sofar = db_path_to_string(pathp);
	bu_log("FAILED in triangulator: %s\n", sofar);
	bu_free((char *)sofar, "sofar");

	/* Sometimes the NMG library adds debugging bits when
	 * it detects an internal error, before bombing out.
	 */
	RTG.NMG_debug = NMG_debug;	/* restore mode */

	/* Release any intersector 2d tables */
	nmg_isect2d_final_cleanup();

	/* Get rid of (m)any other intermediate structures */
	if ((*tsp->ts_m)->magic == NMG_MODEL_MAGIC) {
	    nmg_km(*tsp->ts_m);
	} else {
	    bu_log("WARNING: tsp->ts_m pointer corrupted, ignoring it.\n");
	}

	/* Now, make a new, clean model structure for next pass. */
	*tsp->ts_m = nmg_mm();
    }  BU_UNSETJUMP;
}
示例#8
0
文件: dirname.c 项目: cciechad/brlcad
/**
 *			B U _ D I R N A M E
 *
 *  Given a filesystem pathname, return a pointer to a dynamic string
 *  which is the parent directory of that file/directory.
 *
 *	/usr/dir/file	/usr/dir
 * @n	/usr/dir/	/usr
 * @n	/usr/file	/usr
 * @n	/usr/		/
 * @n	/usr		/
 * @n	/		/
 * @n	.		.
 * @n	..		.
 * @n	usr		.
 * @n	a/b		a
 * @n	a/		.
 * @n	../a/b		../a
 */
char *
bu_dirname(const char *cp)
{
    char	*ret;
    char	*slash;
    int	len;

    /* Special cases */
    if ( cp == NULL )  return bu_strdup(".");
    if ( strcmp( cp, "/" ) == 0 )
	return bu_strdup("/");
    if ( strcmp( cp, "." ) == 0 ||
	 strcmp( cp, ".." ) == 0 ||
	 strrchr(cp, '/') == NULL )
	return bu_strdup(".");

    /* Make a duplicate copy of the string, and shorten it in place */
    ret = bu_strdup(cp);

    /* A trailing slash doesn't count */
    len = strlen(ret);
    if ( ret[len-1] == '/' )  ret[len-1] = '\0';

    /* If no slashes remain, return "." */
    if ( (slash = strrchr(ret, '/')) == NULL )  {
	bu_free( ret, "bu_dirname" );
	return bu_strdup(".");
    }

    /* Remove trailing slash, unless it's at front */
    if ( slash == ret )
	ret[1] = '\0';		/* ret == "/" */
    else
	*slash = '\0';

    return ret;
}
示例#9
0
文件: g-off.c 项目: cciechad/brlcad
static void
nmg_to_psurf(struct nmgregion *r, FILE *fp_psurf)
    /* NMG region to be converted. */
    /* Jack format file to write vertex list to. */
{
    int			i;
    int			*map;	/* map from v->index to Jack vert # */
    struct bu_ptbl		vtab;	/* vertex table */

    map = (int *)bu_calloc(r->m_p->maxindex, sizeof(int *), "Jack vert map");

    /* Built list of vertex structs */
    nmg_vertex_tabulate( &vtab, &r->l.magic );

    /* XXX What to do if 0 vertices?  */

    /* Print list of unique vertices and convert from mm to cm. */
    for (i = 0; i < BU_PTBL_END(&vtab); i++)  {
	struct vertex			*v;
	register struct vertex_g	*vg;
	v = (struct vertex *)BU_PTBL_GET(&vtab, i);
	NMG_CK_VERTEX(v);
	vg = v->vg_p;
	NMG_CK_VERTEX_G(vg);
	NMG_INDEX_ASSIGN( map, v, i+1 );  /* map[v->index] = i+1 */
	fprintf(fp_psurf, "%f\t%f\t%f\n",
		vg->coord[X] / 10.,
		vg->coord[Y] / 10.,
		vg->coord[Z] / 10.);
    }
    fprintf(fp_psurf, ";;\n");

    jack_faces(r, fp_psurf, map);

    bu_ptbl( &vtab, BU_PTBL_FREE, 0 );
    bu_free( (char *)map, "Jack vert map" );
}
示例#10
0
void addtext(struct frame *fp, char *tp)
{
    char *p;
    int length;

#ifdef DEBUG
    fprintf(stderr, "addtext: %s\n", tp);
#endif

    BU_CKMAG(&(fp->l.magic), MAGIC, "frame magic");

    length = strlen(tp) + 1;	/* length of text string and NULL */
    length += 1;			/* For the Space or newline */
    if (fp->text) {
	length += fp->tp;
    }
    if (length > fp->tl || !fp->text) {
	fp->tl = (length/1024)*1024 + 1024;
	p = (char *) bu_malloc(fp->tl, "text area");
	*p = '\0';

	if (fp->text) {
	    bu_strlcpy(p, fp->text, fp->tl);
	    bu_free(fp->text, "text area");
	}
	fp->text = p;
    }
    bu_strlcat(&fp->text[fp->tp], tp, fp->tl);

    if (*tp == ';') {
	bu_strlcat(&fp->text[fp->tp], "\n", fp->tl);
    } else {
	bu_strlcat(&fp->text[fp->tp], " ", fp->tl);
    }

    fp->tp += strlen(tp)+1;
}
示例#11
0
文件: nurb_ray.c 项目: kanzure/brlcad
struct face_g_snurb *
rt_nurb_region_from_srf(const struct face_g_snurb *srf, int dir, fastf_t param1, fastf_t param2, struct resource *res)
{
    register int i;
    struct face_g_snurb *region;
    struct knot_vector new_knots;

    fastf_t *knot_vec = NULL;
    size_t maxorder = FMAX(srf->order[0], srf->order[1]);
    knot_vec = (fastf_t *)bu_calloc(maxorder * 2, sizeof(fastf_t), "knot vector");

    /* Build the new knot vector in a local array, which gets copied
     * later in rt_nurb_s_refine(). */
    new_knots.knots = &knot_vec[0];

    if (dir == RT_NURB_SPLIT_ROW) {
	new_knots.k_size = srf->order[0] * 2;

	for (i = 0; i < srf->order[0]; i++) {
	    knot_vec[i] = param1;
	    knot_vec[i+srf->order[0]] = param2;
	}
    } else {
	new_knots.k_size = srf->order[1] * 2;

	for (i = 0; i < srf->order[1]; i++) {
	    knot_vec[i] = param1;
	    knot_vec[i+srf->order[1]] = param2;
	}
    }

    region = rt_nurb_s_refine(srf, dir, &new_knots, res);
    bu_free(knot_vec, "knot vector");

    return region;
}
/**
 * @brief This routine is called when a region is first encountered in the
 * hierarchy when processing a tree
 *
 *      @param tsp tree state (for parsing the tree)
 *      @param pathp A listing of all the nodes traversed to get to this node in the database
 *      @param combp the combination record for this region
 */
int
region_start(struct db_tree_state *tsp,
	     const struct db_full_path *pathp,
	     const struct rt_comb_internal *combp,
	     void *client_data)
{
    char *name;
    struct directory *dp;
    struct bu_vls str = BU_VLS_INIT_ZERO;
    struct user_data *your_stuff = (struct user_data *)client_data;

    RT_CK_DBTS(tsp);

    name = db_path_to_string(pathp);
    bu_log("region_start %s\n", name);
    bu_free(name, "reg_start name");

    bu_log("data = %ld\n", your_stuff->data);
    rt_pr_tol(&your_stuff->tol);

    dp = DB_FULL_PATH_CUR_DIR(pathp);

    /* here is where the conversion should be done */
    if (combp->region_flag)
	printf("Write this region (name=%s) as a part in your format:\n", dp->d_namep);
    else
	printf("Write this combination (name=%s) as an assembly in your format:\n", dp->d_namep);

    describe_tree(combp->tree, &str);

    printf("\t%s\n\n", bu_vls_addr(&str));

    bu_vls_free(&str);

    return 0;
}
示例#13
0
/*
 *  Called from db_walk_tree().
 *
 *  This routine must be prepared to run in parallel.
 */
union tree *do_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, union tree *curtree, void *UNUSED(client_data))
{
    union tree		*ret_tree;
    struct bu_list		vhead;
    struct nmgregion	*r;

    RT_CK_FULL_PATH(pathp);
    RT_CK_TREE(curtree);
    RT_CK_TESS_TOL(tsp->ts_ttol);
    BN_CK_TOL(tsp->ts_tol);
    NMG_CK_MODEL(*tsp->ts_m);

    BU_LIST_INIT(&vhead);

    {
	char	*sofar = db_path_to_string(pathp);
	bu_log("\ndo_region_end(%d %d%%) %s\n",
	       regions_tried,
	       regions_tried>0 ? (regions_converted * 100) / regions_tried : 0,
	       sofar);
	bu_free(sofar, "path string");
    }

    if (curtree->tr_op == OP_NOP)
	return curtree;

    regions_tried++;

    if (verbose)
	bu_log("Attempting to process region %s\n", db_path_to_string(pathp));

    ret_tree= process_boolean(curtree, tsp, pathp);

    if (ret_tree)
	r = ret_tree->tr_d.td_r;
    else
    {
	if (verbose)
	    bu_log("\tNothing left of this region after Boolean evaluation\n");
	regions_written++; /* don't count as a failure */
	r = (struct nmgregion *)NULL;
    }

    regions_converted++;

    if (r != (struct nmgregion *)NULL)
    {
	struct shell *s;
	int empty_region=0;
	int empty_model=0;

	/* Kill cracks */
	s = BU_LIST_FIRST(shell, &r->s_hd);
	while (BU_LIST_NOT_HEAD(&s->l, &r->s_hd))
	{
	    struct shell *next_s;

	    next_s = BU_LIST_PNEXT(shell, &s->l);
	    if (nmg_kill_cracks(s))
	    {
		if (nmg_ks(s))
		{
		    empty_region = 1;
		    break;
		}
	    }
	    s = next_s;
	}

	/* kill zero length edgeuses */
	if (!empty_region) {
	    empty_model = nmg_kill_zero_length_edgeuses(*tsp->ts_m);
	}

	if (!empty_region && !empty_model) {
	    process_triangulation(r, pathp, tsp);

	    regions_written++;
	}

	if (!empty_model)
	    nmg_kr(r);
    }

    /*
     *  Dispose of original tree, so that all associated dynamic
     *  memory is released now, not at the end of all regions.
     *  A return of TREE_NULL from this routine signals an error,
     *  and there is no point to adding _another_ message to our output,
     *  so we need to cons up an OP_NOP node to return.
     */


    db_free_tree(curtree, &rt_uniresource);		/* Does an nmg_kr() */

    BU_ALLOC(curtree, union tree);
    RT_TREE_INIT(curtree);
    curtree->tr_op = OP_NOP;
    return curtree;
}
示例#14
0
/* routine to output the faceted NMG representation of a BRL-CAD region */
static void
output_nmg(struct nmgregion *r, const struct db_full_path *pathp, int UNUSED(region_id), int UNUSED(material_id))
{
    struct model *m;
    struct shell *s;
    struct vertex *v;
    char *region_name;

    NMG_CK_REGION(r);
    RT_CK_FULL_PATH(pathp);

    region_name = db_path_to_string(pathp);

    m = r->m_p;
    NMG_CK_MODEL(m);

    /* triangulate model */
    nmg_triangulate_model(m, &tol);

    /* Output triangles */
    if (verbose) {
	printf("Convert these triangles to your format for region %s\n", region_name);
    } else {
	printf("Converted %s\n", region_name);
    }
    for (BU_LIST_FOR(s, shell, &r->s_hd))
    {
	struct faceuse *fu;

	NMG_CK_SHELL(s);

	for (BU_LIST_FOR(fu, faceuse, &s->fu_hd))
	{
	    struct loopuse *lu;
	    /* vect_t facet_normal; */

	    NMG_CK_FACEUSE(fu);

	    if (fu->orientation != OT_SAME)
		continue;

	    /* Grab the face normal if needed */
	    /* NMG_GET_FU_NORMAL(facet_normal, fu); */

	    for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd))
	    {
		struct edgeuse *eu;

		NMG_CK_LOOPUSE(lu);

		if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
		    continue;

		/* loop through the edges in this loop (facet) */
		if (verbose)
		    printf("\tfacet:\n");
		for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd))
		{
		    NMG_CK_EDGEUSE(eu);

		    v = eu->vu_p->v_p;
		    NMG_CK_VERTEX(v);
		    if (verbose)
			printf("\t\t(%g %g %g)\n", V3ARGS(v->vg_p->coord));
		}
		tot_polygons++;
	    }
	}
    }

    bu_free(region_name, "region name");
}
示例#15
0
文件: sh_fbm.c 项目: cciechad/brlcad
/*
 *	F B M _ F R E E
 */
HIDDEN void
fbm_free(char *cp)
{
    bu_free( cp, "fbm_specific" );
}
示例#16
0
文件: vshoot.c 项目: kanzure/brlcad
/**
 * Given a ray, shoot it at all the relevant parts of the model,
 * (building the HeadSeg chain), and then call rt_boolregions() to
 * build and evaluate the partition chain.  If the ray actually hit
 * anything, call the application's a_hit() routine with a pointer to
 * the partition chain, otherwise, call the application's a_miss()
 * routine.
 *
 * It is important to note that rays extend infinitely only in the
 * positive direction.  The ray is composed of all points P, where
 *
 * P = r_pt + K * r_dir
 *
 * for K ranging from 0 to +infinity.  There is no looking backwards.
 *
 * It is also important to note that the direction vector r_dir must
 * have unit length; this is mandatory, and is not ordinarily checked,
 * in the name of efficiency.
 *
 * Input:  Pointer to an application structure, with these mandatory fields:
 * a_ray.r_pt Starting point of ray to be fired
 * a_ray.r_dir UNIT VECTOR with direction to fire in (dir cosines)
 * a_hit Routine to call when something is hit
 * a_miss Routine to call when ray misses everything
 *
 * Calls user's a_miss() or a_hit() routine as appropriate.  Passes
 * a_hit() routine list of partitions, with only hit_dist fields
 * valid.  Normal computation deferred to user code, to avoid needless
 * computation here.
 *
 * Returns: whatever the application function returns (an int).
 *
 * NOTE: The application functions may call rt_shootray() recursively.
 * Thus, none of the local variables may be static.
 *
 * An open issue for execution in a PARALLEL environment is locking of
 * the statistics variables.
 */
int
rt_vshootray(struct application *ap)
{
    struct seg *HeadSeg;
    int ret;
    vect_t inv_dir;	/* inverses of ap->a_ray.r_dir */
    struct bu_bitv *solidbits;	/* bits for all solids shot so far */
    struct bu_ptbl *regionbits;	/* bits for all involved regions */
    char *status;
    struct partition InitialPart;	/* Head of Initial Partitions */
    struct partition FinalPart;	/* Head of Final Partitions */
    int nrays = 1;			/* for now */
    int vlen;
    int id;
    int i;
    struct soltab **ary_stp;	/* array of pointers */
    struct xray **ary_rp;	/* array of pointers */
    struct seg *ary_seg;	/* array of structures */
    struct rt_i *rtip;
    int done;

#define BACKING_DIST (-2.0)		/* mm to look behind start point */
    rtip = ap->a_rt_i;
    RT_AP_CHECK(ap);
    if (!ap->a_resource) {
	ap->a_resource = &rt_uniresource;
    }
    RT_CK_RESOURCE(ap->a_resource);

    if (RT_G_DEBUG&(DEBUG_ALLRAYS|DEBUG_SHOOT|DEBUG_PARTITION)) {
	bu_log("\n**********mshootray cpu=%d  %d, %d lvl=%d (%s)\n",
	       ap->a_resource->re_cpu,
	       ap->a_x, ap->a_y,
	       ap->a_level,
	       ap->a_purpose != (char *)0 ? ap->a_purpose : "?");
	VPRINT("Pnt", ap->a_ray.r_pt);
	VPRINT("Dir", ap->a_ray.r_dir);
    }

    rtip->rti_nrays++;
    if (rtip->needprep)
	rt_prep(rtip);

    /* Allocate dynamic memory */
    vlen = nrays * rtip->rti_maxsol_by_type;
    ary_stp = (struct soltab **)bu_calloc(vlen, sizeof(struct soltab *),
					  "*ary_stp[]");
    ary_rp = (struct xray **)bu_calloc(vlen, sizeof(struct xray *),
				       "*ary_rp[]");
    ary_seg = (struct seg *)bu_calloc(vlen, sizeof(struct seg),
				      "ary_seg[]");

    /**** for each ray, do this ****/

    InitialPart.pt_forw = InitialPart.pt_back = &InitialPart;
    FinalPart.pt_forw = FinalPart.pt_back = &FinalPart;

    HeadSeg = RT_SEG_NULL;

    solidbits = rt_get_solidbitv(rtip->nsolids, ap->a_resource);

    if (BU_LIST_IS_EMPTY(&ap->a_resource->re_region_ptbl)) {
	BU_ALLOC(regionbits, struct bu_ptbl);
	bu_ptbl_init(regionbits, 7, "rt_shootray() regionbits ptbl");
    } else {
	regionbits = BU_LIST_FIRST(bu_ptbl, &ap->a_resource->re_region_ptbl);
	BU_LIST_DEQUEUE(&regionbits->l);
	BU_CK_PTBL(regionbits);
    }

    /* Compute the inverse of the direction cosines */
    if (!ZERO(ap->a_ray.r_dir[X])) {
	inv_dir[X]=1.0/ap->a_ray.r_dir[X];
    } else {
	inv_dir[X] = INFINITY;
	ap->a_ray.r_dir[X] = 0.0;
    }
    if (!ZERO(ap->a_ray.r_dir[Y])) {
	inv_dir[Y]=1.0/ap->a_ray.r_dir[Y];
    } else {
	inv_dir[Y] = INFINITY;
	ap->a_ray.r_dir[Y] = 0.0;
    }
    if (!ZERO(ap->a_ray.r_dir[Z])) {
	inv_dir[Z]=1.0/ap->a_ray.r_dir[Z];
    } else {
	inv_dir[Z] = INFINITY;
	ap->a_ray.r_dir[Z] = 0.0;
    }

    /*
     * XXX handle infinite solids here, later.
     */

    /*
     * If ray does not enter the model RPP, skip on.
     * If ray ends exactly at the model RPP, trace it.
     */
    if (!rt_in_rpp(&ap->a_ray, inv_dir, rtip->mdl_min, rtip->mdl_max)  ||
	ap->a_ray.r_max < 0.0) {
	rtip->nmiss_model++;
	if (ap->a_miss)
	    ret = ap->a_miss(ap);
	else
	    ret = 0;
	status = "MISS model";
	goto out;
    }

    /* For each type of solid to be shot at, assemble the vectors */
    for (id = 1; id <= ID_MAX_SOLID; id++) {
	register int nsol;

	if ((nsol = rtip->rti_nsol_by_type[id]) <= 0) continue;

	/* For each instance of this solid type */
	for (i = nsol-1; i >= 0; i--) {
	    ary_stp[i] = rtip->rti_sol_by_type[id][i];
	    ary_rp[i] = &(ap->a_ray);	/* XXX, sb [ray] */
	    ary_seg[i].seg_stp = SOLTAB_NULL;
	    BU_LIST_INIT(&ary_seg[i].l);
	}
	/* bounding box check */
	/* bit vector per ray check */
	/* mark elements to be skipped with ary_stp[] = SOLTAB_NULL */
	ap->a_rt_i->nshots += nsol;	/* later: skipped ones */
	if (OBJ[id].ft_vshot) {
	    OBJ[id].ft_vshot(ary_stp, ary_rp, ary_seg, nsol, ap);
	} else {
	    vshot_stub(ary_stp, ary_rp, ary_seg, nsol, ap);
	}


	/* set bits for all solids shot at for each ray */

	/* append resulting seg list to input for boolweave */
	for (i = nsol-1; i >= 0; i--) {
	    register struct seg *seg2;

	    if (ary_seg[i].seg_stp == SOLTAB_NULL) {
		/* MISS */
		ap->a_rt_i->nmiss++;
		continue;
	    }
	    ap->a_rt_i->nhits++;

	    /* For now, do it the slow way.  sb [ray] */
	    /* MUST dup it -- all segs have to live till after a_hit() */
	    RT_GET_SEG(seg2, ap->a_resource);
	    *seg2 = ary_seg[i];	/* struct copy */
	    /* rt_boolweave(seg2, &InitialPart, ap); */
	    bu_bomb("FIXME: need to call boolweave here");

	    /* Add seg chain to list of used segs awaiting reclaim */

#if 0
	    /* FIXME: need to use waiting_segs/finished_segs here in
	     * conjunction with rt_boolweave()
	     {
	     register struct seg *seg3 = seg2;
	     while (seg3->seg_next != RT_SEG_NULL)
	     seg3 = seg3->seg_next;
	     seg3->seg_next = HeadSeg;
	     HeadSeg = seg2;
	     }
	    */
#endif
	}
    }

    /*
     * Ray has finally left known space.
     */
    if (InitialPart.pt_forw == &InitialPart) {
	if (ap->a_miss)
	    ret = ap->a_miss(ap);
	else
	    ret = 0;
	status = "MISSed all primitives";
	goto freeup;
    }

    /*
     * All intersections of the ray with the model have been computed.
     * Evaluate the boolean trees over each partition.
     */
    done = rt_boolfinal(&InitialPart, &FinalPart, BACKING_DIST, INFINITY, regionbits, ap, solidbits);

    if (done > 0) goto hitit;

    if (FinalPart.pt_forw == &FinalPart) {
	if (ap->a_miss)
	    ret = ap->a_miss(ap);
	else
	    ret = 0;
	status = "MISS bool";
	goto freeup;
    }

    /*
     * Ray/model intersections exist.  Pass the list to the user's
     * a_hit() routine.  Note that only the hit_dist elements of
     * pt_inhit and pt_outhit have been computed yet.  To compute both
     * hit_point and hit_normal, use the
     *
     * RT_HIT_NORMAL(NULL, hitp, stp, rayp, 0);
     *
     * macro.  To compute just hit_point, use
     *
     * VJOIN1(hitp->hit_point, rp->r_pt, hitp->hit_dist, rp->r_dir);
     */
hitit:
    if (RT_G_DEBUG&DEBUG_SHOOT) rt_pr_partitions(rtip, &FinalPart, "a_hit()");

    if (ap->a_hit)
	ret = ap->a_hit(ap, &FinalPart, HeadSeg/* &finished_segs */);
    else
	ret = 0;
    status = "HIT";

    /*
     * Processing of this ray is complete.  Free dynamic resources.
     */
freeup:
    {
	register struct partition *pp;

	/* Free up initial partition list */
	for (pp = InitialPart.pt_forw; pp != &InitialPart;) {
	    register struct partition *newpp;
	    newpp = pp;
	    pp = pp->pt_forw;
	    FREE_PT(newpp, ap->a_resource);
	}
	/* Free up final partition list */
	for (pp = FinalPart.pt_forw; pp != &FinalPart;) {
	    register struct partition *newpp;
	    newpp = pp;
	    pp = pp->pt_forw;
	    FREE_PT(newpp, ap->a_resource);
	}
    }

    /* Segs can't be freed until after a_hit() has returned */
#if 0
    /* FIXME: depends on commented out code above */
    if (HeadSeg)
	RT_FREE_SEG_LIST(HeadSeg, ap->a_resource);
#endif

out:
    bu_free((char *)ary_stp, "*ary_stp[]");
    bu_free((char *)ary_rp, "*ary_rp[]");
    bu_free((char *)ary_seg, "ary_seg[]");

    if (solidbits != NULL) {
	bu_bitv_free(solidbits);
    }
    if (RT_G_DEBUG&(DEBUG_ALLRAYS|DEBUG_SHOOT|DEBUG_PARTITION)) {
	bu_log("----------mshootray cpu=%d  %d, %d lvl=%d (%s) %s ret=%d\n",
	       ap->a_resource->re_cpu,
	       ap->a_x, ap->a_y,
	       ap->a_level,
	       ap->a_purpose != (char *)0 ? ap->a_purpose : "?",
	       status, ret);
    }
    return ret;
}
int
main(int ac, char **av)
{
    int fmt = 0;
    int ret = 0;
    int ac_offset = 0;
    const char *in_fmt = NULL;
    const char *out_fmt = NULL;
    mime_model_t in_type = MIME_MODEL_UNKNOWN;
    mime_model_t out_type = MIME_MODEL_UNKNOWN;
    struct bu_vls in_format = BU_VLS_INIT_ZERO;
    struct bu_vls in_path = BU_VLS_INIT_ZERO;
    struct bu_vls out_format = BU_VLS_INIT_ZERO;
    struct bu_vls out_path = BU_VLS_INIT_ZERO;
    struct bu_vls log = BU_VLS_INIT_ZERO;
    struct bu_vls input_opts = BU_VLS_INIT_ZERO;
    struct bu_vls output_opts = BU_VLS_INIT_ZERO;

    ac-=(ac>0); av+=(ac>0); // skip program name argv[0] if present
    ac_offset = (ac > 2) ? 2 : 0;  // The last two argv entries must always be the input and output paths

    /* Handle anything else as options */
    option::Stats stats(TopUsage, ac - ac_offset, av);
    option::Option *options = (option::Option *)bu_calloc(stats.options_max, sizeof(option::Option), "options");
    option::Option *buffer= (option::Option *)bu_calloc(stats.buffer_max, sizeof(option::Option), "options");
    option::Parser parse(TopUsage, ac - ac_offset, av, options, buffer);

    /* Now that we've parsed them, start using them */
    if (options[HELP] || ac == 0) {
	if (options[HELP].arg) {
	    int help_type_int = bu_file_mime(options[HELP].arg, MIME_MODEL);
	    switch (help_type_int) {
		case MIME_MODEL_VND_FASTGEN:
		    option::printUsage(std::cout, Fast4Usage);
		    break;
		case MIME_MODEL_STL:
		    option::printUsage(std::cout, STLUsage);
		    break;
		default:
		    option::printUsage(std::cout, TopUsage);
		    break;
	    }
	} else {
	    option::printUsage(std::cout, TopUsage);
	    // TODO - figure out how to get this info from each plugin to construct this table
	    // on the fly...
	    bu_log("\nSupported formats:\n");
	    bu_log(" ------------------------------------------------------------\n");
	    bu_log(" | Extension  |          File Format      |  Input | Output |\n");
	    bu_log(" |----------------------------------------------------------|\n");
	    bu_log(" |    stl     |   STereoLithography       |   Yes  |   Yes  |\n");
	    bu_log(" |------------|---------------------------|--------|--------|\n");
	    bu_log(" |    obj     |   Wavefront Object        |   Yes  |   Yes  |\n");
	    bu_log(" |------------|---------------------------|--------|--------|\n");
	    bu_log(" |    step    |   STEP (AP203)            |   Yes  |   Yes  |\n");
	    bu_log(" |------------|---------------------------|--------|--------|\n");
	    bu_log(" |    iges    |   Initial Graphics        |   Yes  |   No   |\n");
	    bu_log(" |            |   Exchange Specification  |        |        |\n");
	    bu_log(" |----------------------------------------------------------|\n");
	}
	goto cleanup;
    }

    /* Any args that weren't top level args will get passed to the
     * format specific arg processing routines, after we use the known
     * top level options and the path inputs to determine what the file
     * types in question are.  Steps:
     *
     * 1.  Reassemble the unknown args into strings. */
    reassemble_argstr(&input_opts, &output_opts, options[UNKNOWN]);
    if (bu_vls_strlen(&input_opts) > 0) bu_log("Unknown options (input): %s\n", bu_vls_addr(&input_opts));
    if (bu_vls_strlen(&output_opts) > 0) bu_log("Unknown options (output): %s\n", bu_vls_addr(&output_opts));
    /*
     * 2.  Use bu_argv_from_string to create new
     * arrays to be fed to the format specific option parsers.*/

    /* TODO - determine whether we want to have a specific option prefix,
     * such as in- and out-, to identify an option as specific to the
     * input file format suboption parser only.  i.e.:
     *
     * --in-tol=1.0  -> --tol=1.0 to the input file's suboptions only
     * --out-tol=2.0 -> --tol=2.0 to the input file's suboptions only
     * --tol=1.5     -> --tol=1.5 to both input and output suboptions
     *
     *  consistent with top level --in-format and --out-format options
     *
     */

    /* See if we have input and output files specified */
    if (!extract_path(&in_path, av[ac-2])) {
	bu_vls_printf(&log, "Error: no input path identified: %s\n", av[ac-2]);
	ret = 1;
    }
    if (!extract_path(&out_path, av[ac-1])) {
	bu_vls_printf(&log, "Error: no output path identified: %s\n", av[ac-1]);
	ret = 1;
    }

    /* Make sure we have distinct input and output paths */
    if (bu_vls_strlen(&in_path) > 0 && BU_STR_EQUAL(bu_vls_addr(&in_path), bu_vls_addr(&out_path))) {
	bu_vls_printf(&log, "Error: identical path specified for both input and output: %s\n", bu_vls_addr(&out_path));
	ret = 1;
    }

    /* Find out what input file type we are dealing with */
    if (options[IN_FORMAT]) {
	in_fmt = options[IN_FORMAT].arg;
    } else {
	/* If we aren't overridden by an option, it's worth doing file
	 * introspection to see if the file contents identify the input
	 * type solidly, provided we have that capability.*/

	/* fake type introspection for testing: */
	//bu_vls_sprintf(&in_format, "step");
    }
    fmt = parse_model_string(&in_format, &log, in_fmt, av[ac-2]);
    in_type = (fmt < 0) ? MIME_MODEL_UNKNOWN : (mime_model_t)fmt;
    in_fmt = NULL;

    /* Identify output file type */
    if (options[OUT_FORMAT]) out_fmt = options[OUT_FORMAT].arg;
    fmt = parse_model_string(&out_format, &log, out_fmt, av[ac-1]);
    out_type = (fmt < 0) ? MIME_MODEL_UNKNOWN : (mime_model_t)fmt;
    out_fmt = NULL;

    /* If we get to this point without knowing both input and output types, we've got a problem */
    if (in_type == MIME_MODEL_UNKNOWN) {
	bu_vls_printf(&log, "Error: no format type identified for input path: %s\n", bu_vls_addr(&in_path));
	ret = 1;
    }
    if (out_type == MIME_MODEL_UNKNOWN) {
	bu_vls_printf(&log, "Error: no format type identified for output path: %s\n", bu_vls_addr(&out_path));
	ret = 1;
    }

    /* If everything isn't OK, we're done - report and clean up memory */
    if (ret == 1) goto cleanup;

    /* If we've gotten this far, we know enough to try to convert. Until we
     * hook in conversion calls to libgcv, print a summary of the option
     * parsing results for debugging. */
    in_fmt = bu_file_mime_str((int)in_type, MIME_MODEL);
    out_fmt = bu_file_mime_str((int)out_type, MIME_MODEL);
    bu_log("Input file format: %s\n", in_fmt);
    bu_log("Output file format: %s\n", out_fmt);
    bu_log("Input file path: %s\n", bu_vls_addr(&in_path));
    bu_log("Output file path: %s\n", bu_vls_addr(&out_path));

    switch (in_type) {
	case MIME_MODEL_VND_FASTGEN:
	    fast4_arg_process(bu_vls_addr(&input_opts));
	    break;
	case MIME_MODEL_STL:
	    stl_arg_process(bu_vls_addr(&input_opts));
	default:
	    break;
    }

    switch (out_type) {
	case MIME_MODEL_VND_FASTGEN:
	    fast4_arg_process(bu_vls_addr(&output_opts));
	    break;
	case MIME_MODEL_STL:
	    stl_arg_process(bu_vls_addr(&output_opts));
	default:
	    break;
    }



    /* Clean up */
cleanup:
    if (bu_vls_strlen(&log) > 0) bu_log("%s", bu_vls_addr(&log));
    if (in_fmt) bu_free((char *)in_fmt, "input format string");
    if (out_fmt) bu_free((char *)out_fmt, "output format string");
    bu_free(options, "free options");
    bu_free(buffer, "free buffer");
    bu_vls_free(&in_format);
    bu_vls_free(&in_path);
    bu_vls_free(&out_format);
    bu_vls_free(&out_path);
    bu_vls_free(&log);
    bu_vls_free(&input_opts);
    bu_vls_free(&output_opts);

    return ret;
}
int
ged_killtree(struct ged *gedp, int argc, const char *argv[])
{
    struct directory *dp;
    int i;
    int c;
    struct killtree_data gktd;
    static const char *usage = "[-a|-f|-n] object(s)";

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);

    /* initialize result */
    bu_vls_trunc(gedp->ged_result_str, 0);

    /* must be wanting help */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_HELP;
    }

    gktd.gedp = gedp;
    gktd.killrefs = 0;
    gktd.print = 0;
    gktd.force = 0;
    gktd.ac = 1;
    gktd.top = NULL;

    gktd.av = (char **)bu_calloc(1, sizeof(char *) * AV_STEP, "alloc av");
    gktd.av_capacity = AV_STEP;
    BU_ASSERT(gktd.ac + argc + 2 < AV_STEP); /* potential -n opts */
    gktd.av[0] = "killrefs";
    gktd.av[1] = (char *)0;

    bu_optind = 1;
    while ((c = bu_getopt(argc, (char * const *)argv, "afn")) != -1) {
	switch (c) {
	    case 'a':
		gktd.killrefs = 1;
		break;
	    case 'n':
		gktd.print = 1;
		gktd.av[gktd.ac++] = bu_strdup("-n");
		gktd.av[gktd.ac] = (char *)0;
		break;
	    case 'f':
		gktd.force = 1;
		break;
	    default:
		bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		bu_free(gktd.av, "free av (error)");
		gktd.av = NULL;
		return GED_ERROR;
	}
    }

    argc -= (bu_optind - 1);
    argv += (bu_optind - 1);

    /* Objects that would be killed are in the first sublist */
    if (gktd.print)
	bu_vls_printf(gedp->ged_result_str, "{");

    for (i = 1; i < argc; i++) {
	if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL)
	    continue;

	/* ignore phony objects */
	if (dp->d_addr == RT_DIR_PHONY_ADDR)
	    continue;

	/* stash the what's killed so we can find refs elsewhere */
	gktd.top = argv[i];

	db_functree(gedp->ged_wdbp->dbip, dp,
		    killtree_callback, killtree_callback,
		    gedp->ged_wdbp->wdb_resp, (void *)&gktd);
    }

    /* Close the sublist of would-be killed objects. Also open the
     * sublist of objects that reference the would-be killed objects.
     */
    if (gktd.print)
	bu_vls_printf(gedp->ged_result_str, "} {");

    if (gktd.killrefs && gktd.ac > 1) {
	gedp->ged_internal_call = 1;
	(void)ged_killrefs(gedp, gktd.ac, (const char **)gktd.av);
	gedp->ged_internal_call = 0;

	for (i = 1; i < gktd.ac; i++) {
	    if (!gktd.print)
		bu_vls_printf(gedp->ged_result_str, "Freeing %s\n", gktd.av[i]);
	    bu_free((void *)gktd.av[i], "killtree_data");
	    gktd.av[i] = NULL;
	}
    }

    if (gktd.print)
	bu_vls_printf(gedp->ged_result_str, "}");

    bu_free(gktd.av, "free av");
    gktd.av = NULL;

    return GED_OK;
}
示例#19
0
/*
 *  Each word in the command buffer is the name of a treetop.
 */
void
ph_gettrees(struct pkg_conn *UNUSED(pc), char *buf)
{
    size_t n = 0;
    long max_argc = 0;
    char **argv = NULL;
    int	argc = 0;
    struct rt_i *rtip = APP.a_rt_i;

    RT_CK_RTI(rtip);

    if (debug)  fprintf(stderr, "ph_gettrees: %s\n", buf);

    /* Copy values from command line options into rtip */
    rtip->useair = use_air;
    if (rt_dist_tol > 0)  {
	rtip->rti_tol.dist = rt_dist_tol;
	rtip->rti_tol.dist_sq = rt_dist_tol * rt_dist_tol;
    }
    if (rt_perp_tol > 0)  {
	rtip->rti_tol.perp = rt_perp_tol;
	rtip->rti_tol.para = 1 - rt_perp_tol;
    }

    for (n = 0; n < strlen(buf); n++) {
	if (isspace((int)buf[n]))
	    max_argc++;
    }
    argv = (char **)bu_calloc(max_argc+1, sizeof(char *), "alloc argv");

    if ((argc = bu_argv_from_string(argv, max_argc, buf)) <= 0)  {
	/* No words in input */
	(void)free(buf);
	bu_free(argv, "free argv");
	return;
    }
    title_obj = bu_strdup(argv[0]);

    if (rtip->needprep == 0)  {
	/* First clean up after the end of the previous frame */
	if (debug)bu_log("Cleaning previous model\n");
	view_end(&APP);
	view_cleanup(rtip);
	rt_clean(rtip);
	if (rdebug&RDEBUG_RTMEM_END)
	    bu_prmem("After rt_clean");
    }

    /* Load the desired portion of the model */
    if (rt_gettrees(rtip, argc, (const char **)argv, npsw) < 0)
	fprintf(stderr, "rt_gettrees(%s) FAILED\n", argv[0]);
    bu_free(argv, "free argv");

    /* In case it changed from startup time via an OPT command */
    if (npsw > 1)  {
	RTG.rtg_parallel = 1;
    } else
	RTG.rtg_parallel = 0;

    seen_gettrees = 1;
    (void)free(buf);

    prepare();

    /* Acknowledge that we are ready */
    if (pkg_send(MSG_GETTREES_REPLY,
		   title_obj, strlen(title_obj)+1, pcsrv) < 0)
	fprintf(stderr, "MSG_START error\n");
}
示例#20
0
int
get_args(int argc, char **argv)
{
    int ch;
    char *ifname;

    while ((ch = bu_getopt(argc, argv, OPT_STRING)) != -1) {
	switch (ch) {
	    /*
	     * BRL-CAD image-size options
	     */
	    case 'a':
		autosize = 1;
		break;
	    case 's':
		/* square file size */
		file_height = file_width = atol(bu_optarg);
		autosize = 0;
		break;
	    case 'n':
		file_height = atol(bu_optarg);
		autosize = 0;
		break;
	    case 'w':
		file_width = atol(bu_optarg);
		autosize = 0;
		break;
		/*
		 * application-specific options
		 */
	    case 'c':
		make_cells = 1;
		break;
	    case 'f':
		if (format != 0)
		    bu_free(format, "format_string");
		format = (char *)bu_malloc(strlen(bu_optarg)+1, "format string");
		bu_strlcpy(format, bu_optarg, strlen(bu_optarg)+1);
		break;
	    case '#':
		d_per_l = atoi(bu_optarg);
		break;
	    default:
		print_usage(1);
	}
    }
    if (argc == 1 && isatty(fileno(stdin)) && isatty(fileno(stdout)))
	print_usage(0);

    if (format == 0)
	format = " %g";

    /*
     * Establish the input stream
     */
    switch (argc - bu_optind) {
	case 0:
	    file_name = "stdin";
	    infd = 0;
	    break;
	case 1:
	    file_name = argv[bu_optind++];
	    ifname = bu_realpath(file_name, NULL);
	    if ((infd = open(ifname, O_RDONLY)) == -1) {
		bu_free(ifname, "ifname alloc from bu_realpath");
		bu_exit (1, "Cannot open file '%s'\n", file_name);
	    }
	    bu_free(ifname, "ifname alloc from bu_realpath");
	    fileinput = 1;
	    break;
	default:
	    print_usage(1);
    }

    if (argc > ++bu_optind) {
	print_usage(1);
    }

    return 1;		/* OK */
}
示例#21
0
文件: proe-g.c 项目: cciechad/brlcad
static struct name_conv_list *
Add_new_name(char *name, unsigned int obj, int type)
{
    struct name_conv_list *ptr;

    if ( debug )
	bu_log( "Add_new_name( %s, x%x, %d )\n", name, obj, type );

    if ( type != ASSEMBLY_TYPE && type != PART_TYPE && type != CUT_SOLID_TYPE )
    {
	bu_exit(EXIT_FAILURE, "Bad type for name (%s) in Add_new_name\n", name );
    }


    /* Add a new name */
    ptr = (struct name_conv_list *)bu_calloc( 1, sizeof( struct name_conv_list ), "Add_new_name: prev->next" );
    ptr->next = (struct name_conv_list *)NULL;
    ptr->brlcad_name = bu_strdup( name );
    ptr->obj = obj;
    if ( do_regex && type != CUT_SOLID_TYPE )
    {
	regmatch_t pmatch;

	if ( regexec( &reg_cmp, ptr->brlcad_name, 1, &pmatch, 0  ) == 0 )
	{
	    /* got a match */
	    bu_strlcpy( &ptr->brlcad_name[pmatch.rm_so], &ptr->brlcad_name[pmatch.rm_eo], MAX_LINE_SIZE );
	}
	if ( debug )
	    bu_log( "\tafter reg_ex, name is %s\n", ptr->brlcad_name );
    }
    else if ( type == CUT_SOLID_TYPE ) {
	bu_free( (char *)ptr->brlcad_name, "brlcad_name" );
	ptr->brlcad_name = NULL;
    }
    ptr->solid_use_no = 0;
    ptr->comb_use_no = 0;

    if ( type != CUT_SOLID_TYPE )
    {
	/* make sure brlcad_name is unique */
	char *tmp;

	tmp = ptr->brlcad_name;
	ptr->brlcad_name = bu_strdup( Build_unique_name( ptr->brlcad_name ) );
	bu_free( (char *)tmp, "brlcad_name" );
    }

    if ( type == ASSEMBLY_TYPE )
    {
	ptr->solid_name = NULL;
	return( ptr );
    }
    else if ( type == PART_TYPE )
    {
	struct bu_vls vls;

	bu_vls_init( &vls );

	bu_vls_strcpy( &vls, "s." );
	bu_vls_strcat( &vls, ptr->brlcad_name );

	ptr->solid_name = bu_vls_strgrab( &vls );
    }
    else
    {
	struct bu_vls vls;

	bu_vls_init( &vls );

	bu_vls_strcpy( &vls, "s." );
	bu_vls_strcat( &vls, ptr->brlcad_name );

	ptr->solid_name = bu_vls_strgrab( &vls );
    }

    /* make sure solid name is unique */
    ptr->solid_name = bu_strdup( Build_unique_name( ptr->solid_name ) );
    return( ptr );
}
示例#22
0
/*
 *			M A I N
 */
int
main(int argc, char **argv)
{
    unsigned char	*inbuf;
    unsigned char	*outbuf;
    int	*rout, *gout, *bout;
    long int	out_width;
    long int	i;
    int	eof_seen;

    if ( !get_args( argc, argv ) )  {
	(void)fputs(usage, stderr);
	bu_exit ( 1, NULL );
    }

    /* autosize input? */
    if ( fileinput && autosize ) {
	unsigned long int	w, h;
	if ( fb_common_file_size(&w, &h, file_name, 3) ) {
	    file_width = (long)w;
	} else {
	    fprintf(stderr, "pixhalve: unable to autosize\n");
	}
    }
    out_width = file_width/2;

    /* Allocate 1-scanline input & output buffers */
    inbuf = malloc( 3*file_width+8 );
    outbuf = malloc( 3*(out_width+2)+8 );

    /* Allocate 5 integer arrays for each color */
    /* each width+2 elements wide */
    for ( i=0; i<5; i++ )  {
	rlines[i] = (int *)bu_calloc( (file_width+4)+1, sizeof(long), "rlines" );
	glines[i] = (int *)bu_calloc( (file_width+4)+1, sizeof(long), "glines" );
	blines[i] = (int *)bu_calloc( (file_width+4)+1, sizeof(long), "blines" );
    }

    /* Allocate an integer array for each color, for output */
    rout = (int *)bu_malloc( out_width * sizeof(long) + 8, "rout" );
    gout = (int *)bu_malloc( out_width * sizeof(long) + 8, "gout" );
    bout = (int *)bu_malloc( out_width * sizeof(long) + 8, "bout" );

    /*
     *  Prime the pumps with 5 lines of image.
     *  Repeat the bottom most line three times to generate a "fill"
     *  line on the bottom.  This will have to be matched on the top.
     */
    if ( fread( inbuf, 3, file_width, infp ) != file_width )  {
	perror(file_name);
	fprintf(stderr, "pixhalve:  fread error\n");
	bu_exit (1, NULL);
    }
    separate( &rlines[0][2], &glines[0][2], &blines[0][2], inbuf, file_width );
    separate( &rlines[1][2], &glines[1][2], &blines[1][2], inbuf, file_width );
    separate( &rlines[2][2], &glines[2][2], &blines[2][2], inbuf, file_width );
    for ( i=3; i<5; i++ )  {
	if ( fread( inbuf, 3, file_width, infp ) != file_width )  {
	    perror(file_name);
	    fprintf(stderr, "pixhalve:  fread error\n");
	    bu_exit (1, NULL);
	}
	separate( &rlines[i][2], &glines[i][2], &blines[i][2],
		  inbuf, file_width );
    }

    eof_seen = 0;
    for (;;)  {
	filter3( rout, rlines, out_width );
	filter5( gout, glines, out_width );
	filter5( bout, blines, out_width );
	combine( outbuf, rout, gout, bout, out_width );
	if ( fwrite( (void*)outbuf, 3, out_width, stdout ) != out_width )  {
	    perror("stdout");
	    bu_exit (2, NULL);
	}

	/* Ripple down two scanlines, and acquire two more */
	if ( fread( inbuf, 3, file_width, infp ) != file_width )  {
	    if ( eof_seen >= 2 )  break;
	    /* EOF, repeat last line 2x for final output line */
	    eof_seen++;
	    /* Fall through */
	}
	ripple( rlines, 5 );
	ripple( glines, 5 );
	ripple( blines, 5 );
	separate( &rlines[4][2], &glines[4][2], &blines[4][2],
		  inbuf, file_width );

	if ( fread( inbuf, 3, file_width, infp ) != file_width )  {
	    if ( eof_seen >= 2 )  break;
	    /* EOF, repeat last line 2x for final output line */
	    eof_seen++;
	    /* Fall through */
	}
	ripple( rlines, 5 );
	ripple( glines, 5 );
	ripple( blines, 5 );
	separate( &rlines[4][2], &glines[4][2], &blines[4][2],
		  inbuf, file_width );
    }

    bu_free(rlines, "rlines");
    bu_free(glines, "glines");
    bu_free(blines, "blines");
    bu_free(rout, "rout");
    bu_free(gout, "gout");
    bu_free(bout, "bout");
}
示例#23
0
extern "C" void
rt_nmg_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *tol)
{
    struct model *m;
    struct nmgregion *r;
    struct shell *s;
    struct faceuse *fu;
    struct loopuse *lu;
    struct edgeuse *eu;

    int edge_index;
    long* brepi;

    RT_CK_DB_INTERNAL(ip);
    m = (struct model *)ip->idb_ptr;
    NMG_CK_MODEL(m);

    brepi = static_cast<long*>(bu_malloc(m->maxindex * sizeof(long), "rt_nmg_brep: brepi[]"));
    for (int i = 0; i < m->maxindex; i++) brepi[i] = -INT_MAX;

    for (BU_LIST_FOR(r, nmgregion, &m->r_hd)) {
	for (BU_LIST_FOR(s, shell, &r->s_hd)) {
	    for (BU_LIST_FOR(fu, faceuse, &s->fu_hd)) {
		NMG_CK_FACEUSE(fu);
		if (fu->orientation != OT_SAME) continue;

		// Need to create ON_NurbsSurface based on plane of
		// face in order to have UV space in which to define
		// trimming loops.  Bounding points are NOT on the
		// face plane, so another approach must be used.
		//
		// General approach: For all loops in the faceuse,
		// collect all the vertices.  Find the center point of
		// all the vertices, and search for the point with the
		// greatest distance from that center point.  Once
		// found, cross the vector between the center point
		// and furthest point with the normal of the face and
		// scale the resulting vector to have the same length
		// as the vector to the furthest point.  Add the two
		// resulting vectors to find the first corner point.
		// Mirror the first corner point across the center to
		// find the second corner point.  Cross the two
		// vectors created by the first two corner points with
		// the face normal to get the vectors of the other two
		// corners, and scale the resulting vectors to the
		// same magnitude as the first two.  These four points
		// bound all vertices on the plane and form a suitable
		// staring point for a UV space, since all points on
		// all the edges are equal to or further than the
		// distance between the furthest vertex and the center
		// point.

		// ............. .............
		// .           .* .          .
		// .         .  .    .       .
		// .        .   .      .     .
		// .       .    .       *    .
		// .      .     .       .    .
		// .     .      .       .    .
		// .    .       .       .    .
		// .   *        *       .    .
		// .   .                .    .
		// .   .                .    .
		// .   .                .    .
		// .   *.               .    .
		// .     ...        ...*     .
		// .       .... ....         .
		// .           *             .
		// ...........................
		//


		const struct face_g_plane *fg = fu->f_p->g.plane_p;
		struct bu_ptbl vert_table;
		nmg_tabulate_face_g_verts(&vert_table, fg);
		point_t tmppt, center, max_pt;
		struct vertex **pt;

		VSET(tmppt, 0, 0, 0);
		VSET(max_pt, 0, 0, 0);

		int ptcnt = 0;
		for (BU_PTBL_FOR(pt, (struct vertex **), &vert_table)) {
		    tmppt[0] += (*pt)->vg_p->coord[0];
		    tmppt[1] += (*pt)->vg_p->coord[1];
		    tmppt[2] += (*pt)->vg_p->coord[2];
		    ptcnt++;
		    if (brepi[(*pt)->vg_p->index] == -INT_MAX) {
			ON_BrepVertex& vert = (*b)->NewVertex((*pt)->vg_p->coord, SMALL_FASTF);
			brepi[(*pt)->vg_p->index] = vert.m_vertex_index;
		    }
		}
		VSET(center, tmppt[0]/ptcnt, tmppt[1]/ptcnt, tmppt[2]/ptcnt);
		fastf_t max_dist = 0.0;
		fastf_t curr_dist;
		for (BU_PTBL_FOR(pt, (struct vertex **), &vert_table)) {
		    tmppt[0] = (*pt)->vg_p->coord[0];
		    tmppt[1] = (*pt)->vg_p->coord[1];
		    tmppt[2] = (*pt)->vg_p->coord[2];
		    curr_dist = DIST_PT_PT(center, tmppt);
		    if (curr_dist > max_dist) {
			max_dist = curr_dist;
			VMOVE(max_pt, tmppt);
		    }
		}
		bu_ptbl_free(&vert_table);
		int ccw = 0;
		vect_t vtmp, uv1, uv2, uv3, uv4, vnormal;
		// If an outer loop is found in the nmg with a cw
		// orientation, use a flipped normal to form the NURBS
		// surface
		for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
		    if (lu->orientation == OT_SAME && nmg_loop_is_ccw(lu, fg->N, tol) == -1) ccw = -1;
		}
		if (ccw != -1) {
		    VSET(vnormal, fg->N[0], fg->N[1], fg->N[2]);
		} else {
		    VSET(vnormal, -fg->N[0], -fg->N[1], -fg->N[2]);
		}
		VSUB2(uv1, max_pt, center);
		VCROSS(vtmp, uv1, vnormal);
		VADD2(uv1, uv1, vtmp);
		VCROSS(uv2, uv1, vnormal);
		VREVERSE(uv3, uv1);
		VCROSS(uv4, uv3, vnormal);
		VADD2(uv1, uv1, center);
		VADD2(uv2, uv2, center);
		VADD2(uv3, uv3, center);
		VADD2(uv4, uv4, center);

		ON_3dPoint p1 = ON_3dPoint(uv1);
		ON_3dPoint p2 = ON_3dPoint(uv2);
		ON_3dPoint p3 = ON_3dPoint(uv3);
		ON_3dPoint p4 = ON_3dPoint(uv4);

		(*b)->m_S.Append(sideSurface(p1, p4, p3, p2));
		ON_Surface *surf = (*(*b)->m_S.Last());
		int surfindex = (*b)->m_S.Count();

		// Now that we have the surface, define the face
		ON_BrepFace& face = (*b)->NewFace(surfindex - 1);

		// With the surface and the face defined, make
		// trimming loops and create faces.  To generate UV
		// coordinates for each from and to for the
		// edgecurves, the UV origin is defined to be v1,
		// v1->v2 is defined as the U domain, and v1->v4 is
		// defined as the V domain.
		vect_t u_axis, v_axis;
		VSUB2(u_axis, uv2, uv1);
		VSUB2(v_axis, uv4, uv1);
		fastf_t u_axis_dist = MAGNITUDE(u_axis);
		fastf_t v_axis_dist = MAGNITUDE(v_axis);

		// Now that the surface context is set up, add the loops.
		for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
		    int edges=0;
		    if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC) continue; // loop is a single vertex
		    ON_BrepLoop::TYPE looptype;
		    // Check if this is an inner or outer loop
		    if (lu->orientation == OT_SAME) {
			looptype = ON_BrepLoop::outer;
		    } else {
			looptype = ON_BrepLoop::inner;
		    }
		    ON_BrepLoop& loop = (*b)->NewLoop(looptype, face);
		    for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
			++edges;
			vect_t ev1, ev2;
			struct vertex_g *vg1, *vg2;
			vg1 = eu->vu_p->v_p->vg_p;
			NMG_CK_VERTEX_G(vg1);
			int vert1 = brepi[vg1->index];
			VMOVE(ev1, vg1->coord);
			vg2 = eu->eumate_p->vu_p->v_p->vg_p;
			NMG_CK_VERTEX_G(vg2);
			int vert2 = brepi[vg2->index];
			VMOVE(ev2, vg2->coord);
			// Add edge if not already added
			if (brepi[eu->e_p->index] == -INT_MAX) {
			    /* always add edges with the small vertex index as from */
			    if (vg1->index > vg2->index) {
				int tmpvert = vert1;
				vert1 = vert2;
				vert2 = tmpvert;
			    }
			    // Create and add 3D curve
			    ON_Curve* c3d = new ON_LineCurve((*b)->m_V[vert1].Point(), (*b)->m_V[vert2].Point());
			    c3d->SetDomain(0.0, 1.0);
			    (*b)->m_C3.Append(c3d);
			    // Create and add 3D edge
			    ON_BrepEdge& e = (*b)->NewEdge((*b)->m_V[vert1], (*b)->m_V[vert2] , (*b)->m_C3.Count() - 1);
			    e.m_tolerance = 0.0;
			    brepi[eu->e_p->index] = e.m_edge_index;
			}
			// Regardless of whether the edge existed as
			// an object, it needs to be added to the
			// trimming loop
			vect_t u_component, v_component;
			ON_3dPoint vg1pt(vg1->coord);
			int orientation = 0;
			edge_index = brepi[eu->e_p->index];
			if (vg1pt !=  (*b)->m_V[(*b)->m_E[edge_index].m_vi[0]].Point()) {
			    orientation = 1;
			}
			// Now, make 2d trimming curves
			vect_t vect1, vect2;
			VSUB2(vect1, ev1, uv1);
			VSUB2(vect2, ev2, uv1);
			ON_2dPoint from_uv, to_uv;
			double u0, u1, v0, v1;
			surf->GetDomain(0, &u0, &u1);
			surf->GetDomain(1, &v0, &v1);

			VPROJECT(vect1, u_axis, u_component, v_component);
			from_uv.y = u0 + MAGNITUDE(u_component)/u_axis_dist*(u1-u0);
			from_uv.x = v0 + MAGNITUDE(v_component)/v_axis_dist*(v1-v0);
			VPROJECT(vect2, u_axis, u_component, v_component);
			to_uv.y = u0 + MAGNITUDE(u_component)/u_axis_dist*(u1-u0);
			to_uv.x = v0 + MAGNITUDE(v_component)/v_axis_dist*(v1-v0);
			ON_3dPoint S1, S2;
			ON_3dVector Su, Sv;
			surf->Ev1Der(from_uv.x, from_uv.y, S1, Su, Sv);
			surf->Ev1Der(to_uv.x, to_uv.y, S2, Su, Sv);
			ON_Curve* c2d =  new ON_LineCurve(from_uv, to_uv);
			c2d->SetDomain(0.0, 1.0);
			int c2i = (*b)->m_C2.Count();
			(*b)->m_C2.Append(c2d);
			edge_index = brepi[eu->e_p->index];
			ON_BrepTrim& trim = (*b)->NewTrim((*b)->m_E[edge_index], orientation, loop, c2i);
			trim.m_type = ON_BrepTrim::mated;
			trim.m_tolerance[0] = 0.0;
			trim.m_tolerance[1] = 0.0;
		    }
		}
	    }
	    (*b)->SetTrimIsoFlags();
	}
    }

    bu_free(brepi, "rt_nmg_brep: brepi[]");
}
HIDDEN void
killtree_callback(struct db_i *dbip, struct directory *dp, void *ptr)
{
    struct killtree_data *gktdp = (struct killtree_data *)ptr;
    int ref_exists = 0;

    if (dbip == DBI_NULL)
	return;

    /* don't bother checking for references if the -f or -a flags are
     * presented to force a full kill and all references respectively.
     */
    if (!gktdp->force && !gktdp->killrefs)
	ref_exists = find_reference(dbip, gktdp->top, dp->d_namep);

    /* if a reference exists outside of the subtree we're killing, we
     * don't kill this object or it'll create invalid reference
     * elsewhere in the database.  do nothing.
     */
    if (ref_exists)
	return;

    if (gktdp->print) {
	if (!gktdp->killrefs)
	    bu_vls_printf(gktdp->gedp->ged_result_str, "%s ", dp->d_namep);
	else {
	    if ((size_t)(gktdp->ac + 2) >= gktdp->av_capacity) {
		gktdp->av = (char **)bu_realloc(gktdp->av, sizeof(char *) * (gktdp->av_capacity + AV_STEP), "realloc av");
		gktdp->av_capacity += AV_STEP;
	    }
	    gktdp->av[gktdp->ac++] = bu_strdup(dp->d_namep);
	    gktdp->av[gktdp->ac] = (char *)0;

	    bu_vls_printf(gktdp->gedp->ged_result_str, "%s ", dp->d_namep);
	}
    } else {
	_dl_eraseAllNamesFromDisplay(gktdp->gedp->ged_gdp->gd_headDisplay, gktdp->gedp->ged_wdbp->dbip, gktdp->gedp->ged_free_vlist_callback, dp->d_namep, 0, gktdp->gedp->freesolid);

	bu_vls_printf(gktdp->gedp->ged_result_str, "KILL %s:  %s\n",
		      (dp->d_flags & RT_DIR_COMB) ? "COMB" : "Solid",
		      dp->d_namep);

	if (!gktdp->killrefs) {
	    if (db_delete(dbip, dp) != 0 || db_dirdelete(dbip, dp) != 0) {
		bu_vls_printf(gktdp->gedp->ged_result_str, "an error occurred while deleting %s\n", dp->d_namep);
	    }
	} else {
	    if ((size_t)(gktdp->ac + 2) >= gktdp->av_capacity) {
		gktdp->av = (char **)bu_realloc(gktdp->av, sizeof(char *) * (gktdp->av_capacity + AV_STEP), "realloc av");
		gktdp->av_capacity += AV_STEP;
	    }
	    gktdp->av[gktdp->ac++] = bu_strdup(dp->d_namep);
	    gktdp->av[gktdp->ac] = (char *)0;

	    if (db_delete(dbip, dp) != 0 || db_dirdelete(dbip, dp) != 0) {
		bu_vls_printf(gktdp->gedp->ged_result_str, "an error occurred while deleting %s\n", dp->d_namep);

		/* Remove from list */
		bu_free((void *)gktdp->av[--gktdp->ac], "killtree_callback");
		gktdp->av[gktdp->ac] = (char *)0;
	    }
	}
    }
}
示例#25
0
文件: sh_text.c 项目: kanzure/brlcad
/*
 * This is a helper routine used in txt_setup() to load a texture either from
 * a file or from a db object.  The resources are released in txt_free()
 * (there is no specific unload_datasource function).
 */
HIDDEN int
txt_load_datasource(struct txt_specific *texture, struct db_i *dbInstance, const unsigned long int size)
{
    struct directory *dirEntry;

    RT_CK_DBI(dbInstance);

    if (texture == (struct txt_specific *)NULL) {
	bu_bomb("ERROR: txt_load_datasource() received NULL arg (struct txt_specific *)\n");
    }

    bu_log("Loading texture %s [%s]...", texture->tx_datasrc==TXT_SRC_AUTO?"from auto-determined datasource":texture->tx_datasrc==TXT_SRC_OBJECT?"from a database object":texture->tx_datasrc==TXT_SRC_FILE?"from a file":"from an unknown source (ERROR)", bu_vls_addr(&texture->tx_name));

    /* if the source is auto or object, we try to load the object */
    if ((texture->tx_datasrc==TXT_SRC_AUTO) || (texture->tx_datasrc==TXT_SRC_OBJECT)) {

	/* see if the object exists */
	if ((dirEntry=db_lookup(dbInstance, bu_vls_addr(&texture->tx_name), LOOKUP_QUIET)) == RT_DIR_NULL) {

	    /* unable to find the texture object */
	    if (texture->tx_datasrc!=TXT_SRC_AUTO) {
		return -1;
	    }
	} else {
	    struct rt_db_internal *dbip;

	    BU_ALLOC(dbip, struct rt_db_internal);

	    RT_DB_INTERNAL_INIT(dbip);
	    RT_CK_DB_INTERNAL(dbip);
	    RT_CK_DIR(dirEntry);

	    /* the object was in the directory, so go get it */
	    if (rt_db_get_internal(dbip, dirEntry, dbInstance, NULL, NULL) <= 0) {
		/* unable to load/create the texture database record object */
		return -1;
	    }

	    RT_CK_DB_INTERNAL(dbip);
	    RT_CK_BINUNIF(dbip->idb_ptr);

	    /* keep the binary object pointer */
	    texture->tx_binunifp=(struct rt_binunif_internal *)dbip->idb_ptr; /* make it so */

	    /* release the database instance pointer struct we created */
	    RT_DB_INTERNAL_INIT(dbip);
	    bu_free(dbip, "txt_load_datasource");

	    /* check size of object */
	    if (texture->tx_binunifp->count < size) {
		bu_log("\nWARNING: %s needs %d bytes, binary object only has %lu\n", bu_vls_addr(&texture->tx_name), size, texture->tx_binunifp->count);
	    } else if (texture->tx_binunifp->count > size) {
		bu_log("\nWARNING: Binary object is larger than specified texture size\n\tBinary Object: %zu pixels\n\tSpecified Texture Size: %zu pixels\n...continuing to load using image subsection...", texture->tx_binunifp->count);
	    }
	}
    }

    /* if we are auto and we couldn't find a database object match, or if source
     * is explicitly a file then we load the file.
     */
    if (((texture->tx_datasrc==TXT_SRC_AUTO) && (texture->tx_binunifp==NULL)) || (texture->tx_datasrc==TXT_SRC_FILE)) {

	texture->tx_mp = bu_open_mapped_file_with_path(dbInstance->dbi_filepath,	bu_vls_addr(&texture->tx_name), NULL);

	if (texture->tx_mp==NULL)
	    return -1;				/* FAIL */

	if (texture->tx_mp->buflen < size) {
	    bu_log("\nWARNING: %s needs %d bytes, file only has %lu\n", bu_vls_addr(&texture->tx_name), size, texture->tx_mp->buflen);
	} else if (texture->tx_mp->buflen > size) {
	    bu_log("\nWARNING: Texture file size is larger than specified texture size\n\tInput File: %zu pixels\n\tSpecified Texture Size: %lu pixels\n...continuing to load using image subsection...", texture->tx_mp->buflen, size);
	}

    }

    bu_log("done.\n");

    return 0;
}
示例#26
0
void texture_mix_free(texture_t *texture) {
    bu_free(texture->data, "texture data");
}
示例#27
0
void
texture_blend_free(struct texture_s *texture) {
    bu_free(texture->data, "texture data");
}
/**
 * Read a polygon file and convert it to an NMG shell
 *
 * A polygon file consists of the following:
 *
 * The first line consists of two integer numbers: the number of
 * points (vertices) in the file, followed by the number of polygons
 * in the file.  This line is followed by lines for each of the
 * vertices.  Each vertex is listed on its own line, as the 3tuple "X
 * Y Z".  After the list of vertices comes the list of polygons.
 * each polygon is represented by a line containing 1) the number of
 * vertices in the polygon, followed by 2) the indices of the
 * vertices that make up the polygon.
 *
 * Implicitly returns r->s_p which is a new shell containing all the
 * faces from the polygon file.
 *
 * XXX This is a horrible way to do this.  Lee violates his own rules
 * about not creating fundamental structures on his own...  :-)
 * Retired in favor of more modern tessellation strategies.
 */
struct shell *
nmg_polytonmg(FILE *fp, struct nmgregion *r, const struct bn_tol *tol)
{
    int i, j, num_pts, num_facets, pts_this_face, facet;
    int vl_len;
    struct vertex **v;  /* list of all vertices */
    struct vertex **vl; /* list of vertices for this polygon*/
    point_t p;
    struct shell *s;
    struct faceuse *fu;
    struct loopuse *lu;
    struct edgeuse *eu;
    plane_t plane;
    struct model *m;

    s = nmg_msv(r);
    m = s->r_p->m_p;
    nmg_kvu(s->vu_p);

    /* get number of points & number of facets in file */
    if (fscanf(fp, "%d %d", &num_pts, &num_facets) != 2)
	bu_bomb("polytonmg() Error in first line of poly file\n");
    else
	if (RTG.NMG_debug & DEBUG_POLYTO)
	    bu_log("points: %d facets: %d\n",
		   num_pts, num_facets);


    v = (struct vertex **) bu_calloc(num_pts, sizeof (struct vertex *),
				     "vertices");

    /* build the vertices */
    for (i = 0; i < num_pts; ++i) {
	GET_VERTEX(v[i], m);
	v[i]->magic = NMG_VERTEX_MAGIC;
    }

    /* read in the coordinates of the vertices */
    for (i=0; i < num_pts; ++i) {
	if (fscanf(fp, "%lg %lg %lg", &p[0], &p[1], &p[2]) != 3)
	    bu_bomb("polytonmg() Error reading point");
	else
	    if (RTG.NMG_debug & DEBUG_POLYTO)
		bu_log("read vertex #%d (%g %g %g)\n",
		       i, p[0], p[1], p[2]);

	nmg_vertex_gv(v[i], p);
    }

    vl = (struct vertex **)bu_calloc(vl_len=8, sizeof (struct vertex *),
				     "vertex parameter list");

    for (facet = 0; facet < num_facets; ++facet) {
	if (fscanf(fp, "%d", &pts_this_face) != 1)
	    bu_bomb("polytonmg() error getting pt count for this face");

	if (RTG.NMG_debug & DEBUG_POLYTO)
	    bu_log("facet %d pts in face %d\n",
		   facet, pts_this_face);

	if (pts_this_face > vl_len) {
	    while (vl_len < pts_this_face) vl_len *= 2;
	    vl = (struct vertex **)bu_realloc((char *)vl,
					      vl_len*sizeof(struct vertex *),
					      "vertex parameter list (realloc)");
	}

	for (i=0; i < pts_this_face; ++i) {
	    if (fscanf(fp, "%d", &j) != 1)
		bu_bomb("polytonmg() error getting point index for v in f");
	    vl[i] = v[j-1];
	}

	fu = nmg_cface(s, vl, pts_this_face);
	lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
	/* XXX should check for vertex-loop */
	eu = BU_LIST_FIRST(edgeuse, &lu->down_hd);
	NMG_CK_EDGEUSE(eu);
	if (bn_mk_plane_3pts(plane, eu->vu_p->v_p->vg_p->coord,
			     BU_LIST_PNEXT(edgeuse, eu)->vu_p->v_p->vg_p->coord,
			     BU_LIST_PLAST(edgeuse, eu)->vu_p->v_p->vg_p->coord,
			     tol)) {
	    bu_log("At %d in %s\n", __LINE__, __FILE__);
	    bu_bomb("polytonmg() cannot make plane equation\n");
	} else nmg_face_g(fu, plane);
    }

    for (i=0; i < num_pts; ++i) {
	if (BU_LIST_IS_EMPTY(&v[i]->vu_hd)) continue;
	FREE_VERTEX(v[i]);
    }
    bu_free((char *)v, "vertex array");
    return s;
}
示例#29
0
文件: move_all.c 项目: kanzure/brlcad
HIDDEN int
move_all_func(struct ged *gedp, int nflag, const char *old_name, const char *new_name)
{
    int i;
    struct ged_display_list *gdlp;
    struct directory *dp;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    struct bu_ptbl stack;

    /* rename the record itself */
    if ((dp = db_lookup(gedp->ged_wdbp->dbip, old_name, LOOKUP_NOISY)) == RT_DIR_NULL)
	return GED_ERROR;

    if (db_lookup(gedp->ged_wdbp->dbip, new_name, LOOKUP_QUIET) != RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s: already exists", new_name);
	return GED_ERROR;
    }

    /* if this was a sketch, we need to look for all the extrude
     * objects that might use it.
     *
     * This has to be done here, before we rename the (possible) sketch object
     * because the extrude will do a rt_db_get on the sketch when we call
     * rt_db_get_internal on it.
     */
    if (dp->d_major_type == DB5_MAJORTYPE_BRLCAD && \
	dp->d_minor_type == DB5_MINORTYPE_BRLCAD_SKETCH) {

	struct directory *dirp;

	for (i = 0; i < RT_DBNHASH; i++) {
	    for (dirp = gedp->ged_wdbp->dbip->dbi_Head[i]; dirp != RT_DIR_NULL; dirp = dirp->d_forw) {

		if (dirp->d_major_type == DB5_MAJORTYPE_BRLCAD && \
		    dirp->d_minor_type == DB5_MINORTYPE_BRLCAD_EXTRUDE) {
		    struct rt_extrude_internal *extrude;

		    if (rt_db_get_internal(&intern, dirp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
			bu_log("Can't get extrude %s?\n", dirp->d_namep);
			continue;
		    }
		    extrude = (struct rt_extrude_internal *)intern.idb_ptr;
		    RT_EXTRUDE_CK_MAGIC(extrude);

		    if (BU_STR_EQUAL(extrude->sketch_name, old_name)) {
			if (nflag) {
			    bu_vls_printf(gedp->ged_result_str, "%s ", dirp->d_namep);
			    rt_db_free_internal(&intern);
			} else {
			    bu_free(extrude->sketch_name, "sketch name");
			    extrude->sketch_name = bu_strdup(new_name);

			    if (rt_db_put_internal(dirp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
				bu_log("oops\n");
			    }
			}
		    } else
			rt_db_free_internal(&intern);
		}
	    }
	}
    }

    if (!nflag) {
	/* Change object name in the directory. */
	if (db_rename(gedp->ged_wdbp->dbip, dp, new_name) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "error in rename to %s, aborting", new_name);
	    return GED_ERROR;
	}

	/* Change name in the file */
	if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "Database read error, aborting");
	    return GED_ERROR;
	}

	if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "Database write error, aborting");
	    return GED_ERROR;
	}
    }

    bu_ptbl_init(&stack, 64, "combination stack for wdb_mvall_cmd");


    /* Examine all COMB nodes */
    for (i = 0; i < RT_DBNHASH; i++) {
	for (dp = gedp->ged_wdbp->dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw) {
	    if (nflag) {
		union tree *comb_leaf;
		int done=0;

		if (!(dp->d_flags & RT_DIR_COMB)) continue;
		if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) continue;
		comb = (struct rt_comb_internal *)intern.idb_ptr;
		bu_ptbl_reset(&stack);
		/* visit each leaf in the combination */
		comb_leaf = comb->tree;
		if (comb_leaf) {
		    while (!done) {
			while (comb_leaf->tr_op != OP_DB_LEAF) {
			    bu_ptbl_ins(&stack, (long *)comb_leaf);
			    comb_leaf = comb_leaf->tr_b.tb_left;
			}

			if (BU_STR_EQUAL(comb_leaf->tr_l.tl_name, old_name)) {
			    bu_vls_printf(gedp->ged_result_str, "%s ", dp->d_namep);
			}

			if (BU_PTBL_END(&stack) < 1) {
			    done = 1;
			    break;
			}
			comb_leaf = (union tree *)BU_PTBL_GET(&stack, BU_PTBL_END(&stack)-1);
			if (comb_leaf->tr_op != OP_DB_LEAF) {
			    bu_ptbl_rm(&stack, (long *)comb_leaf);
			    comb_leaf = comb_leaf->tr_b.tb_right;
			}
		    }
		}
		rt_db_free_internal(&intern);
	    } else {
		int comb_mvall_status = db_comb_mvall(dp, gedp->ged_wdbp->dbip, old_name, new_name, &stack);
		if (!comb_mvall_status) continue;
		if (comb_mvall_status == 2) {
		    bu_ptbl_free(&stack);
		    bu_vls_printf(gedp->ged_result_str, "Database write error, aborting");
		    return GED_ERROR;
		}
	    }
	}
    }

    bu_ptbl_free(&stack);

    if (!nflag) {
	/* Change object name anywhere in the display list path. */
	for (BU_LIST_FOR(gdlp, ged_display_list, gedp->ged_gdp->gd_headDisplay)) {
	    int first = 1;
	    int found = 0;
	    struct bu_vls new_path = BU_VLS_INIT_ZERO;
	    char *dupstr = strdup(bu_vls_addr(&gdlp->gdl_path));
	    char *tok = strtok(dupstr, "/");

	    while (tok) {
		if (BU_STR_EQUAL(tok, old_name)) {
		    found = 1;

		    if (first) {
			first = 0;
			bu_vls_printf(&new_path, "%s", new_name);
		    } else
			bu_vls_printf(&new_path, "/%s", new_name);
		} else {
		    if (first) {
			first = 0;
			bu_vls_printf(&new_path, "%s", tok);
		    } else
			bu_vls_printf(&new_path, "/%s", tok);
		}

		tok = strtok((char *)NULL, "/");
	    }

	    if (found) {
		bu_vls_free(&gdlp->gdl_path);
		bu_vls_printf(&gdlp->gdl_path, "%s", bu_vls_addr(&new_path));
	    }

	    free((void *)dupstr);
	    bu_vls_free(&new_path);
	}
    }

    return GED_OK;
}
示例#30
0
文件: process.c 项目: cciechad/brlcad
/**
 * handle a group of points of a particular type, with potentially
 * multiple sets delimited by triplicate points.
 */
void 
process_multi_group(point_line_t **plta, int count, double tolerance) {
    int i;
    point_line_t *plt = NULL;

    int points = 0;
    point_line_t *pltg = NULL;

    int marker = 0;
    point_line_t *prev_plt = NULL;

    if (!plta) {
	printf("WARNING: Unexpected call to process_multi_group with a NULL point array\n");
	return;
    }

#if PRINT_ARRAY
    static int print_counter = 0;
    if (print_counter == 0) {
	bu_log("--- BEFORE ---\n");
	print_array(plta, count);
    }
#endif

    /* remove points marked as bogus, 5-identical points in succession */
    count = delete_points(plta, count, tolerance);

#if PRINT_ARRAY
    if (print_counter == 0) {
	print_counter++;
	bu_log("--- AFTER ---\n");
	print_array(plta, count);
    }
#endif

    /* isolate groups and pass them on to the group processing routine */
    for (i = 0; i < count; i++) {
	plt = &(*plta)[i];
	if (!plt || !plt->type) {
	    printf("WARNING: Unexpected NULL encountered while processing a point array (%d of %d)\n", i, count);
	    continue;
	}

	/* if this is the first point of a group, allocate and initialize */
	if (!prev_plt) {
	    prev_plt = &(*plta)[i];
	    pltg = (point_line_t *) bu_malloc(sizeof(point_line_t), "begin point_line_t subgroup");
	    COPY_POINT_LINE_T(*pltg, *prev_plt);
	    marker = 0;
	    continue;
	}

	if (marker) {
	    /* gobble up repeats points used as a marker, average new point */
	    if (DIST_PT_PT(prev_plt->val, plt->val) < tolerance) {
		prev_plt->val[X] = (prev_plt->val[X] + plt->val[X]) / 2.0;
		prev_plt->val[Y] = (prev_plt->val[Y] + plt->val[Y]) / 2.0;
		prev_plt->val[Z] = (prev_plt->val[Z] + plt->val[Z]) / 2.0;
		INITIALIZE_POINT_LINE_T(*plt); /* poof */
		continue;
	    }

	    if (process_group(&pltg, points+1)) {
		bu_free((genptr_t)pltg, "end subgroup: point_line_t");
		pltg = NULL;
		prev_plt = NULL;
		points = 0;
		marker = 0;
		--i;
		continue;
	    } else {
		/* process_group is allowed to return non-zero if
		   there are not enough points -- they get returned to
		   the stack for processing again */
		printf("warning, process_group returned 0\n");
	    }

	    marker = 0;
	    continue;
	}

	/* FIXME: shouldn't just average to the average, later points
	   get weighted too much.. */
	if (DIST_PT_PT(prev_plt->val, plt->val) < tolerance) {
	    /*	    printf("%d: CLOSE DISTANCE of %f\n", plt->index, DIST_PT_PT(prev_plt->val, plt->val));*/
	    marker = points;
	    (pltg[marker]).val[X] = (prev_plt->val[X] + plt->val[X]) / 2.0;
	    (pltg[marker]).val[Y] = (prev_plt->val[Y] + plt->val[Y]) / 2.0;
	    (pltg[marker]).val[Z] = (prev_plt->val[Z] + plt->val[Z]) / 2.0;
	    continue;
	}

	if (!pltg) {
	    printf("Blah! Error. Group array is null. Shouldn't be here!\n");
	    return;
	}

	pltg = (point_line_t *) bu_realloc(pltg, sizeof(point_line_t) * (points + 2), "add subgroup: point_line_t");

	points++;
	COPY_POINT_LINE_T(pltg[points], *plt);
	prev_plt = plt;
    }
    printf("i: %d, count: %d", i, count);

    /* make sure we're not at the end of a list (i.e. no end marker,
       but we're at the end of this group */
    if (points > 0) {
	if (process_group(&pltg, points+1)) {
	    bu_free((genptr_t)pltg, "end point_line_t subgroup");
	    pltg = NULL;
	    prev_plt = NULL;
	    points = 0;
	    marker = 0;
	} else {
	    /* this one shouldn't return zero, we're at the end of a multiblock */
	    printf("ERROR, process_group returned 0\n");
	}
    }

}