Exemplo n.º 1
0
/**
 * Makes a deep copy of a NMG model structure.
 */
struct model *
nmg_clone_model(const struct model *original)
{
    struct model           *ret;
    void *              *structArray;
    const struct nmgregion *originalRegion;
    struct bn_tol           tolerance;

    NMG_CK_MODEL(original);

    structArray = (void **)bu_calloc(original->maxindex, sizeof(void *), "nmg_clone_model() structArray");

    ret = nmg_mm();
    ret->index    = original->index;
    ret->maxindex = original->maxindex;

    structArray[ret->index] = ret;

    tolerance.magic   = BN_TOL_MAGIC;
    tolerance.dist    = 0.0005;
    tolerance.dist_sq = tolerance.dist * tolerance.dist;
    tolerance.perp    = 1e-6;
    tolerance.para    = 1 - tolerance.perp;

    for (BU_LIST_FOR(originalRegion, nmgregion, &original->r_hd)) {
	struct nmgregion *newRegion = (struct nmgregion *)structArray[originalRegion->index];

	if (newRegion == NULL) {
	    const struct shell *originalShell;

	    newRegion = nmg_construct_region(ret, originalRegion, structArray);

	    for (BU_LIST_FOR(originalShell, shell, &originalRegion->s_hd)) {
		struct shell *newShell = (struct shell *)structArray[originalShell->index];

		if (newShell == NULL)
		    newShell = nmg_construct_shell(newRegion, originalShell, structArray);

		BU_LIST_INSERT(&newRegion->s_hd, &newShell->l);
	    }

	    BU_LIST_INSERT(&ret->r_hd, &newRegion->l);
	}
    }

    bu_free(structArray, "nmg_clone_model() structArray");

    return ret;
}
Exemplo n.º 2
0
Arquivo: xxx.c Projeto: kanzure/brlcad
/**
 * Intersect a ray with a xxx.  If an intersection occurs, a struct
 * seg will be acquired and filled in.
 *
 * Returns -
 * 0 MISS
 * >0 HIT
 */
int
rt_xxx_shot(struct soltab *stp, struct xray *rp, struct application *ap, struct seg *seghead)
{
    struct xxx_specific *xxx;

    if (!stp) return -1;
    RT_CK_SOLTAB(stp);
    xxx = (struct xxx_specific *)stp->st_specific;
    if (!xxx) return -1;
    if (rp) RT_CK_RAY(rp);
    if (ap) RT_CK_APPLICATION(ap);
    if (!seghead) return -1;

/* the EXAMPLE_NEW_SEGMENT block shows how one might add a new result
 * if the ray did hit the primitive.  the segment values would need to
 * be adjusted accordingly to match real values instead of -1.
 */
#ifdef EXAMPLE_NEW_SEGMENT
    /* allocate a segment */
    RT_GET_SEG(segp, ap->a_resource);
    segp->seg_stp = stp; /* stash a pointer to the primitive */

    segp->seg_in.hit_dist = -1; /* XXX set to real distance to entry point */
    segp->seg_out.hit_dist = -1; /* XXX set to real distance to exit point */
    segp->seg_in.hit_surfno = -1; /* XXX set to a non-negative ID for entry surface */
    segp->seg_out.hit_surfno = -1;  /* XXX set to a non-negative ID for exit surface */

    /* add segment to list of those encountered for this primitive */
    BU_LIST_INSERT(&(seghead->l), &(segp->l));

    return 2; /* num surface intersections == in + out == 2 */
#endif

    return 0;			/* MISS */
}
Exemplo n.º 3
0
/**
 *	P O P _ F I N D _ N O D E S --- find nodes with equal # of children
 *	note: not part of pop_functree as a lot less arguments are needed
 *	and it eliminates a lot of overhead
 */
int
pop_find_nodes(	union tree *tp)
{
    int n1, n2;
    struct node *add;

    if (!tp)
	return 0;

    switch (tp->tr_op) {
	case OP_DB_LEAF:
	    return 1;
	case OP_UNION:
	case OP_INTERSECT:
	case OP_SUBTRACT:
	case OP_XOR:
	    crossover_parent = &tp->tr_b.tb_left;
	    n1 = pop_find_nodes(tp->tr_b.tb_left);
	    if (n1 == crossover_node) {
		if (tp->tr_b.tb_left->tr_op & crossover_op) {
		    BU_ALLOC(add, struct node);
		    add->s_parent = &tp->tr_b.tb_left;
		    add->s_child = tp->tr_b.tb_left;
		    BU_LIST_INSERT(&node->l, &add->l);
		    ++num_nodes;
		}
	    }
	    crossover_parent = &tp->tr_b.tb_right;
	    n2 = pop_find_nodes(tp->tr_b.tb_right);
	    if (n2 == crossover_node) {
		if (tp->tr_b.tb_right->tr_op & crossover_op) {
		    BU_ALLOC(add, struct node);
		    add->s_parent = &tp->tr_b.tb_right;
		    add->s_child = tp->tr_b.tb_right;
		    BU_LIST_INSERT(&node->l, &add->l);
		    ++num_nodes;
		}
	    }
	    /* include current node as part of the count to
	     * mirror the behavior of db_count_tree_nodes() */
	    return 1+n1 + n2;
    }

    return 0;
}
Exemplo n.º 4
0
HIDDEN int
wdb_add_operand(Tcl_Interp *interp, struct bu_list *hp, char *name)
{
    char *ptr_lparen;
    char *ptr_rparen;
    int name_len;
    union tree *node;
    struct tokens *tok;

    BU_CK_LIST_HEAD(hp);

    ptr_lparen = strchr(name, '(');
    ptr_rparen = strchr(name, ')');

    RT_GET_TREE( node, &rt_uniresource );
    node->magic = RT_TREE_MAGIC;
    node->tr_op = OP_DB_LEAF;
    node->tr_l.tl_mat = (matp_t)NULL;
    if (ptr_lparen || ptr_rparen) {
	int tmp1, tmp2;

	if (ptr_rparen)
	    tmp1 = ptr_rparen - name;
	else
	    tmp1 = (-1);
	if (ptr_lparen)
	    tmp2 = ptr_lparen - name;
	else
	    tmp2 = (-1);

	if (tmp2 == (-1) && tmp1 > 0)
	    name_len = tmp1;
	else if (tmp1 == (-1) && tmp2 > 0)
	    name_len = tmp2;
	else if (tmp1 > 0 && tmp2 > 0) {
	    if (tmp1 < tmp2)
		name_len = tmp1;
	    else
		name_len = tmp2;
	}
	else {
	    Tcl_AppendResult(interp, "Cannot determine length of operand name: ",
			     name, ", aborting\n", (char *)NULL);
	    return (0);
	}
    } else
	name_len = strlen( name );

    node->tr_l.tl_name = (char *)bu_malloc(name_len+1, "node name");
    bu_strlcpy(node->tr_l.tl_name, name, name_len+1);

    tok = (struct tokens *)bu_malloc(sizeof(struct tokens), "tok");
    tok->type = WDB_TOK_TREE;
    tok->tp = node;
    BU_LIST_INSERT(hp, &tok->l);
    return (name_len);
}
Exemplo n.º 5
0
HIDDEN int
add_operand(struct ged *gedp, struct bu_list *hp, char *name)
{
    char *ptr_lparen;
    char *ptr_rparen;
    int name_len;
    union tree *node;
    struct tokens *tok;

    BU_CK_LIST_HEAD(hp);

    ptr_lparen = strchr(name, '(');
    ptr_rparen = strchr(name, ')');

    RT_GET_TREE(node, &rt_uniresource);
    node->tr_op = OP_DB_LEAF;
    node->tr_l.tl_mat = (matp_t)NULL;
    if (ptr_lparen || ptr_rparen) {
	int tmp1, tmp2;

	if (ptr_rparen)
	    tmp1 = ptr_rparen - name;
	else
	    tmp1 = (-1);
	if (ptr_lparen)
	    tmp2 = ptr_lparen - name;
	else
	    tmp2 = (-1);

	if (tmp2 == (-1) && tmp1 > 0)
	    name_len = tmp1;
	else if (tmp1 == (-1) && tmp2 > 0)
	    name_len = tmp2;
	else if (tmp1 > 0 && tmp2 > 0) {
	    if (tmp1 < tmp2)
		name_len = tmp1;
	    else
		name_len = tmp2;
	} else {
	    bu_vls_printf(gedp->ged_result_str, "Cannot determine length of operand name: %s, aborting\n", name);
	    return 0;
	}
    } else
	name_len = (int)strlen(name);

    node->tr_l.tl_name = (char *)bu_malloc(name_len+1, "node name");
    bu_strlcpy(node->tr_l.tl_name, name, name_len+1);

    BU_ALLOC(tok, struct tokens);
    tok->type = TOK_TREE;
    tok->tp = node;
    BU_LIST_INSERT(hp, &tok->l);
    return name_len;
}
Exemplo n.º 6
0
/*
 * Usage:
 * write i|next c x y z
 */
static int
vdraw_write_tcl(void *clientData, int argc, const char *argv[])
{
    struct dg_obj *dgop = (struct dg_obj *)clientData;
    size_t idx;
    unsigned long uind = 0;
    struct bn_vlist *vp, *cp;

    if (!dgop->dgo_currVHead) {
	Tcl_AppendResult(dgop->interp, "vdraw write: no vlist is currently open.", (char *)NULL);
	return TCL_ERROR;
    }
    if (argc < 4) {
	Tcl_AppendResult(dgop->interp, "vdraw write: not enough args\n", (char *)NULL);
	return TCL_ERROR;
    }
    if (argv[1][0] == 'n') {
	/* next */
	for (REV_BU_LIST_FOR(vp, bn_vlist, &(dgop->dgo_currVHead->vdc_vhd))) {
	    if (vp->nused > 0) {
		break;
	    }
	}
	if (BU_LIST_IS_HEAD(vp, &(dgop->dgo_currVHead->vdc_vhd))) {
	    /* we went all the way through */
	    vp = BU_LIST_PNEXT(bn_vlist, vp);
	    if (BU_LIST_IS_HEAD(vp, &(dgop->dgo_currVHead->vdc_vhd))) {
		RT_GET_VLIST(vp);
		BU_LIST_INSERT(&(dgop->dgo_currVHead->vdc_vhd), &(vp->l));
	    }
	}
	if (vp->nused >= BN_VLIST_CHUNK) {
	    vp = BU_LIST_PNEXT(bn_vlist, vp);
	    if (BU_LIST_IS_HEAD(vp, &(dgop->dgo_currVHead->vdc_vhd))) {
		RT_GET_VLIST(vp);
		BU_LIST_INSERT(&(dgop->dgo_currVHead->vdc_vhd), &(vp->l));
	    }
	}
	cp = vp;
	idx = vp->nused;
    } else if (sscanf(argv[1], "%lu", &uind) < 1) {
Exemplo n.º 7
0
HIDDEN void
wdb_append_inter(struct bu_list *hp)
{
    struct tokens *tok;

    BU_CK_LIST_HEAD(hp);

    tok = (struct tokens *)bu_malloc(sizeof(struct tokens), "tok");
    tok->type = WDB_TOK_INTER;
    tok->tp = (union tree *)NULL;
    BU_LIST_INSERT( hp, &tok->l );
}
Exemplo n.º 8
0
/*
 *  Generic routine to add a newly arrived PKG to a linked list,
 *  for later processing.
 *  Note that the buffer will be freed when the list element is processed.
 *  Presently used for MATRIX and LINES messages.
 */
void
ph_enqueue(struct pkg_conn *pc, char *buf)
{
    struct pkg_queue	*lp;

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

    BU_GET(lp, struct pkg_queue);
    lp->type = pc->pkc_type;
    lp->buf = buf;
    BU_LIST_INSERT(&WorkHead, &lp->l);
}
Exemplo n.º 9
0
HIDDEN void
append_union(struct bu_list *hp)
{
    struct tokens *tok;

    BU_CK_LIST_HEAD(hp);

    BU_ALLOC(tok, struct tokens);
    tok->type = TOK_UNION;
    tok->tp = (union tree *)NULL;
    BU_LIST_INSERT(hp, &tok->l);
}
Exemplo n.º 10
0
HIDDEN void
wdb_append_inter(struct bu_list *hp)
{
    struct tokens *tok;

    BU_CK_LIST_HEAD(hp);

    BU_ALLOC(tok, struct tokens);
    tok->type = WDB_TOK_INTER;
    tok->tp = (union tree *)NULL;
    BU_LIST_INSERT(hp, &tok->l);
}
Exemplo n.º 11
0
static struct face *
nmg_construct_face(struct faceuse *parent, const struct face *original, void **structArray)
{
    struct face *ret;

    NMG_GETSTRUCT(ret, face);

    ret->l.magic   = NMG_FACE_MAGIC;
    ret->fu_p      = parent;
    ret->g.magic_p = (uint32_t *)NULL;
    ret->flip      = original->flip;

    VMOVE(ret->min_pt, original->min_pt);
    VMOVE(ret->max_pt, original->max_pt);

    ret->index              = original->index;
    structArray[ret->index] = ret;

    switch (*original->g.magic_p) {
	case NMG_FACE_G_PLANE_MAGIC:
	    ret->g.plane_p = (struct face_g_plane *)structArray[original->g.plane_p->index];

	    if (ret->g.plane_p == NULL)
		ret->g.plane_p = nmg_construct_face_g_plane(original->g.plane_p, structArray);

	    BU_LIST_INSERT(&ret->g.plane_p->f_hd, &ret->l);
	    break;

	case NMG_FACE_G_SNURB_MAGIC:
	    ret->g.snurb_p = (struct face_g_snurb *)structArray[original->g.plane_p->index];

	    if (ret->g.snurb_p == NULL)
		ret->g.snurb_p = nmg_construct_face_g_snurb(original->g.snurb_p, structArray);

	    BU_LIST_INSERT(&ret->g.snurb_p->f_hd, &ret->l);
    }

    return ret;
}
/**
 * Add a single point to an existing metaball.
 */
int
rt_metaball_add_point (struct rt_metaball_internal *mb, const point_t *loc, const fastf_t fldstr, const fastf_t goo)
{
    struct wdb_metaballpt *mbpt;

    BU_GET(mbpt, struct wdb_metaballpt);
    mbpt->l.magic = WDB_METABALLPT_MAGIC;
    VMOVE(mbpt->coord, *loc);
    mbpt->fldstr = fldstr;
    mbpt->sweat = goo;
    BU_LIST_INSERT(&mb->metaball_ctrl_head, &mbpt->l);

    return 0;
}
Exemplo n.º 13
0
void enqueue_site (struct bu_list *sl, fastf_t x, fastf_t y, fastf_t z)
{
    struct site	*sp;

    BU_CK_LIST_HEAD(sl);

    sp = (struct site *) bu_malloc(sizeof(struct site), "site structure");
    sp -> s_magic = SITE_MAGIC;
    sp -> s_x = x;
    sp -> s_y = y;
    sp -> s_z = z;

    BU_LIST_INSERT(sl, &(sp -> l));
}
Exemplo n.º 14
0
void enqueue_site (struct bu_list *sl, fastf_t x, fastf_t y, fastf_t z)
{
    struct site *sp;

    BU_CK_LIST_HEAD(sl);

    BU_ALLOC(sp, struct site);
    sp->s_magic = SITE_MAGIC;
    sp->s_x = x;
    sp->s_y = y;
    sp->s_z = z;

    BU_LIST_INSERT(sl, &(sp->l));
}
Exemplo n.º 15
0
struct region_pair *
add_unique_pair(struct region_pair *list, /* list to add into */
		struct region *r1,        /* first region involved */
		struct region *r2,        /* second region involved */
		double dist,              /* distance/thickness metric value */
		point_t pt)               /* location where this takes place */
{
    struct region_pair *rp, *rpair;

    /* look for it in our list */
    bu_semaphore_acquire(GED_SEM_LIST);
    for (BU_LIST_FOR (rp, region_pair, &list->l)) {

	if ((r1 == rp->r.r1 && r2 == rp->r2) || (r1 == rp->r2 && r2 == rp->r.r1)) {
	    /* we already have an entry for this region pair, we
	     * increase the counter, check the depth and update
	     * thickness maximum and entry point if need be and
	     * return.
	     */
	    rp->count++;

	    if (dist > rp->max_dist) {
		rp->max_dist = dist;
		VMOVE(rp->coord, pt);
	    }
	    rpair = rp;
	    goto found;
	}
    }
    /* didn't find it in the list.  Add it */
    BU_ALLOC(rpair, struct region_pair);
    rpair->r.r1 = r1;
    rpair->r2 = r2;
    rpair->count = 1;
    rpair->max_dist = dist;
    VMOVE(rpair->coord, pt);
    list->max_dist ++; /* really a count */

    /* insert in the list at the "nice" place */
    for (BU_LIST_FOR (rp, region_pair, &list->l)) {
	if (bu_strcmp(rp->r.r1->reg_name, r1->reg_name) <= 0)
	    break;
    }
    BU_LIST_INSERT(&rp->l, &rpair->l);
 found:
    bu_semaphore_release(GED_SEM_LIST);
    return rpair;
}
/**
 * prep and build bounding volumes... unfortunately, generating the
 * bounding sphere is too 'loose' (I think) and O(n^2).
 */
int
rt_metaball_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
{
    struct rt_metaball_internal *mb, *nmb;
    struct wdb_metaballpt *mbpt, *nmbpt;
    fastf_t minfstr = +INFINITY;

    if (rtip) RT_CK_RTI(rtip);

    mb = (struct rt_metaball_internal *)ip->idb_ptr;
    RT_METABALL_CK_MAGIC(mb);

    /* generate a copy of the metaball */
    BU_ALLOC(nmb, struct rt_metaball_internal);
    nmb->magic = RT_METABALL_INTERNAL_MAGIC;
    BU_LIST_INIT(&nmb->metaball_ctrl_head);
    nmb->threshold = mb->threshold;
    nmb->method = mb->method;

    /* and copy the list of control points */
    for (BU_LIST_FOR(mbpt, wdb_metaballpt, &mb->metaball_ctrl_head)) {
	BU_ALLOC(nmbpt, struct wdb_metaballpt);
	nmbpt->fldstr = mbpt->fldstr;
	if (mbpt->fldstr < minfstr)
	    minfstr = mbpt->fldstr;
	nmbpt->sweat = mbpt->sweat;
	VMOVE(nmbpt->coord, mbpt->coord);
	BU_LIST_INSERT(&nmb->metaball_ctrl_head, &nmbpt->l);
    }

    /* find the bounding sphere */
    stp->st_aradius = rt_metaball_get_bounding_sphere(&stp->st_center, mb->threshold, mb);
    stp->st_bradius = stp->st_aradius * 1.01;

    /* XXX magic numbers, increase if scalloping is observed. :(*/
    nmb->initstep = minfstr / 2.0;
    if (nmb->initstep < (stp->st_aradius / 200.0))
	nmb->initstep = (stp->st_aradius / 200.0);
    else if (nmb->initstep > (stp->st_aradius / 10.0))
	nmb->initstep = (stp->st_aradius / 10.0);
    nmb->finalstep = /*stp->st_aradius * */minfstr / 1e5;

    /* generate a bounding box around the sphere...
     * XXX this can be optimized greatly to reduce the BSP presence... */
    if (rt_metaball_bbox(ip, &(stp->st_min), &(stp->st_max), &rtip->rti_tol)) return 1;
    stp->st_specific = (void *)nmb;
    return 0;
}
Exemplo n.º 17
0
int
main(int argc, char *argv[])
{
    struct frame *newframe, *lp;

    int base, count;

    if (!get_args(argc, argv)) {
	return 1;
    }
    if (verbose) fprintf(stderr, "scriptsort: starting.\n");

    BU_LIST_INIT(&head);
    globals.text=NULL;
    globals.tp=globals.tl = 0;
    globals.flags=globals.location=globals.length = 0;
    globals.l.magic = MAGIC;

    if (verbose) fprintf(stderr, "scriptsort: reading.\n");

    while ((newframe=getframe(stdin)) != NULL) {
	BU_LIST_INSERT(&head, &newframe->l);
    }
    if (verbose) fprintf(stderr, "scriptsort: sorting.\n");
    bubblesort();
    if (verbose) fprintf(stderr, "scriptsort: merging.\n");
    merge();

    if (verbose) fprintf(stderr, "scriptsort: squirting.\n");
    if (specify_base) {
	base = user_base;
    } else {
	base = 1; /* prints frames in natural order */
    }
    if (base <= 0) {
	/*compute base as largest power of 2 less than num of frames*/
	base = 1;
	count = 2;
	for (BU_LIST_FOR(lp, frame, &head)) {
	    if (count-- <= 0) {
		base *= 2;
		count = base - 1;
	    }
	}
    } else {
Exemplo n.º 18
0
static struct faceuse *
nmg_construct_faceuse(struct shell *parent, const struct faceuse *original, void **structArray)
{
    struct faceuse       *ret;
    const struct loopuse *originalLoopUse;

    NMG_GETSTRUCT(ret, faceuse);

    ret->l.magic     = NMG_FACEUSE_MAGIC;
    ret->s_p         = parent;
    ret->fumate_p    = (struct faceuse *)NULL;
    ret->orientation = original->orientation;
    ret->outside     = original->outside;
    ret->f_p         = (struct face *)NULL;

    BU_LIST_INIT(&ret->lu_hd);

    ret->index              = original->index;
    structArray[ret->index] = ret;

    if (original->fumate_p != NULL) {
	ret->fumate_p = (struct faceuse *)structArray[original->fumate_p->index];

	if (ret->fumate_p == NULL)
	    ret->fumate_p = nmg_construct_faceuse(parent, original->fumate_p, structArray);
    }

    if (original->f_p != NULL) {
	ret->f_p = (struct face *)structArray[original->f_p->index];

	if (ret->f_p == 0)
	    ret->f_p = nmg_construct_face(ret, original->f_p, structArray);
    }

    for (BU_LIST_FOR(originalLoopUse, loopuse, &original->lu_hd)) {
	struct loopuse *newLoopUse = (struct loopuse *)structArray[originalLoopUse->index];

	if (newLoopUse == NULL)
	    newLoopUse = nmg_construct_loopuse(ret, originalLoopUse, structArray);

	BU_LIST_INSERT(&ret->lu_hd, &newLoopUse->l);
    }

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

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

    if (dbip) RT_CK_DBI(dbip);

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

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

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

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

    bu_free((void *)buf, "rt_metaball_import5: buf");
    return 0;		/* OK */
}
Exemplo n.º 20
0
/**
 * called by rt_shootray(), stores a ray that hit the shape
 */
int
capture_hit(register struct application *ap, struct partition *partHeadp, struct seg *UNUSED(segs))
{
    register struct partition *pp;
    struct part *add;

    /* initialize list of partitions */
    BU_ALLOC(((struct fitness_state *)ap->a_uptr)->ray[ap->a_user], struct part);
    BU_LIST_INIT(&((struct fitness_state *)ap->a_uptr)->ray[ap->a_user]->l);

    /* save ray */
    for (pp = partHeadp->pt_forw; pp != partHeadp; pp = pp->pt_forw) {
	BU_ALLOC(add, struct part);
	add->inhit_dist = pp->pt_inhit->hit_dist;
	add->outhit_dist = pp->pt_outhit->hit_dist;
	BU_LIST_INSERT(&((struct fitness_state *)ap->a_uptr)->ray[ap->a_user]->l, &add->l);
    }
    return 1;
}
Exemplo n.º 21
0
static struct vertexuse *
nmg_construct_vertexuse(void *parent, const struct vertexuse *original, void **structArray)
{
    struct vertexuse *ret;

    NMG_GETSTRUCT(ret, vertexuse);

    ret->l.magic            = NMG_VERTEXUSE_MAGIC;
    ret->up.magic_p         = (uint32_t *)parent;
    ret->v_p                = (struct vertex*)NULL;
    ret->a.magic_p          = NULL;
    ret->index              = original->index;
    structArray[ret->index] = ret;

    if (original->v_p != NULL) {
	ret->v_p = (struct vertex *)structArray[original->v_p->index];

	if (ret->v_p == NULL)
	    ret->v_p = nmg_construct_vertex(original->v_p, structArray);

	BU_LIST_INSERT(&ret->v_p->vu_hd, &(ret->l));
    }

    if (original->a.magic_p != NULL) {
	switch (*original->a.magic_p) {
	    case NMG_VERTEXUSE_A_PLANE_MAGIC:
		ret->a.plane_p = (struct vertexuse_a_plane *)structArray[original->a.plane_p->index];
		if (ret->a.plane_p == NULL)
		    ret->a.plane_p = nmg_construct_vertexuse_a_plane(original->a.plane_p, structArray);
		break;
	    case NMG_VERTEXUSE_A_CNURB_MAGIC:
		ret->a.cnurb_p = (struct vertexuse_a_cnurb *)structArray[original->a.cnurb_p->index];
		if (ret->a.cnurb_p == NULL)
		    ret->a.cnurb_p = nmg_construct_vertexuse_a_cnurb(original->a.cnurb_p, structArray);
		break;
	    default:
		/* FIXME: any more cases? any action to take? */
		break;
	}
    }

    return ret;
}
Exemplo n.º 22
0
void
bubblesort(void)
{
    struct frame *a, *b;

    a = (struct frame *)head.forw;
    while (a->l.forw != &head) {
	b = (struct frame *)a->l.forw;
	if (a->number > b->number) {
	    BU_LIST_DEQUEUE(&b->l);
	    BU_LIST_INSERT(&a->l, &b->l);
	    if (b->l.back != &head) {
		a = (struct frame *)b->l.back;
	    };
	} else {
	    a=(struct frame *)a->l.forw;
	}
    }
}
Exemplo n.º 23
0
/**
 * H I S T O R Y _ R E C O R D
 *
 * Stores the given command with start and finish times in the
 * history vls'es. 'status' is either BRLCAD_OK or BRLCAD_ERROR.
 */
HIDDEN void
cmdhist_record(struct bu_cmdhist_obj *chop, struct bu_vls *cmdp, struct timeval *start, struct timeval *finish, int status)
{
    struct bu_cmdhist *new_hist;
    const char *eol = "\n";

    if (UNLIKELY(BU_STR_EQUAL(bu_vls_addr(cmdp), eol)))
	return;

    BU_ALLOC(new_hist, struct bu_cmdhist);
    bu_vls_init(&new_hist->h_command);
    bu_vls_vlscat(&new_hist->h_command, cmdp);
    new_hist->h_start = *start;
    new_hist->h_finish = *finish;
    new_hist->h_status = status;
    BU_LIST_INSERT(&chop->cho_head.l, &new_hist->l);

    chop->cho_curr = &chop->cho_head;
}
Exemplo n.º 24
0
/*
 *	H I S T O R Y _ R E C O R D
 *
 *	Stores the given command with start and finish times in the
 *	history vls'es.
 */
void
history_record(struct bu_vls *cmdp, struct timeval *start, struct timeval *finish, int status)


    /* Either TCL_OK or TCL_ERROR */
{
    struct bu_cmdhist *new_hist;

    if (strcmp(bu_vls_addr(cmdp), "\n") == 0)
	return;

    new_hist = (struct bu_cmdhist *)bu_malloc(sizeof(struct bu_cmdhist),
					      "mged history");
    bu_vls_init(&(new_hist->h_command));
    bu_vls_vlscat(&(new_hist->h_command), cmdp);
    new_hist->h_start = *start;
    new_hist->h_finish = *finish;
    new_hist->h_status = status;

    /* make sure the list is initialized before attempting to add this entry */
    if (!historyInitialized) {
	historyInit();
    }

    BU_LIST_INSERT(&(histHead.l), &(new_hist->l));

    /* As long as this isn't our first command to record after setting
       up the journal (which would be "journal", which we don't want
       recorded!)... */

#if 0
    if (journalfp != NULL && !firstjournal)
	history_journalize(new_hist);
#endif

    currHist = &histHead;
#if 0
    firstjournal = 0;
#endif
}
Exemplo n.º 25
0
/**
 * string is a literal or a file name
 */
static void
enqueue_script(struct bu_list *qp, int type, char *string)
{
    struct script_rec *srp;
    FILE *cfPtr;
    struct bu_vls str = BU_VLS_INIT_ZERO;

    BU_CK_LIST_HEAD(qp);

    BU_ALLOC(srp, struct script_rec);
    srp->sr_magic = SCRIPT_REC_MAGIC;
    srp->sr_type = type;
    bu_vls_init(&(srp->sr_script));

    /*Check if supplied file name is local or in brlcad's nirt data dir*/
    if (type == READING_FILE) {
	bu_vls_trunc(&str, 0);
	bu_vls_printf(&str, "%s", string);
	cfPtr = fopen(bu_vls_addr(&str), "rb");
	if (cfPtr == NULL) {
	    bu_vls_trunc(&str, 0);
	    bu_vls_printf(&str, "%s/%s.nrt", bu_brlcad_data("nirt", 0), string);
	    cfPtr = fopen(bu_vls_addr(&str), "rb");
	    if (cfPtr != NULL) {
		fclose(cfPtr);
	    } else {
		bu_vls_trunc(&str, 0);
		bu_vls_printf(&str, "%s", string);
	    }
	} else {
	    fclose(cfPtr);
	}
	bu_vls_printf(&(srp->sr_script), "%s", bu_vls_addr(&str));
    } else {
	bu_vls_strcat(&(srp->sr_script), string);
    }
    BU_LIST_INSERT(qp, &(srp->l));
    bu_vls_free(&str);
}
Exemplo n.º 26
0
void
rt_alloc_seg_block(register struct resource *res)
{
    register struct seg *sp;
    size_t bytes;

    RT_CK_RESOURCE(res);

    if (!BU_LIST_IS_INITIALIZED(&res->re_seg)) {
	BU_LIST_INIT(&(res->re_seg));
	bu_ptbl_init(&res->re_seg_blocks, 64, "re_seg_blocks ptbl");
    }
    bytes = bu_malloc_len_roundup(64*sizeof(struct seg));
    sp = (struct seg *)bu_malloc(bytes, "rt_alloc_seg_block()");
    bu_ptbl_ins(&res->re_seg_blocks, (long *)sp);
    while (bytes >= sizeof(struct seg)) {
	sp->l.magic = RT_SEG_MAGIC;
	BU_LIST_INSERT(&(res->re_seg), &(sp->l));
	res->re_seglen++;
	sp++;
	bytes -= sizeof(struct seg);
    }
}
Exemplo n.º 27
0
static bool_t
pars_Argv(int argc, char **argv)
{
    int c;

    /* Parse options. */
    while ((c = bu_getopt(argc, argv, OPT_STRING)) != -1) {
	switch (c) {
	    case 'C':
		color_flag = 1;
		break;
	    case 'M': {
		RGBpixel lo_rgb, hi_rgb;
		int lo_red, lo_grn, lo_blu;
		int hi_red, hi_grn, hi_blu;

		if (sscanf(bu_optarg, "%d %d %d %d %d %d",
			   &lo_red, &lo_grn, &lo_blu,
			   &hi_red, &hi_grn, &hi_blu)
		    < 3) {
		    bu_log("cell-fb: Invalid color-mapping: '%s'\n",
			   bu_optarg);
		    return 0;
		}
		lo_rgb[RED] = lo_red;
		lo_rgb[GRN] = lo_grn;
		lo_rgb[BLU] = lo_blu;
		hi_rgb[RED] = hi_red;
		hi_rgb[GRN] = hi_grn;
		hi_rgb[BLU] = hi_blu;
		fill_colortbl(lo_rgb, hi_rgb);
		break;
	    }
	    case 'F':
		(void) bu_strlcpy(fbfile, bu_optarg, sizeof(fbfile));
		break;
	    case 'N':
		if (sscanf(bu_optarg, "%d", &fb_height) < 1) {
		    bu_log("cell-fb: Invalid frame-buffer height: '%s'\n", bu_optarg);
		    return 0;
		}
		if (fb_height < -1) {
		    bu_log("cell-fb: Frame-buffer height out of range: %d\n", fb_height);
		    return 0;
		}
		break;
	    case 'W':
		if (sscanf(bu_optarg, "%d", &fb_width) < 1) {
		    bu_log("cell-fb: Invalid frame-buffer width: '%s'\n", bu_optarg);
		    return 0;
		}
		if (fb_width < -1) {
		    bu_log("cell-fb: Frame-buffer width out of range: %d\n", fb_width);
		    return 0;
		}
		break;
	    case 'S':
		if (sscanf(bu_optarg, "%d", &fb_height) < 1) {
		    bu_log("cell-fb: Invalid frame-buffer dimension: '%s'\n", bu_optarg);
		    return 0;
		}
		if (fb_height < -1) {
		    bu_log("cell-fb: Frame-buffer dimensions out of range: %d\n",
			   fb_height);
		    return 0;
		}
		fb_width = fb_height;
		break;
	    case 'X':
		if (sscanf(bu_optarg, "%x", &debug_flag) < 1) {
		    bu_log("cell-fb: Invalid debug flag: '%s'\n", bu_optarg);
		    return 0;
		}
		break;
	    case 'a': {
		fastf_t h;
		fastf_t v;
		double scan[2];
		struct locrec *lrp;

		if (sscanf(bu_optarg, "%lf %lf", &scan[0], &scan[1]) != 2) {
		    bu_log("cell-fb: Invalid grid-plane location: '%s'\n", bu_optarg);
		    return 0;
		}
		/* double to fastf_t */
		h = scan[0];
		v = scan[1];
		lrp = mk_locrec(h, v);
		BU_LIST_INSERT(&(gp_locs.l), &(lrp->l));
	    }
		break;
	    case 'b':
		if (sscanf(bu_optarg, "%lf", &bool_val) != 1) {
		    bu_log("cell-fb: Invalid boolean value: '%s'\n", bu_optarg);
		    return 0;
		}
		boolean_flag = 1;
		break;
	    case 'c':
		if (sscanf(bu_optarg, "%lf", &cell_size) != 1) {
		    bu_log("cell-fb: Invalid cell size: '%s'\n", bu_optarg);
		    return 0;
		}
		if (cell_size <= 0) {
		    bu_log("cell-fb: Cell size out of range: %lf\n", cell_size);
		    return 0;
		}
		break;
	    case 'd':
		if (sscanf(bu_optarg, "%lf %lf", &dom_min, &dom_max) < 2) {
		    bu_log("cell-fb: Invalid domain for input: '%s'\n", bu_optarg);
		    return 0;
		}
		if (dom_min >= dom_max) {
		    bu_log("Bad domain for input: [%lf, %lf]\n",
			   dom_min, dom_max);
		    return 0;
		}
		dom_cvt = 10.0 / (dom_max - dom_min);
		break;
	    case 'e':
		erase_flag = 1;
		break;
	    case 'f':
		if (sscanf(bu_optarg, "%d", &field) != 1) {
		    bu_log("cell-fb: Invalid field: '%s'\n", bu_optarg);
		    return 0;
		}
		break;
	    case 'g':
		grid_flag = 1;
		break;
	    case 'i':
		interp_flag = 0;
		break;
	    case 'k':
		key_flag = 1;
		key_height = 2.5;
		break;
	    case 'l':
		if (sscanf(bu_optarg, "%lf%lf", &az, &el) != 2) {
		    bu_log("cell-fb: Invalid view: '%s'\n", bu_optarg);
		    return 0;
		}
		log_flag = 1;
		if (view_flag == 0)
		    view_flag = 1;
		break;
	    case 'm': {
		double value;
		RGBpixel rgb;
		int red, grn, blu;
		int idx;

		if (sscanf(bu_optarg, "%lf %d %d %d", &value, &red, &grn, &blu)
		    < 4) {
		    bu_log("cell-fb: Invalid color-mapping: '%s'\n", bu_optarg);
		    return 0;
		}
		value *= 10.0;
		idx = value + 0.01;
		if (idx < 0 || idx > MAX_COLORTBL) {
		    bu_log("Value out of range (%s)\n", bu_optarg);
		    return 0;
		}
		rgb[RED] = red;
		rgb[GRN] = grn;
		rgb[BLU] = blu;
		COPYRGB(colortbl[idx], rgb);
		break;
	    }
	    case 'p':
		switch (sscanf(bu_optarg, "%d %d", &xorigin, &yorigin)) {
		    case 2: break;
		    case 1: yorigin = xorigin; break;
		    default:
			bu_log("cell-fb: Invalid offset: '%s'\n", bu_optarg);
			return 0;
		}
		break;
	    case 's':
		switch (sscanf(bu_optarg, "%d %d", &wid, &hgt)) {
		    case 2: break;
		    case 1: hgt = wid; break;
		    default:
			bu_log("cell-fb: Invalid cell scale: '%s'\n", bu_optarg);
			return 0;
		}
		break;
	    case 'v':
		if (sscanf(bu_optarg, "%d", &view_flag) < 1) {
		    bu_log("cell-fb: Invalid view number: '%s'\n", bu_optarg);
		    return 0;
		}
		if (view_flag == 0)
		    log_flag = 0;
		break;
	    case 'x':
		if (sscanf(bu_optarg, "%x", (unsigned int *)&bu_debug) < 1) {
		    bu_log("cell-fb: Invalid debug flag: '%s'\n", bu_optarg);
		    return 0;
		}
		break;
	    default:
		return 0;
	}
    }

    if (argc == bu_optind + 1) {
	if ((filep = fopen(argv[bu_optind], "rb")) == NULL) {
	    bu_log("Cannot open file '%s'\n", argv[bu_optind]);
	    return 0;
	}
    } else if (argc != bu_optind) {
	bu_log("Too many arguments!\n");
	return 0;
    } else
	filep = stdin;

    /* if fb_height/width has not been set, do snug fit
     * else if fb_height/width set to 0 force loose fit
     * else take user specified dimensions
     */
    compute_fb_height = (fb_height == -1) ? SNUG_FIT :
	(fb_height == 0) ? LOOSE_FIT : 0;
    compute_fb_width = (fb_width == -1) ? SNUG_FIT :
	(fb_width == 0) ? LOOSE_FIT : 0;
    return 1;
}
Exemplo n.º 28
0
/**
 * R T _ P G _ S H O T
 *
 * Function -
 * Shoot a ray at a polygonal object.
 *
 * Returns -
 * 0 MISS
 * >0 HIT
 */
int
rt_pg_shot(struct soltab *stp, struct xray *rp, struct application *ap, struct seg *seghead)
{
    struct tri_specific *trip =
	(struct tri_specific *)stp->st_specific;
#define MAXHITS 128		/* # surfaces hit, must be even */
    struct hit hits[MAXHITS];
    struct hit *hp;
    size_t nhits;

    nhits = 0;
    hp = &hits[0];

    /* consider each face */
    for (; trip; trip = trip->tri_forw) {
	fastf_t dn;		/* Direction dot Normal */
	fastf_t abs_dn;
	fastf_t k;
	fastf_t alpha, beta;
	vect_t wxb;		/* vertex - ray_start */
	vect_t xp;		/* wxb cross ray_dir */

	/*
	 * Ray Direction dot N.  (N is outward-pointing normal)
	 * wn points inwards, and is not unit length.
	 */
	dn = VDOT(trip->tri_wn, rp->r_dir);

	/*
	 * If ray lies directly along the face, (i.e., dot product
	 * is zero), drop this face.
	 */
	abs_dn = dn >= 0.0 ? dn : (-dn);
	if (abs_dn < SQRT_SMALL_FASTF)
	    continue;
	VSUB2(wxb, trip->tri_A, rp->r_pt);
	VCROSS(xp, wxb, rp->r_dir);

	/* Check for exceeding along the one side */
	alpha = VDOT(trip->tri_CA, xp);
	if (dn < 0.0) alpha = -alpha;
	if (alpha < 0.0 || alpha > abs_dn)
	    continue;

	/* Check for exceeding along the other side */
	beta = VDOT(trip->tri_BA, xp);
	if (dn > 0.0) beta = -beta;
	if (beta < 0.0 || beta > abs_dn)
	    continue;
	if (alpha+beta > abs_dn)
	    continue;
	k = VDOT(wxb, trip->tri_wn) / dn;

	/* For hits other than the first one, might check
	 * to see it this is approx. equal to previous one */

	/* If dn < 0, we should be entering the solid.
	 * However, we just assume in/out sorting later will work.
	 * Really should mark and check this!
	 */
	VJOIN1(hp->hit_point, rp->r_pt, k, rp->r_dir);

	/* HIT is within planar face */
	hp->hit_magic = RT_HIT_MAGIC;
	hp->hit_dist = k;
	VMOVE(hp->hit_normal, trip->tri_N);
	hp->hit_surfno = trip->tri_surfno;
	if (++nhits >= MAXHITS) {
	    bu_log("rt_pg_shot(%s): too many hits (%zu)\n", stp->st_name, nhits);
	    break;
	}
	hp++;
    }
    if (nhits == 0)
	return 0;		/* MISS */

    /* Sort hits, Near to Far */
    rt_hitsort(hits, nhits);

    /* Remove duplicate hits.
       We remove one of a pair of hits when they are
       1) close together, and
       2) both "entry" or both "exit" occurrences.
       Two immediate "entry" or two immediate "exit" hits suggest
       that we hit both of two joined faces, while we want to hit only
       one.  An "entry" followed by an "exit" (or vice versa) suggests
       that we grazed an edge, and thus we should leave both
       in the hit list. */

    {
	size_t i, j;

	for (i=0; i<nhits-1; i++) {
	    fastf_t dist;

	    dist = hits[i].hit_dist - hits[i+1].hit_dist;
	    if (NEAR_ZERO(dist, ap->a_rt_i->rti_tol.dist) &&
		VDOT(hits[i].hit_normal, rp->r_dir) *
		VDOT(hits[i+1].hit_normal, rp->r_dir) > 0)
	    {
		for (j=i; j<nhits-1; j++)
		    hits[j] = hits[j+1];
		nhits--;
		i--;
	    }
	}
    }


    if (nhits == 1)
	nhits = 0;

    if (nhits&1) {
	size_t i;
	static int nerrors = 0;		/* message counter */
	/*
	 * If this condition exists, it is almost certainly due to
	 * the dn==0 check above.  Thus, we will make the last
	 * surface rather thin.
	 * This at least makes the
	 * presence of this solid known.  There may be something
	 * better we can do.
	 */

	if (nerrors++ < 6) {
	    bu_log("rt_pg_shot(%s): WARNING %zu hits:\n", stp->st_name, nhits);
	    bu_log("\tray start = (%g %g %g) ray dir = (%g %g %g)\n",
		   V3ARGS(rp->r_pt), V3ARGS(rp->r_dir));
	    for (i=0; i < nhits; i++) {
		point_t tmp_pt;

		VJOIN1(tmp_pt, rp->r_pt, hits[i].hit_dist, rp->r_dir);
		if (VDOT(rp->r_dir, hits[i].hit_normal) < 0.0)
		    bu_log("\tentrance at dist=%f (%g %g %g)\n", hits[i].hit_dist, V3ARGS(tmp_pt));
		else
		    bu_log("\texit at dist=%f (%g %g %g)\n", hits[i].hit_dist, V3ARGS(tmp_pt));
	    }
	}

	if (nhits > 2) {
	    fastf_t dot1, dot2;
	    size_t j;

	    /* likely an extra hit,
	     * look for consecutive entrances or exits */

	    dot2 = 1.0;
	    i = 0;
	    while (i<nhits) {
		dot1 = dot2;
		dot2 = VDOT(rp->r_dir, hits[i].hit_normal);
		if (dot1 > 0.0 && dot2 > 0.0) {
		    /* two consecutive exits,
		     * manufacture an entrance at same distance
		     * as second exit.
		     */
		    for (j=nhits; j>i; j--)
			hits[j] = hits[j-1];	/* struct copy */

		    VREVERSE(hits[i].hit_normal, hits[i].hit_normal);
		    dot2 = VDOT(rp->r_dir, hits[i].hit_normal);
		    nhits++;
		    bu_log("\t\tadding fictitious entry at %f (%s)\n", hits[i].hit_dist, stp->st_name);
		} else if (dot1 < 0.0 && dot2 < 0.0) {
		    /* two consecutive entrances,
		     * manufacture an exit between them.
		     */

		    for (j=nhits; j>i; j--)
			hits[j] = hits[j-1];	/* struct copy */

		    hits[i] = hits[i-1];	/* struct copy */
		    VREVERSE(hits[i].hit_normal, hits[i-1].hit_normal);
		    dot2 = VDOT(rp->r_dir, hits[i].hit_normal);
		    nhits++;
		    bu_log("\t\tadding fictitious exit at %f (%s)\n", hits[i].hit_dist, stp->st_name);
		}
		i++;
	    }

	} else {
	    hits[nhits] = hits[nhits-1];	/* struct copy */
	    VREVERSE(hits[nhits].hit_normal, hits[nhits-1].hit_normal);
	    bu_log("\t\tadding fictitious hit at %f (%s)\n", hits[nhits].hit_dist, stp->st_name);
	    nhits++;
	}
    }

    if (nhits&1) {
	if (nhits < MAXHITS) {
	    hits[nhits] = hits[nhits-1];	/* struct copy */
	    VREVERSE(hits[nhits].hit_normal, hits[nhits-1].hit_normal);
	    bu_log("\t\tadding fictitious hit at %f (%s)\n", hits[nhits].hit_dist, stp->st_name);
	    nhits++;
	} else
	    nhits--;
    }

    /* nhits is even, build segments */
    {
	struct seg *segp;
	size_t i;
	for (i=0; i < nhits; i += 2) {
	    RT_GET_SEG(segp, ap->a_resource);
	    segp->seg_stp = stp;
	    segp->seg_in = hits[i];		/* struct copy */
	    segp->seg_out = hits[i+1];	/* struct copy */
	    BU_LIST_INSERT(&(seghead->l), &(segp->l));
	}
    }
    return nhits;			/* HIT */
}
Exemplo n.º 29
0
static struct shell *
nmg_construct_shell(struct nmgregion *parent, const struct shell *original, void **structArray)
{
    struct shell         *ret;
    const struct faceuse *originalFaceUse;
    const struct loopuse *originalLoopUse;
    const struct edgeuse *originalEdgeUse;

    NMG_GETSTRUCT(ret, shell);

    ret->l.magic = NMG_SHELL_MAGIC;
    ret->r_p     = parent;
    ret->sa_p    = (struct shell_a *)NULL;

    BU_LIST_INIT(&ret->fu_hd);
    BU_LIST_INIT(&ret->lu_hd);
    BU_LIST_INIT(&ret->eu_hd);

    ret->vu_p               = (struct vertexuse *) NULL;
    ret->index              = original->index;
    structArray[ret->index] = ret;

    if (original->sa_p != NULL) {
	const struct shell_a *originalAttributes = original->sa_p;
	struct shell_a       *newAttributes      = (struct shell_a *)structArray[originalAttributes->index];

	if (newAttributes == NULL)
	    newAttributes = nmg_construct_shell_a(originalAttributes, structArray);

	ret->sa_p = newAttributes;
    }

    for (BU_LIST_FOR(originalFaceUse, faceuse, &original->fu_hd)) {
	struct faceuse *newFaceUse = (struct faceuse *)structArray[originalFaceUse->index];

	if (newFaceUse == NULL)
	    newFaceUse = nmg_construct_faceuse(ret, originalFaceUse, structArray);

	BU_LIST_INSERT(&ret->fu_hd, &newFaceUse->l);
    }

    for (BU_LIST_FOR(originalLoopUse, loopuse, &original->lu_hd)) {
	struct loopuse *newLoopUse = (struct loopuse *)structArray[originalLoopUse->index];

	if (newLoopUse == NULL)
	    newLoopUse = nmg_construct_loopuse(ret, originalLoopUse, structArray);

	BU_LIST_INSERT(&ret->lu_hd, &newLoopUse->l);
    }

    for (BU_LIST_FOR(originalEdgeUse, edgeuse, &original->eu_hd)) {
	struct edgeuse *newEdgeUse = (struct edgeuse *)structArray[originalEdgeUse->index];

	if (newEdgeUse == NULL)
	    newEdgeUse = nmg_construct_edgeuse(ret, originalEdgeUse, structArray);

	BU_LIST_INSERT(&ret->eu_hd, &newEdgeUse->l);
    }

    if (original->vu_p != 0) {
	ret->vu_p = (struct vertexuse *)structArray[original->vu_p->index];

	if (ret->vu_p == NULL)
	    ret->vu_p = nmg_construct_vertexuse(ret, original->vu_p, structArray);
    }

    return ret;
}
Exemplo n.º 30
0
static struct loopuse *
nmg_construct_loopuse(void *parent, const struct loopuse *original, void **structArray)
{
    struct loopuse *ret;

    NMG_GETSTRUCT(ret, loopuse);

    ret->l.magic     = NMG_LOOPUSE_MAGIC;
    ret->up.magic_p  = (uint32_t *)parent;
    ret->lumate_p    = (struct loopuse *)NULL;
    ret->orientation = original->orientation;
    ret->l_p         = (struct loop *)NULL;

    BU_LIST_INIT(&ret->down_hd);

    ret->index              = original->index;
    structArray[ret->index] = ret;

    if (original->lumate_p != NULL) {
	ret->lumate_p = (struct loopuse *)structArray[original->lumate_p->index];

	/* because it's tricky to choose the right parent for the mate
	 * wait until it's created and set eumate_p afterwards
	 */
	if (ret->lumate_p != NULL)
	    ret->lumate_p->lumate_p = ret;
    }

    if (original->l_p != NULL) {
	ret->l_p = (struct loop *)structArray[original->l_p->index];

	if (ret->l_p == 0)
	    ret->l_p = nmg_construct_loop(ret, original->l_p, structArray);
    }

    switch (BU_LIST_FIRST_MAGIC(&original->down_hd)) {
	case NMG_VERTEXUSE_MAGIC: {
	    const struct vertexuse *originalVertexUse = BU_LIST_FIRST(vertexuse, &original->down_hd);
	    struct vertexuse       *newVertexUse      = (struct vertexuse *)structArray[originalVertexUse->index];

	    if (newVertexUse == NULL)
		newVertexUse = nmg_construct_vertexuse(ret, originalVertexUse, structArray);

	    BU_LIST_INSERT(&ret->down_hd, &newVertexUse->l);
	}
	    break;
	case NMG_EDGEUSE_MAGIC: {
	    const struct edgeuse *originalEdgeUse;
	    for (BU_LIST_FOR(originalEdgeUse, edgeuse, &original->down_hd)) {
		struct edgeuse *newEdgeUse = (struct edgeuse *)structArray[originalEdgeUse->index];
		if (newEdgeUse == NULL)
		    newEdgeUse = nmg_construct_edgeuse(ret, originalEdgeUse, structArray);
		BU_LIST_INSERT(&ret->down_hd, &newEdgeUse->l);
	    }
	}
	    break;
	default:
	    /* FIXME: any more cases? any action to take? */
	    break;
    }

    return ret;
}