예제 #1
0
파일: poly.c 프로젝트: cogitokat/brlcad
/**
 * R T _ P G _ P L O T _ P O L Y
 *
 * Convert to vlist, draw as polygons.
 */
int
rt_pg_plot_poly(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *UNUSED(tol))
{
    size_t i;
    size_t p;	/* current polygon number */
    struct rt_pg_internal *pgp;

    BU_CK_LIST_HEAD(vhead);
    RT_CK_DB_INTERNAL(ip);
    pgp = (struct rt_pg_internal *)ip->idb_ptr;
    RT_PG_CK_MAGIC(pgp);

    for (p = 0; p < pgp->npoly; p++) {
	struct rt_pg_face_internal *pp;
	vect_t aa, bb, norm;

	pp = &pgp->poly[p];
	if (pp->npts < 3)
	    continue;
	VSUB2(aa, &pp->verts[3*(0)], &pp->verts[3*(1)]);
	VSUB2(bb, &pp->verts[3*(0)], &pp->verts[3*(2)]);
	VCROSS(norm, aa, bb);
	VUNITIZE(norm);
	RT_ADD_VLIST(vhead, norm, BN_VLIST_POLY_START);

	RT_ADD_VLIST(vhead, &pp->verts[3*(pp->npts-1)], BN_VLIST_POLY_MOVE);
	for (i=0; i < pp->npts-1; i++) {
	    RT_ADD_VLIST(vhead, &pp->verts[3*i], BN_VLIST_POLY_DRAW);
	}
	RT_ADD_VLIST(vhead, &pp->verts[3*(pp->npts-1)], BN_VLIST_POLY_END);
    }
    return 0;		/* OK */
}
예제 #2
0
파일: poly.c 프로젝트: cogitokat/brlcad
/**
 * R T _ P G _ I F R E E
 *
 * Free the storage associated with the rt_db_internal version of this solid.
 */
void
rt_pg_ifree(struct rt_db_internal *ip)
{
    struct rt_pg_internal *pgp;
    size_t i;

    RT_CK_DB_INTERNAL(ip);

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

    /*
     * Free storage for each polygon
     */
    for (i=0; i < pgp->npoly; i++) {
	bu_free((char *)pgp->poly[i].verts, "pg verts[]");
	bu_free((char *)pgp->poly[i].norms, "pg norms[]");
    }
    if (pgp->npoly)
	bu_free((char *)pgp->poly, "pg poly[]");
    pgp->magic = 0;			/* sanity */
    pgp->npoly = 0;
    bu_free((char *)pgp, "pg ifree");
    ip->idb_ptr = GENPTR_NULL;	/* sanity */
}
예제 #3
0
파일: poly.c 프로젝트: cogitokat/brlcad
/**
 * R T _ P G _ P L O T
 *
 * Calculate the bounding RPP for a poly
 */
int
rt_pg_bbox(struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *UNUSED(tol))
{
    struct rt_pg_internal *pgp;
    size_t i;
    size_t p;

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

    VSETALL((*min), INFINITY);
    VSETALL((*max), -INFINITY);

    for (p = 0; p < pgp->npoly; p++) {
	vect_t work[3];

	VMOVE(work[0], &pgp->poly[p].verts[0*3]);
	VMINMAX((*min), (*max), work[0]);
	VMOVE(work[1], &pgp->poly[p].verts[1*3]);
	VMINMAX((*min), (*max), work[1]);

	for (i=2; i < pgp->poly[p].npts; i++) {
	    VMOVE(work[2], &pgp->poly[p].verts[i*3]);
	    VMINMAX((*min), (*max), work[2]);

	    /* Chop off a triangle, and continue */
	    VMOVE(work[1], work[2]);
	}
    }

    return 0;		/* OK */
}
예제 #4
0
파일: poly.c 프로젝트: cogitokat/brlcad
/**
 * R T _ P G _ P L O T
 */
int
rt_pg_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *UNUSED(tol), const struct rt_view_info *UNUSED(info))
{
    size_t i;
    size_t p;	/* current polygon number */
    struct rt_pg_internal *pgp;

    BU_CK_LIST_HEAD(vhead);
    RT_CK_DB_INTERNAL(ip);
    pgp = (struct rt_pg_internal *)ip->idb_ptr;
    RT_PG_CK_MAGIC(pgp);

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

	pp = &pgp->poly[p];
	RT_ADD_VLIST(vhead, &pp->verts[3*(pp->npts-1)],
		     BN_VLIST_LINE_MOVE);
	for (i=0; i < pp->npts; i++) {
	    RT_ADD_VLIST(vhead, &pp->verts[3*i],
			 BN_VLIST_LINE_DRAW);
	}
    }
    return 0;		/* OK */
}
예제 #5
0
파일: poly.c 프로젝트: cogitokat/brlcad
/**
 * R T _ P G _ P R E P
 *
 * This routine is used to prepare a list of planar faces for
 * being shot at by the triangle routines.
 *
 * Process a PG, which is represented as a vector
 * from the origin to the first point, and many vectors
 * from the first point to the remaining points.
 *
 */
int
rt_pg_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
{
    struct rt_pg_internal *pgp;
    size_t i;
    size_t p;

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

    if (rt_pg_bbox(ip, &(stp->st_min), &(stp->st_max), &rtip->rti_tol)) return 1;

    for (p = 0; p < pgp->npoly; p++) {
	vect_t work[3];

	VMOVE(work[0], &pgp->poly[p].verts[0*3]);
	VMOVE(work[1], &pgp->poly[p].verts[1*3]);

	for (i=2; i < pgp->poly[p].npts; i++) {
	    VMOVE(work[2], &pgp->poly[p].verts[i*3]);

	    /* output a face */
	    (void)rt_pgface(stp,
			    work[0], work[1], work[2], &rtip->rti_tol);

	    /* Chop off a triangle, and continue */
	    VMOVE(work[1], work[2]);
	}
    }
    if (stp->st_specific == (genptr_t)0) {
	bu_log("pg(%s):  no faces\n", stp->st_name);
	return -1;		/* BAD */
    }

    {
	fastf_t dx, dy, dz;
	fastf_t f;

	VADD2SCALE(stp->st_center, stp->st_max, stp->st_min, 0.5);

	dx = (stp->st_max[X] - stp->st_min[X])/2;
	f = dx;
	dy = (stp->st_max[Y] - stp->st_min[Y])/2;
	if (dy > f) f = dy;
	dz = (stp->st_max[Z] - stp->st_min[Z])/2;
	if (dz > f) f = dz;
	stp->st_aradius = f;
	stp->st_bradius = sqrt(dx*dx + dy*dy + dz*dz);
    }

    return 0;		/* OK */
}
예제 #6
0
파일: poly.c 프로젝트: cogitokat/brlcad
/**
 * R T _ P G _ D E S C R I B E
 *
 * Make human-readable formatted presentation of this solid.
 * First line describes type of solid.
 * Additional lines are indented one tab, and give parameter values.
 */
int
rt_pg_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
{
    size_t i, j;
    struct rt_pg_internal *pgp = (struct rt_pg_internal *)ip->idb_ptr;
    char buf[256] = {0};

    RT_PG_CK_MAGIC(pgp);
    bu_vls_strcat(str, "polygon solid with no topology (POLY)\n");

    sprintf(buf, "\t%ld polygons (faces)\n",
	    (long int)pgp->npoly);
    bu_vls_strcat(str, buf);

    sprintf(buf, "\tMost complex face has %lu vertices\n", (long unsigned)pgp->max_npts);
    bu_vls_strcat(str, buf);

    if (pgp->npoly) {
	sprintf(buf, "\tFirst vertex (%g, %g, %g)\n",
		INTCLAMP(pgp->poly[0].verts[X] * mm2local),
		INTCLAMP(pgp->poly[0].verts[Y] * mm2local),
		INTCLAMP(pgp->poly[0].verts[Z] * mm2local));
	bu_vls_strcat(str, buf);
    }

    if (!verbose) return 0;

    /* Print out all the vertices of all the faces */
    for (i=0; i < pgp->npoly; i++) {
	fastf_t *v = pgp->poly[i].verts;
	fastf_t *n = pgp->poly[i].norms;

	sprintf(buf, "\tPolygon %lu: (%lu pts)\n", (long unsigned)i, (long unsigned)pgp->poly[i].npts);
	bu_vls_strcat(str, buf);
	for (j=0; j < pgp->poly[i].npts; j++) {
	    sprintf(buf, "\t\tV (%g, %g, %g)\n\t\t N (%g, %g, %g)\n",
		    INTCLAMP(v[X] * mm2local),
		    INTCLAMP(v[Y] * mm2local),
		    INTCLAMP(v[Z] * mm2local),
		    INTCLAMP(n[X] * mm2local),
		    INTCLAMP(n[Y] * mm2local),
		    INTCLAMP(n[Z] * mm2local));
	    bu_vls_strcat(str, buf);
	    v += ELEMENTS_PER_VECT;
	    n += ELEMENTS_PER_VECT;
	}
    }

    return 0;
}
예제 #7
0
파일: poly.c 프로젝트: cogitokat/brlcad
/**
 * R T _ P G _ E X P O R T
 *
 * The name will be added by the caller.
 * Generally, only libwdb will set conv2mm != 1.0
 */
int
rt_pg_export4(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
{
    struct rt_pg_internal *pgp;
    union record *rec;
    size_t i;
    size_t rno;		/* current record number */
    size_t p;		/* current polygon index */

    if (dbip) RT_CK_DBI(dbip);

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

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

    rec[0].p.p_id = ID_P_HEAD;

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

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

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

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

    return 0;
}
예제 #8
0
/*
 * Default keypoint in model space is established in "pt". Returns
 * GED_ERROR if unable to determine a keypoint, otherwise returns
 * GED_OK.
 */
int
_ged_get_solid_keypoint(struct ged *const gedp,
			fastf_t *const pt,
			const struct rt_db_internal *const ip,
			const fastf_t *const mat)
{
    point_t mpt;

    RT_CK_DB_INTERNAL(ip);

    switch (ip->idb_type) {
	case ID_CLINE:
	    {
		struct rt_cline_internal *cli =
		    (struct rt_cline_internal *)ip->idb_ptr;

		RT_CLINE_CK_MAGIC(cli);

		VMOVE(mpt, cli->v);
		break;
	    }
	case ID_PARTICLE:
	    {
		struct rt_part_internal *part =
		    (struct rt_part_internal *)ip->idb_ptr;

		RT_PART_CK_MAGIC(part);

		VMOVE(mpt, part->part_V);
		break;
	    }
	case ID_PIPE:
	    {
		struct rt_pipe_internal *pipeip;
		struct wdb_pipept *pipe_seg;

		pipeip = (struct rt_pipe_internal *)ip->idb_ptr;

		RT_PIPE_CK_MAGIC(pipeip);

		pipe_seg = BU_LIST_FIRST(wdb_pipept, &pipeip->pipe_segs_head);
		VMOVE(mpt, pipe_seg->pp_coord);
		break;
	    }
	case ID_METABALL:
	    {
		struct rt_metaball_internal *metaball =
		    (struct rt_metaball_internal *)ip->idb_ptr;
		struct wdb_metaballpt *metaballpt;

		RT_METABALL_CK_MAGIC(metaball);

		VSETALL(mpt, 0.0);
		metaballpt = BU_LIST_FIRST(wdb_metaballpt,
					   &metaball->metaball_ctrl_head);
		VMOVE(mpt, metaballpt->coord);
		break;
	    }
	case ID_ARBN:
	    {
		struct rt_arbn_internal *arbn =
		    (struct rt_arbn_internal *)ip->idb_ptr;
		size_t i, j, k;
		int good_vert = 0;

		RT_ARBN_CK_MAGIC(arbn);
		for (i = 0; i < arbn->neqn; i++) {
		    for (j = i + 1; j < arbn->neqn; j++) {
			for (k = j + 1; k < arbn->neqn; k++) {
			    if (!bn_mkpoint_3planes(mpt, arbn->eqn[i],
						    arbn->eqn[j],
						    arbn->eqn[k])) {
				size_t l;

				good_vert = 1;
				for (l = 0; l < arbn->neqn; l++) {
				    if (l == i || l == j || l == k)
					continue;

				    if (DIST_PT_PLANE(mpt,
					arbn->eqn[l]) >
					gedp->ged_wdbp->wdb_tol.dist) {
					good_vert = 0;
					break;
				    }
				}

				if (good_vert)
				    break;
			    }
			}
			if (good_vert)
			    break;
		    }
		    if (good_vert)
			break;
		}

		break;
	    }
	case ID_EBM:
	    {
		struct rt_ebm_internal *ebm =
		    (struct rt_ebm_internal *)ip->idb_ptr;
		point_t pnt;

		RT_EBM_CK_MAGIC(ebm);

		VSETALL(pnt, 0.0);
		MAT4X3PNT(mpt, ebm->mat, pnt);
		break;
	    }
	case ID_BOT:
	    {
		struct rt_bot_internal *bot =
		    (struct rt_bot_internal *)ip->idb_ptr;

		    VMOVE(mpt, bot->vertices);
		break;
	    }
	case ID_DSP:
	    {
		struct rt_dsp_internal *dsp =
		    (struct rt_dsp_internal *)ip->idb_ptr;
		point_t pnt;

		RT_DSP_CK_MAGIC(dsp);

		VSETALL(pnt, 0.0);
		MAT4X3PNT(mpt, dsp->dsp_stom, pnt);
		break;
	    }
	case ID_HF:
	    {
		struct rt_hf_internal *hf =
		    (struct rt_hf_internal *)ip->idb_ptr;

		RT_HF_CK_MAGIC(hf);

		VMOVE(mpt, hf->v);
		break;
	    }
	case ID_VOL:
	    {
		struct rt_vol_internal *vol =
		    (struct rt_vol_internal *)ip->idb_ptr;
		point_t pnt;

		RT_VOL_CK_MAGIC(vol);

		VSETALL(pnt, 0.0);
		MAT4X3PNT(mpt, vol->mat, pnt);
		break;
	    }
	case ID_HALF:
	    {
		struct rt_half_internal *haf =
		    (struct rt_half_internal *)ip->idb_ptr;
		RT_HALF_CK_MAGIC(haf);

		VSCALE(mpt, haf->eqn, haf->eqn[H]);
		break;
	    }
	case ID_ARB8:
	    {
		struct rt_arb_internal *arb =
		    (struct rt_arb_internal *)ip->idb_ptr;
		RT_ARB_CK_MAGIC(arb);

		VMOVE(mpt, arb->pt[0]);
		break;
	    }
	case ID_ELL:
	case ID_SPH:
	    {
		struct rt_ell_internal *ell =
		    (struct rt_ell_internal *)ip->idb_ptr;
		RT_ELL_CK_MAGIC(ell);

		VMOVE(mpt, ell->v);
		break;
	    }
	case ID_SUPERELL:
	    {
		struct rt_superell_internal *superell =
		    (struct rt_superell_internal *)ip->idb_ptr;
		RT_SUPERELL_CK_MAGIC(superell);

		VMOVE(mpt, superell->v);
		break;
	    }
	case ID_TOR:
	    {
		struct rt_tor_internal *tor =
		    (struct rt_tor_internal *)ip->idb_ptr;
		RT_TOR_CK_MAGIC(tor);

		VMOVE(mpt, tor->v);
		break;
	    }
	case ID_TGC:
	case ID_REC:
	    {
		struct rt_tgc_internal *tgc =
		    (struct rt_tgc_internal *)ip->idb_ptr;
		RT_TGC_CK_MAGIC(tgc);

		VMOVE(mpt, tgc->v);
		break;
	    }
	case ID_GRIP:
	    {
		struct rt_grip_internal *gip =
		    (struct rt_grip_internal *)ip->idb_ptr;
		RT_GRIP_CK_MAGIC(gip);
		VMOVE(mpt, gip->center);
		break;
	    }
	case ID_ARS:
	    {
		struct rt_ars_internal *ars =
		    (struct rt_ars_internal *)ip->idb_ptr;
		RT_ARS_CK_MAGIC(ars);

		VMOVE(mpt, &ars->curves[0][0]);
		break;
	    }
	case ID_RPC:
	    {
		struct rt_rpc_internal *rpc =
		    (struct rt_rpc_internal *)ip->idb_ptr;
		RT_RPC_CK_MAGIC(rpc);

		VMOVE(mpt, rpc->rpc_V);
		break;
	    }
	case ID_RHC:
	    {
		struct rt_rhc_internal *rhc =
		    (struct rt_rhc_internal *)ip->idb_ptr;
		RT_RHC_CK_MAGIC(rhc);

		VMOVE(mpt, rhc->rhc_V);
		break;
	    }
	case ID_EPA:
	    {
		struct rt_epa_internal *epa =
		    (struct rt_epa_internal *)ip->idb_ptr;
		RT_EPA_CK_MAGIC(epa);

		VMOVE(mpt, epa->epa_V);
		break;
	    }
	case ID_EHY:
	    {
		struct rt_ehy_internal *ehy =
		    (struct rt_ehy_internal *)ip->idb_ptr;
		RT_EHY_CK_MAGIC(ehy);

		VMOVE(mpt, ehy->ehy_V);
		break;
	    }
	case ID_HYP:
	    {
		struct rt_hyp_internal *hyp =
		    (struct rt_hyp_internal *)ip->idb_ptr;
		RT_HYP_CK_MAGIC(hyp);

		VMOVE(mpt, hyp->hyp_Vi);
		break;
	    }
	case ID_ETO:
	    {
		struct rt_eto_internal *eto =
		    (struct rt_eto_internal *)ip->idb_ptr;
		RT_ETO_CK_MAGIC(eto);

		VMOVE(mpt, eto->eto_V);
		break;
	    }
	case ID_POLY:
	    {
		struct rt_pg_face_internal *_poly;
		struct rt_pg_internal *pg =
		    (struct rt_pg_internal *)ip->idb_ptr;
		RT_PG_CK_MAGIC(pg);

		_poly = pg->poly;
		VMOVE(mpt, _poly->verts);
		break;
	    }
	case ID_SKETCH:
	    {
		struct rt_sketch_internal *skt =
		    (struct rt_sketch_internal *)ip->idb_ptr;
		RT_SKETCH_CK_MAGIC(skt);

		VMOVE(mpt, skt->V);
		break;
	    }
	case ID_EXTRUDE:
	    {
		struct rt_extrude_internal *extr =
		    (struct rt_extrude_internal *)ip->idb_ptr;
		RT_EXTRUDE_CK_MAGIC(extr);

		if (extr->skt && extr->skt->verts) {
		    VJOIN2(mpt, extr->V, extr->skt->verts[0][0], extr->u_vec,
			   extr->skt->verts[0][1], extr->v_vec);
		} else {
		    VMOVE(mpt, extr->V);
		}
		break;
	    }
	case ID_NMG:
	    {
		struct vertex *v;
		struct vertexuse *vu;
		struct edgeuse *eu;
		struct loopuse *lu;
		struct faceuse *fu;
		struct shell *s;
		struct nmgregion *r;
		struct model *m =
		    (struct model *) ip->idb_ptr;
		NMG_CK_MODEL(m);

		/* set default first */
		VSETALL(mpt, 0.0);

		if (BU_LIST_IS_EMPTY(&m->r_hd))
		    break;

		r = BU_LIST_FIRST(nmgregion, &m->r_hd);
		if (!r)
		    break;
		NMG_CK_REGION(r);

		if (BU_LIST_IS_EMPTY(&r->s_hd))
		    break;

		s = BU_LIST_FIRST(shell, &r->s_hd);
		if (!s)
		    break;
		NMG_CK_SHELL(s);

		if (BU_LIST_IS_EMPTY(&s->fu_hd))
		    fu = (struct faceuse *)NULL;
		else
		    fu = BU_LIST_FIRST(faceuse, &s->fu_hd);
		if (fu) {
		    NMG_CK_FACEUSE(fu);
		    lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
		    NMG_CK_LOOPUSE(lu);
		    if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC) {
			eu = BU_LIST_FIRST(edgeuse, &lu->down_hd);
			NMG_CK_EDGEUSE(eu);
			NMG_CK_VERTEXUSE(eu->vu_p);
			v = eu->vu_p->v_p;
		    } else {
			vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
			NMG_CK_VERTEXUSE(vu);
			v = vu->v_p;
		    }
		    NMG_CK_VERTEX(v);
		    if (!v->vg_p)
			break;
		    VMOVE(mpt, v->vg_p->coord);
		    break;
		}
		if (BU_LIST_IS_EMPTY(&s->lu_hd))
		    lu = (struct loopuse *)NULL;
		else
		    lu = BU_LIST_FIRST(loopuse, &s->lu_hd);
		if (lu) {
		    NMG_CK_LOOPUSE(lu);
		    if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC) {
			eu = BU_LIST_FIRST(edgeuse, &lu->down_hd);
			NMG_CK_EDGEUSE(eu);
			NMG_CK_VERTEXUSE(eu->vu_p);
			v = eu->vu_p->v_p;
		    } else {
			vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
			NMG_CK_VERTEXUSE(vu);
			v = vu->v_p;
		    }
		    NMG_CK_VERTEX(v);
		    if (!v->vg_p)
			break;
		    VMOVE(mpt, v->vg_p->coord);
		    break;
		}
		if (BU_LIST_IS_EMPTY(&s->eu_hd))
		    eu = (struct edgeuse *)NULL;
		else
		    eu = BU_LIST_FIRST(edgeuse, &s->eu_hd);
		if (eu) {
		    NMG_CK_EDGEUSE(eu);
		    NMG_CK_VERTEXUSE(eu->vu_p);
		    v = eu->vu_p->v_p;
		    NMG_CK_VERTEX(v);
		    if (!v->vg_p)
			break;
		    VMOVE(mpt, v->vg_p->coord);
		    break;
		}
		vu = s->vu_p;
		if (vu) {
		    NMG_CK_VERTEXUSE(vu);
		    v = vu->v_p;
		    NMG_CK_VERTEX(v);
		    if (!v->vg_p)
			break;
		    VMOVE(mpt, v->vg_p->coord);
		    break;
		}
	    }
	default:
	    VSETALL(mpt, 0.0);
	    bu_vls_printf(gedp->ged_result_str,
			  "get_solid_keypoint: unrecognized solid type");
	    return GED_ERROR;
    }
    MAT4X3PNT(pt, mat, mpt);
    return GED_OK;
}
예제 #9
0
파일: poly.c 프로젝트: cogitokat/brlcad
/**
 * R T _ P G _ T O _ B O T
 *
 * Convert in-memory form of a polysolid (pg) to a bag of triangles (BoT)
 * There is no record in the V5 database for a polysolid.
 *
 * Depends on the "max_npts" parameter having been set.
 *
 * Returns -
 * -1 FAIL
 * 0 OK
 */
int
rt_pg_to_bot(struct rt_db_internal *ip, const struct bn_tol *tol, struct resource *resp)
{
    struct rt_pg_internal *ip_pg;
    struct rt_bot_internal *ip_bot;
    size_t max_pts;
    size_t max_tri;
    size_t p;
    size_t i;

    RT_CK_DB_INTERNAL(ip);
    BN_CK_TOL(tol);
    RT_CK_RESOURCE(resp);

    if (ip->idb_type != ID_POLY) {
	bu_log("ERROR: rt_pt_to_bot() called with a non-polysolid!!!\n");
	return -1;
    }
    ip_pg = (struct rt_pg_internal *)ip->idb_ptr;

    RT_PG_CK_MAGIC(ip_pg);

    BU_ALLOC(ip_bot, struct rt_bot_internal);
    ip_bot->magic = RT_BOT_INTERNAL_MAGIC;
    ip_bot->mode = RT_BOT_SOLID;
    ip_bot->orientation = RT_BOT_CCW;
    ip_bot->bot_flags = 0;

    /* maximum possible vertices */
    max_pts = ip_pg->npoly * ip_pg->max_npts;
    BU_ASSERT_SIZE_T(max_pts, >, 0);

    /* maximum possible triangular faces */
    max_tri = ip_pg->npoly * 3;
    BU_ASSERT_SIZE_T(max_tri, >, 0);

    ip_bot->num_vertices = 0;
    ip_bot->num_faces = 0;
    ip_bot->thickness = (fastf_t *)NULL;
    ip_bot->face_mode = (struct bu_bitv *)NULL;

    ip_bot->vertices = (fastf_t *)bu_calloc(max_pts * 3, sizeof(fastf_t), "BOT vertices");
    ip_bot->faces = (int *)bu_calloc(max_tri * 3, sizeof(int), "BOT faces");

    for (p=0; p<ip_pg->npoly; p++) {
	vect_t work[3], tmp;
	struct tri_specific trip;
	fastf_t m1, m2, m3, m4;
	size_t v0=0, v2=0;
	int first;

	first = 1;
	VMOVE(work[0], &ip_pg->poly[p].verts[0*3]);
	VMOVE(work[1], &ip_pg->poly[p].verts[1*3]);

	for (i=2; i < ip_pg->poly[p].npts; i++) {
	    VMOVE(work[2], &ip_pg->poly[p].verts[i*3]);

	    VSUB2(trip.tri_BA, work[1], work[0]);
	    VSUB2(trip.tri_CA, work[2], work[0]);
	    VCROSS(trip.tri_wn, trip.tri_BA, trip.tri_CA);

	    /* Check to see if this plane is a line or pnt */
	    m1 = MAGNITUDE(trip.tri_BA);
	    m2 = MAGNITUDE(trip.tri_CA);
	    VSUB2(tmp, work[1], work[2]);
	    m3 = MAGNITUDE(tmp);
	    m4 = MAGNITUDE(trip.tri_wn);
	    if (m1 >= tol->dist && m2 >= tol->dist &&
		m3 >= tol->dist && m4 >= tol->dist) {

		/* add this triangle to the BOT */
		if (first) {
		    ip_bot->faces[ip_bot->num_faces * 3] = ip_bot->num_vertices;
		    VMOVE(&ip_bot->vertices[ip_bot->num_vertices * 3], work[0]);
		    v0 = ip_bot->num_vertices;
		    ip_bot->num_vertices++;

		    ip_bot->faces[ip_bot->num_faces * 3 + 1] = ip_bot->num_vertices;
		    VMOVE(&ip_bot->vertices[ip_bot->num_vertices * 3], work[1]);
		    ip_bot->num_vertices++;
		    first = 0;
		} else {
		    ip_bot->faces[ip_bot->num_faces * 3] = v0;
		    ip_bot->faces[ip_bot->num_faces * 3 + 1] = v2;
		}
		VMOVE(&ip_bot->vertices[ip_bot->num_vertices * 3], work[2]);
		ip_bot->faces[ip_bot->num_faces * 3 + 2] = ip_bot->num_vertices;
		v2 = ip_bot->num_vertices;
		ip_bot->num_vertices++;

		ip_bot->num_faces++;
	    }

	    /* Chop off a triangle, and continue */
	    VMOVE(work[1], work[2]);
	}
    }

    rt_bot_vertex_fuse(ip_bot, tol);
    rt_bot_face_fuse(ip_bot);

    rt_db_free_internal(ip);

    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_BOT;
    ip->idb_meth = &rt_functab[ID_BOT];
    ip->idb_ptr = ip_bot;

    return 0;
}
예제 #10
0
파일: poly.c 프로젝트: cogitokat/brlcad
/**
 * R T _ P G _ T E S S
 */
int
rt_pg_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *tol)
{
    size_t i;
    struct shell *s;
    struct vertex **verts;	/* dynamic array of pointers */
    struct vertex ***vertp;/* dynamic array of ptrs to pointers */
    struct faceuse *fu;
    size_t p;	/* current polygon number */
    struct rt_pg_internal *pgp;

    RT_CK_DB_INTERNAL(ip);
    pgp = (struct rt_pg_internal *)ip->idb_ptr;
    RT_PG_CK_MAGIC(pgp);

    *r = nmg_mrsv(m);	/* Make region, empty shell, vertex */
    s = BU_LIST_FIRST(shell, &(*r)->s_hd);

    verts = (struct vertex **)bu_malloc(
	pgp->max_npts * sizeof(struct vertex *), "pg_tess verts[]");
    vertp = (struct vertex ***)bu_malloc(
	pgp->max_npts * sizeof(struct vertex **), "pg_tess vertp[]");
    for (i=0; i < pgp->max_npts; i++)
	vertp[i] = &verts[i];

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

	pp = &pgp->poly[p];

	/* Locate these points, if previously mentioned */
	for (i=0; i < pp->npts; i++) {
	    verts[i] = nmg_find_pt_in_shell(s,
					    &pp->verts[3*i], tol);
	}

	/* Construct the face.  Verts should be in CCW order */
	if ((fu = nmg_cmface(s, vertp, pp->npts)) == (struct faceuse *)0) {
	    bu_log("rt_pg_tess() nmg_cmface failed, skipping face %zu\n",
		   p);
	}

	/* Associate vertex geometry, where none existed before */
	for (i=0; i < pp->npts; i++) {
	    if (verts[i]->vg_p) continue;
	    nmg_vertex_gv(verts[i], &pp->verts[3*i]);
	}

	/* Associate face geometry */
	if (nmg_calc_face_g(fu)) {
	    nmg_pr_fu_briefly(fu, "");
	    bu_free((char *)verts, "pg_tess verts[]");
	    bu_free((char *)vertp, "pg_tess vertp[]");
	    return -1;			/* FAIL */
	}
    }

    /* Compute "geometry" for region and shell */
    nmg_region_a(*r, tol);

    /* Polysolids are often built with incorrect face normals.
     * Don't depend on them here.
     */
    nmg_fix_normals(s, tol);
    bu_free((char *)verts, "pg_tess verts[]");
    bu_free((char *)vertp, "pg_tess vertp[]");

    return 0;		/* OK */
}
예제 #11
0
/**
 * Given a pointer to an internal GED database object, mirror the
 * object's values about the given transformation matrix.
 */
int
rt_nurb_mirror(struct rt_db_internal *ip, register const plane_t plane)
{
    struct rt_nurb_internal *nurb;

    mat_t mirmat;
    mat_t rmat;
    mat_t temp;
    vect_t nvec;
    vect_t xvec;
    vect_t mirror_dir;
    point_t mirror_pt;
    fastf_t ang;

    int i;
    int j;

    static point_t origin = {0.0, 0.0, 0.0};

    RT_CK_DB_INTERNAL(ip);

    nurb = (struct rt_nurb_internal *)ip->idb_ptr;
    RT_PG_CK_MAGIC(nurb);

    MAT_IDN(mirmat);

    VMOVE(mirror_dir, plane);
    VSCALE(mirror_pt, plane, plane[W]);

    /* Build mirror transform matrix, for those who need it. */
    /* First, perform a mirror down the X axis */
    mirmat[0] = -1.0;

    /* Create the rotation matrix */
    VSET(xvec, 1, 0, 0);
    VCROSS(nvec, xvec, mirror_dir);
    VUNITIZE(nvec);
    ang = -acos(VDOT(xvec, mirror_dir));
    bn_mat_arb_rot(rmat, origin, nvec, ang*2.0);

    /* Add the rotation to mirmat */
    MAT_COPY(temp, mirmat);
    bn_mat_mul(mirmat, temp, rmat);

    /* Add the translation to mirmat */
    mirmat[3 + X*4] += mirror_pt[X] * mirror_dir[X];
    mirmat[3 + Y*4] += mirror_pt[Y] * mirror_dir[Y];
    mirmat[3 + Z*4] += mirror_pt[Z] * mirror_dir[Z];

    for (i=0; i<nurb->nsrf; i++) {
	fastf_t *ptr;
	int tmp;
	int orig_size[2];
	int ncoords;
	int m;
	int l;

	/* swap knot vectors between u and v */
	ptr = nurb->srfs[i]->u.knots;
	tmp = nurb->srfs[i]->u.k_size;

	nurb->srfs[i]->u.knots = nurb->srfs[i]->v.knots;
	nurb->srfs[i]->u.k_size = nurb->srfs[i]->v.k_size;
	nurb->srfs[i]->v.knots = ptr;
	nurb->srfs[i]->v.k_size = tmp;

	/* swap order */
	tmp = nurb->srfs[i]->order[0];
	nurb->srfs[i]->order[0] = nurb->srfs[i]->order[1];
	nurb->srfs[i]->order[1] = tmp;

	/* swap mesh size */
	orig_size[0] = nurb->srfs[i]->s_size[0];
	orig_size[1] = nurb->srfs[i]->s_size[1];

	nurb->srfs[i]->s_size[0] = orig_size[1];
	nurb->srfs[i]->s_size[1] = orig_size[0];

	/* allocate memory for a new control mesh */
	ncoords = RT_NURB_EXTRACT_COORDS(nurb->srfs[i]->pt_type);
	ptr = (fastf_t *)bu_calloc(orig_size[0]*orig_size[1]*ncoords, sizeof(fastf_t), "rt_mirror: ctl mesh ptr");

	/* mirror each control point */
	for (j=0; j<orig_size[0]*orig_size[1]; j++) {
	    point_t pt;

	    VMOVE(pt, &nurb->srfs[i]->ctl_points[j*ncoords]);
	    MAT4X3PNT(&nurb->srfs[i]->ctl_points[j*ncoords], mirmat, pt);
	}

	/* copy mirrored control points into new mesh
	 * while swapping u and v */
	m = 0;
	for (j=0; j<orig_size[0]; j++) {
	    for (l=0; l<orig_size[1]; l++) {
		VMOVEN(&ptr[(l*orig_size[0]+j)*ncoords], &nurb->srfs[i]->ctl_points[m*ncoords], ncoords);
		m++;
	    }
	}

	/* free old mesh */
	bu_free((char *)nurb->srfs[i]->ctl_points, "rt_mirror: ctl points");

	/* put new mesh in place */
	nurb->srfs[i]->ctl_points = ptr;
    }

    return 0;
}