Revision: 69029
http://sourceforge.net/p/brlcad/code/69029
Author: starseeker
Date: 2016-10-11 23:30:56 +0000 (Tue, 11 Oct 2016)
Log Message:
-----------
Move more logic that is librt specific into nmg.c
Modified Paths:
--------------
brlcad/trunk/src/librt/primitives/nmg/nmg.c
brlcad/trunk/src/librt/primitives/nmg/nmg_misc.c
Modified: brlcad/trunk/src/librt/primitives/nmg/nmg.c
===================================================================
--- brlcad/trunk/src/librt/primitives/nmg/nmg.c 2016-10-11 23:07:50 UTC (rev
69028)
+++ brlcad/trunk/src/librt/primitives/nmg/nmg.c 2016-10-11 23:30:56 UTC (rev
69029)
@@ -3739,7 +3739,963 @@
return ret;
}
+HIDDEN int
+Shell_is_arb(struct shell *s, struct bu_ptbl *tab, struct bu_list *vlfree)
+{
+ struct faceuse *fu;
+ struct face *f;
+ size_t four_verts=0;
+ size_t three_verts=0;
+ size_t face_count=0;
+ size_t loop_count;
+ NMG_CK_SHELL(s);
+
+ nmg_vertex_tabulate(tab, &s->l.magic, vlfree);
+
+ if (BU_PTBL_LEN(tab) > 8 || BU_PTBL_LEN(tab) < 4)
+ goto not_arb;
+
+ for (BU_LIST_FOR (fu, faceuse, &s->fu_hd)) {
+ struct loopuse *lu;
+ vect_t fu_norm;
+
+ NMG_CK_FACEUSE(fu);
+
+ if (fu->orientation != OT_SAME)
+ continue;
+
+ f = fu->f_p;
+ NMG_CK_FACE(f);
+
+ if (*f->g.magic_p != NMG_FACE_G_PLANE_MAGIC)
+ goto not_arb;
+
+ NMG_GET_FU_NORMAL(fu_norm, fu);
+
+ loop_count = 0;
+ 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)
+ goto not_arb;
+
+ loop_count++;
+
+ /* face must be a single loop */
+ if (loop_count > 1)
+ goto not_arb;
+
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
+ struct edgeuse *eu_radial;
+ struct faceuse *fu_radial;
+ struct face *f_radial;
+ vect_t norm_radial;
+ vect_t eu_dir;
+ vect_t cross;
+ fastf_t dot;
+
+ NMG_CK_EDGEUSE(eu);
+
+ eu_radial = nmg_next_radial_eu(eu, s, 0);
+
+ /* Can't have any dangling faces */
+ if (eu_radial == eu || eu_radial == eu->eumate_p)
+ goto not_arb;
+
+ fu_radial = nmg_find_fu_of_eu(eu_radial);
+ NMG_CK_FACEUSE(fu_radial);
+
+ if (fu_radial->orientation != OT_SAME)
+ fu_radial = fu_radial->fumate_p;
+
+ f_radial = fu_radial->f_p;
+ NMG_CK_FACE(f_radial);
+
+ /* faces must be planar */
+ if (*f_radial->g.magic_p != NMG_FACE_G_PLANE_MAGIC)
+ goto not_arb;
+
+
+ /* Make sure shell is convex by checking that edgeuses
+ * run in direction fu_norm X norm_radial
+ */
+ NMG_GET_FU_NORMAL(norm_radial, fu_radial);
+
+ dot = VDOT(norm_radial, fu_norm);
+
+ if (!NEAR_EQUAL(dot, 1.0, 0.00001)) {
+
+ VCROSS(cross, fu_norm, norm_radial);
+
+ if (eu->orientation == OT_NONE) {
+ VSUB2(eu_dir, eu->vu_p->v_p->vg_p->coord,
eu->eumate_p->vu_p->v_p->vg_p->coord);
+ if (eu->orientation != OT_SAME) {
+ VREVERSE(eu_dir, eu_dir);
+ }
+ } else {
+ VMOVE(eu_dir, eu->g.lseg_p->e_dir);
+ }
+
+ if (eu->orientation == OT_SAME || eu->orientation ==
OT_NONE) {
+ if (VDOT(cross, eu_dir) < 0.0)
+ goto not_arb;
+ } else {
+ if (VDOT(cross, eu_dir) > 0.0)
+ goto not_arb;
+ }
+ }
+ }
+ }
+ }
+
+ /* count face types */
+ for (BU_LIST_FOR (fu, faceuse, &s->fu_hd)) {
+ struct loopuse *lu;
+ int vert_count=0;
+
+ if (fu->orientation != OT_SAME)
+ continue;
+
+ face_count++;
+ for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd)) {
+ struct edgeuse *eu;
+
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd))
+ vert_count++;
+ }
+
+ if (vert_count == 3)
+ three_verts++;
+ else if (vert_count == 4)
+ four_verts++;
+ }
+
+ /* must have only three and four vertices in each face */
+ if (face_count != three_verts + four_verts)
+ goto not_arb;
+
+ /* which type of arb is this?? */
+ switch (BU_PTBL_LEN(tab)) {
+ case 4: /* each face must have 3 vertices */
+ if (three_verts != 4 || four_verts != 0)
+ goto not_arb;
+ break;
+ case 5: /* one face with 4 verts, four with 3 verts */
+ if (four_verts != 1 || three_verts != 4)
+ goto not_arb;
+ break;
+ case 6: /* three faces with 4 verts, two with 3 verts */
+ if (three_verts != 2 || four_verts != 3)
+ goto not_arb;
+ break;
+ case 7: /* four faces with 4 verts, two with 3 verts */
+ if (four_verts != 4 || three_verts != 2)
+ goto not_arb;
+ break;
+ case 8: /* each face must have 4 vertices */
+ if (four_verts != 6 || three_verts != 0)
+ goto not_arb;
+ break;
+ }
+
+ return BU_PTBL_LEN(tab);
+
+
+not_arb:
+ bu_ptbl_free(tab);
+ return 0;
+}
+
+
+
+/**
+ * Converts an NMG to an ARB, if possible.
+ *
+ * NMG must have been coplanar face merged and simplified
+ *
+ * Returns:
+ * 1 - Equivalent ARB was constructed
+ * 0 - Cannot construct an equivalent ARB
+ *
+ * The newly constructed arb is in "arb_int"
+ */
+int
+nmg_to_arb(const struct model *m, struct rt_arb_internal *arb_int)
+{
+ struct nmgregion *r;
+ struct shell *s;
+ struct faceuse *fu;
+ struct loopuse *lu;
+ struct edgeuse *eu;
+ struct vertex *v;
+ struct edgeuse *eu_start;
+ struct faceuse *fu1;
+ struct bu_ptbl tab = BU_PTBL_INIT_ZERO;
+ int face_verts;
+ int i, j;
+ int found;
+ int ret_val = 0;
+
+ NMG_CK_MODEL(m);
+
+ r = BU_LIST_FIRST(nmgregion, &m->r_hd);
+
+ /* must be a single region */
+ if (BU_LIST_NEXT_NOT_HEAD(&r->l, &m->r_hd))
+ return 0;
+
+ s = BU_LIST_FIRST(shell, &r->s_hd);
+ NMG_CK_SHELL(s);
+
+ /* must be a single shell */
+ if (BU_LIST_NEXT_NOT_HEAD(&s->l, &r->s_hd))
+ return 0;
+
+ switch (Shell_is_arb(s, &tab, &RTG.rtg_vlfree)) {
+ case 0:
+ ret_val = 0;
+ break;
+ case 4:
+ v = (struct vertex *)BU_PTBL_GET(&tab, 0);
+ NMG_CK_VERTEX(v);
+ VMOVE(arb_int->pt[0], v->vg_p->coord);
+ v = (struct vertex *)BU_PTBL_GET(&tab, 1);
+ NMG_CK_VERTEX(v);
+ VMOVE(arb_int->pt[1], v->vg_p->coord);
+ v = (struct vertex *)BU_PTBL_GET(&tab, 2);
+ NMG_CK_VERTEX(v);
+ VMOVE(arb_int->pt[2], v->vg_p->coord);
+ VMOVE(arb_int->pt[3], v->vg_p->coord);
+ v = (struct vertex *)BU_PTBL_GET(&tab, 3);
+ NMG_CK_VERTEX(v);
+ VMOVE(arb_int->pt[4], v->vg_p->coord);
+ VMOVE(arb_int->pt[5], v->vg_p->coord);
+ VMOVE(arb_int->pt[6], v->vg_p->coord);
+ VMOVE(arb_int->pt[7], v->vg_p->coord);
+
+ bu_ptbl_free(&tab);
+ ret_val = 1;
+ break;
+ case 5:
+ fu = BU_LIST_FIRST(faceuse, &s->fu_hd);
+ face_verts = 0;
+ while (face_verts != 4) {
+ face_verts = 0;
+ fu = BU_LIST_PNEXT_CIRC(faceuse, &fu->l);
+ lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd))
+ face_verts++;
+ }
+ NMG_CK_FACEUSE(fu);
+ if (fu->orientation != OT_SAME)
+ fu = fu->fumate_p;
+ NMG_CK_FACEUSE(fu);
+
+ lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
+ j = 0;
+ eu_start = BU_LIST_FIRST(edgeuse, &lu->down_hd);
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
+ VMOVE(arb_int->pt[j], eu->vu_p->v_p->vg_p->coord);
+ j++;
+ }
+
+ eu = eu_start->radial_p;
+ eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
+ eu = eu->eumate_p;
+ for (i=0; i<4; i++) {
+ VMOVE(arb_int->pt[j], eu->vu_p->v_p->vg_p->coord);
+ j++;
+ }
+
+ bu_ptbl_free(&tab);
+ ret_val = 1;
+ break;
+ case 6:
+ fu = BU_LIST_FIRST(faceuse, &s->fu_hd);
+ face_verts = 0;
+ while (face_verts != 3) {
+ face_verts = 0;
+ fu = BU_LIST_PNEXT_CIRC(faceuse, &fu->l);
+ lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd))
+ face_verts++;
+ }
+ NMG_CK_FACEUSE(fu);
+ if (fu->orientation != OT_SAME)
+ fu = fu->fumate_p;
+ NMG_CK_FACEUSE(fu);
+
+ lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
+
+ eu_start = BU_LIST_FIRST(edgeuse, &lu->down_hd);
+ eu = eu_start;
+ VMOVE(arb_int->pt[1], eu->vu_p->v_p->vg_p->coord);
+ eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
+ VMOVE(arb_int->pt[0], eu->vu_p->v_p->vg_p->coord);
+ eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
+ VMOVE(arb_int->pt[4], eu->vu_p->v_p->vg_p->coord);
+ VMOVE(arb_int->pt[5], eu->vu_p->v_p->vg_p->coord);
+
+ eu = eu_start->radial_p;
+ eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
+ eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
+ eu = eu->radial_p->eumate_p;
+ VMOVE(arb_int->pt[2], eu->vu_p->v_p->vg_p->coord);
+ eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
+ VMOVE(arb_int->pt[3], eu->vu_p->v_p->vg_p->coord);
+ eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
+ VMOVE(arb_int->pt[6], eu->vu_p->v_p->vg_p->coord);
+ VMOVE(arb_int->pt[7], eu->vu_p->v_p->vg_p->coord);
+
+ bu_ptbl_free(&tab);
+ ret_val = 1;
+ break;
+ case 7:
+ found = 0;
+ fu = BU_LIST_FIRST(faceuse, &s->fu_hd);
+ while (!found) {
+ int verts4=0, verts3=0;
+
+ lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
+ struct loopuse *lu1;
+ struct edgeuse *eu1;
+ int vert_count=0;
+
+ fu1 = nmg_find_fu_of_eu(eu->radial_p);
+ lu1 = BU_LIST_FIRST(loopuse, &fu1->lu_hd);
+ for (BU_LIST_FOR (eu1, edgeuse, &lu1->down_hd))
+ vert_count++;
+
+ if (vert_count == 4)
+ verts4++;
+ else if (vert_count == 3)
+ verts3++;
+ }
+
+ if (verts4 == 2 && verts3 == 2)
+ found = 1;
+ }
+ if (fu->orientation != OT_SAME)
+ fu = fu->fumate_p;
+ NMG_CK_FACEUSE(fu);
+
+ lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
+ j = 0;
+ eu_start = BU_LIST_FIRST(edgeuse, &lu->down_hd);
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
+ VMOVE(arb_int->pt[j], eu->vu_p->v_p->vg_p->coord);
+ j++;
+ }
+
+ eu = eu_start->radial_p;
+ eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
+ eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
+ eu = eu->radial_p->eumate_p;
+ fu1 = nmg_find_fu_of_eu(eu);
+ if (nmg_faces_are_radial(fu, fu1)) {
+ eu = eu_start->radial_p;
+ eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
+ eu = eu->radial_p->eumate_p;
+ }
+ for (i=0; i<4; i++) {
+ VMOVE(arb_int->pt[j], eu->vu_p->v_p->vg_p->coord);
+ j++;
+ eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
+ }
+
+ bu_ptbl_free(&tab);
+ ret_val = 1;
+ break;
+ case 8:
+ fu = BU_LIST_FIRST(faceuse, &s->fu_hd);
+ NMG_CK_FACEUSE(fu);
+ if (fu->orientation != OT_SAME)
+ fu = fu->fumate_p;
+ NMG_CK_FACEUSE(fu);
+
+ lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
+ j = 0;
+ eu_start = BU_LIST_FIRST(edgeuse, &lu->down_hd);
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
+ VMOVE(arb_int->pt[j], eu->vu_p->v_p->vg_p->coord);
+ j++;
+ }
+
+ eu = eu_start->radial_p;
+ eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
+ eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
+ eu = eu->radial_p->eumate_p;
+ for (i=0; i<4; i++) {
+ VMOVE(arb_int->pt[j], eu->vu_p->v_p->vg_p->coord);
+ j++;
+ eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
+ }
+
+ bu_ptbl_free(&tab);
+ ret_val = 1;
+ break;
+ default:
+ bu_bomb("Shell_is_arb screwed up");
+ break;
+ }
+ if (ret_val)
+ arb_int->magic = RT_ARB_INTERNAL_MAGIC;
+ return ret_val;
+}
+
+
+/**
+ * Converts an NMG to a TGC, if possible.
+ *
+ *
+ * NMG must have been coplanar face merged and simplified
+ *
+ * Returns:
+ * 1 - Equivalent TGC was constructed
+ * 0 - Cannot construct an equivalent TGC
+ *
+ * The newly constructed tgc is in "tgc_int"
+ *
+ * Currently only supports RCC, and creates circumscribed RCC
+ */
+int
+nmg_to_tgc(
+ const struct model *m,
+ struct rt_tgc_internal *tgc_int,
+ const struct bn_tol *tol)
+{
+ struct nmgregion *r;
+ struct shell *s;
+ struct faceuse *fu;
+ struct loopuse *lu;
+ struct edgeuse *eu;
+ struct faceuse *fu_base=(struct faceuse *)NULL;
+ struct faceuse *fu_top=(struct faceuse *)NULL;
+ int three_vert_faces=0;
+ int four_vert_faces=0;
+ int many_vert_faces=0;
+ int base_vert_count=0;
+ int top_vert_count=0;
+ point_t sum = VINIT_ZERO;
+ int vert_count=0;
+ fastf_t one_over_vert_count;
+ point_t base_center;
+ fastf_t min_base_r_sq;
+ fastf_t max_base_r_sq;
+ fastf_t sum_base_r_sq;
+ fastf_t ave_base_r_sq;
+ fastf_t base_r;
+ point_t top_center;
+ fastf_t min_top_r_sq;
+ fastf_t max_top_r_sq;
+ fastf_t sum_top_r_sq;
+ fastf_t ave_top_r_sq;
+ fastf_t top_r;
+ plane_t top_pl = HINIT_ZERO;
+ plane_t base_pl = HINIT_ZERO;
+ vect_t plv_1, plv_2;
+
+ NMG_CK_MODEL(m);
+
+ BN_CK_TOL(tol);
+
+ r = BU_LIST_FIRST(nmgregion, &m->r_hd);
+
+ /* must be a single region */
+ if (BU_LIST_NEXT_NOT_HEAD(&r->l, &m->r_hd))
+ return 0;
+
+ s = BU_LIST_FIRST(shell, &r->s_hd);
+ NMG_CK_SHELL(s);
+
+ /* must be a single shell */
+ if (BU_LIST_NEXT_NOT_HEAD(&s->l, &r->s_hd))
+ return 0;
+
+ for (BU_LIST_FOR (fu, faceuse, &s->fu_hd)) {
+ int lu_count=0;
+
+ NMG_CK_FACEUSE(fu);
+ if (fu->orientation != OT_SAME)
+ continue;
+
+ vert_count = 0;
+
+ for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd)) {
+
+ NMG_CK_LOOPUSE(lu);
+
+ if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
+ return 0;
+
+ lu_count++;
+ if (lu_count > 1)
+ return 0;
+
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd))
+ vert_count++;
+ }
+
+ if (vert_count < 3)
+ return 0;
+
+ if (vert_count == 4)
+ four_vert_faces++;
+ else if (vert_count == 3)
+ three_vert_faces++;
+ else {
+ many_vert_faces++;
+ if (many_vert_faces > 2)
+ return 0;
+
+ if (many_vert_faces == 1) {
+ fu_base = fu;
+ base_vert_count = vert_count;
+ NMG_GET_FU_PLANE(base_pl, fu_base);
+ } else if (many_vert_faces == 2) {
+ fu_top = fu;
+ top_vert_count = vert_count;
+ NMG_GET_FU_PLANE(top_pl, fu_top);
+ }
+ }
+ }
+ /* if there are any three vertex faces,
+ * there must be an even number of them
+ */
+ if (three_vert_faces%2)
+ return 0;
+
+ /* base and top must have same number of vertices */
+ if (base_vert_count != top_vert_count)
+ return 0;
+
+ /* Must have correct number of side faces */
+ if ((base_vert_count != four_vert_faces) &&
+ (base_vert_count*2 != three_vert_faces))
+ return 0;
+
+ if (!NEAR_EQUAL(VDOT(top_pl, base_pl), -1.0, tol->perp))
+ return 0;
+
+ /* This looks like a good candidate,
+ * Calculate center of base and top faces
+ */
+
+ if (fu_base) {
+ vert_count = 0;
+ VSETALL(sum, 0.0);
+ lu = BU_LIST_FIRST(loopuse, &fu_base->lu_hd);
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
+ struct vertex_g *vg;
+
+ NMG_CK_EDGEUSE(eu);
+
+ NMG_CK_VERTEXUSE(eu->vu_p);
+ NMG_CK_VERTEX(eu->vu_p->v_p);
+ vg = eu->vu_p->v_p->vg_p;
+ NMG_CK_VERTEX_G(vg);
+
+ VADD2(sum, sum, vg->coord);
+ vert_count++;
+ }
+
+ one_over_vert_count = 1.0/(fastf_t)vert_count;
+ VSCALE(base_center, sum, one_over_vert_count);
+
+ /* Calculate Average Radius */
+ min_base_r_sq = MAX_FASTF;
+ max_base_r_sq = (-min_base_r_sq);
+ sum_base_r_sq = 0.0;
+ lu = BU_LIST_FIRST(loopuse, &fu_base->lu_hd);
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
+ struct vertex_g *vg;
+ vect_t rad_vect;
+ fastf_t r_sq;
+
+ vg = eu->vu_p->v_p->vg_p;
+
+ VSUB2(rad_vect, vg->coord, base_center);
+ r_sq = MAGSQ(rad_vect);
+ if (r_sq > max_base_r_sq)
+ max_base_r_sq = r_sq;
+ if (r_sq < min_base_r_sq)
+ min_base_r_sq = r_sq;
+
+ sum_base_r_sq += r_sq;
+ }
+
+ ave_base_r_sq = sum_base_r_sq * one_over_vert_count;
+
+ base_r = sqrt(max_base_r_sq);
+
+ if (!NEAR_ZERO((max_base_r_sq - ave_base_r_sq)/ave_base_r_sq, 0.001) ||
+ !NEAR_ZERO((min_base_r_sq - ave_base_r_sq)/ave_base_r_sq, 0.001))
+ return 0;
+
+ VSETALL(sum, 0.0);
+ lu = BU_LIST_FIRST(loopuse, &fu_top->lu_hd);
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
+ struct vertex_g *vg;
+
+ NMG_CK_EDGEUSE(eu);
+
+ NMG_CK_VERTEXUSE(eu->vu_p);
+ NMG_CK_VERTEX(eu->vu_p->v_p);
+ vg = eu->vu_p->v_p->vg_p;
+ NMG_CK_VERTEX_G(vg);
+
+ VADD2(sum, sum, vg->coord);
+ }
+
+ VSCALE(top_center, sum, one_over_vert_count);
+
+ /* Calculate Average Radius */
+ min_top_r_sq = MAX_FASTF;
+ max_top_r_sq = (-min_top_r_sq);
+ sum_top_r_sq = 0.0;
+ lu = BU_LIST_FIRST(loopuse, &fu_top->lu_hd);
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
+ struct vertex_g *vg;
+ vect_t rad_vect;
+ fastf_t r_sq;
+
+ vg = eu->vu_p->v_p->vg_p;
+
+ VSUB2(rad_vect, vg->coord, top_center);
+ r_sq = MAGSQ(rad_vect);
+ if (r_sq > max_top_r_sq)
+ max_top_r_sq = r_sq;
+ if (r_sq < min_top_r_sq)
+ min_top_r_sq = r_sq;
+
+ sum_top_r_sq += r_sq;
+ }
+
+ ave_top_r_sq = sum_top_r_sq * one_over_vert_count;
+ top_r = sqrt(max_top_r_sq);
+
+ if (!NEAR_ZERO((max_top_r_sq - ave_top_r_sq)/ave_top_r_sq, 0.001) ||
+ !NEAR_ZERO((min_top_r_sq - ave_top_r_sq)/ave_top_r_sq, 0.001))
+ return 0;
+
+
+ VMOVE(tgc_int->v, base_center);
+ VSUB2(tgc_int->h, top_center, base_center);
+
+ bn_vec_perp(plv_1, top_pl);
+ VCROSS(plv_2, top_pl, plv_1);
+ VUNITIZE(plv_1);
+ VUNITIZE(plv_2);
+ VSCALE(tgc_int->a, plv_1, base_r);
+ VSCALE(tgc_int->b, plv_2, base_r);
+ VSCALE(tgc_int->c, plv_1, top_r);
+ VSCALE(tgc_int->d, plv_2, top_r);
+
+ tgc_int->magic = RT_TGC_INTERNAL_MAGIC;
+
+ }
+
+ return 1;
+}
+
+/**
+ * XXX This routine is deprecated in favor of BoTs
+ */
+int
+nmg_to_poly(const struct model *m, struct rt_pg_internal *poly_int, struct
bu_list *vlfree, const struct bn_tol *tol)
+{
+ struct nmgregion *r;
+ struct shell *s;
+ struct faceuse *fu;
+ struct loopuse *lu;
+ struct edgeuse *eu;
+ struct model *dup_m;
+ struct nmgregion *dup_r;
+ struct shell *dup_s;
+ int max_count;
+ int count_npts;
+ int face_count=0;
+
+ NMG_CK_MODEL(m);
+
+ BN_CK_TOL(tol);
+
+ for (BU_LIST_FOR (r, nmgregion, &m->r_hd)) {
+ for (BU_LIST_FOR (s, shell, &r->s_hd)) {
+ if (nmg_check_closed_shell(s, tol))
+ return 0;
+ }
+ }
+
+ dup_m = nmg_mm();
+ dup_r = nmg_mrsv(dup_m);
+ dup_s = BU_LIST_FIRST(shell, &dup_r->s_hd);
+
+ 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)) {
+ if (fu->orientation != OT_SAME)
+ continue;
+ (void)nmg_dup_face(fu, dup_s);
+ }
+ }
+ }
+
+ for (BU_LIST_FOR (dup_r, nmgregion, &dup_m->r_hd)) {
+ for (BU_LIST_FOR (dup_s, shell, &dup_r->s_hd)) {
+ for (BU_LIST_FOR (fu, faceuse, &dup_s->fu_hd)) {
+ NMG_CK_FACEUSE(fu);
+
+ /* only do OT_SAME faces */
+ if (fu->orientation != OT_SAME)
+ continue;
+
+ /* count vertices in loops */
+ max_count = 0;
+ for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd)) {
+ NMG_CK_LOOPUSE(lu);
+ if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
+ continue;
+
+ if (lu->orientation != OT_SAME) {
+ /* triangulate holes */
+ max_count = 6;
+ break;
+ }
+
+ count_npts = 0;
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd))
+ count_npts++;
+
+ if (count_npts > 5) {
+ max_count = count_npts;
+ break;
+ }
+ if (!nmg_lu_is_convex(lu, vlfree, tol)) {
+ /* triangulate non-convex faces */
+ max_count = 6;
+ break;
+ }
+ }
+
+ /* if any loop has more than 5 vertices, triangulate the face */
+ if (max_count > 5) {
+ if (RTG.NMG_debug & DEBUG_BASIC)
+ bu_log("nmg_to_poly: triangulating fu %p\n", (void
*)fu);
+ nmg_triangulate_fu(fu, vlfree, tol);
+ }
+
+ for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd)) {
+ NMG_CK_LOOPUSE(lu);
+ if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
+ continue;
+
+ face_count++;
+ }
+ }
+ }
+ }
+ poly_int->npoly = face_count;
+ poly_int->poly = (struct rt_pg_face_internal *)bu_calloc(face_count,
+ sizeof(struct
rt_pg_face_internal), "nmg_to_poly: poly");
+
+ face_count = 0;
+ for (BU_LIST_FOR (dup_r, nmgregion, &dup_m->r_hd)) {
+ for (BU_LIST_FOR (dup_s, shell, &dup_r->s_hd)) {
+ for (BU_LIST_FOR (fu, faceuse, &dup_s->fu_hd)) {
+ vect_t norm;
+
+ NMG_CK_FACEUSE(fu);
+
+ /* only do OT_SAME faces */
+ if (fu->orientation != OT_SAME)
+ continue;
+
+ NMG_GET_FU_NORMAL(norm, fu);
+
+ for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd)) {
+ int pt_no=0;
+
+ if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
+ continue;
+
+ /* count vertices in loop */
+ count_npts = 0;
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd))
+ count_npts++;
+
+ poly_int->poly[face_count].npts = count_npts;
+ poly_int->poly[face_count].verts = (fastf_t *)
bu_calloc(3*count_npts, sizeof(fastf_t), "nmg_to_poly: verts");
+ poly_int->poly[face_count].norms = (fastf_t *)
bu_calloc(3*count_npts, sizeof(fastf_t), "nmg_to_poly: norms");
+
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
+ struct vertex_g *vg;
+
+ vg = eu->vu_p->v_p->vg_p;
+ NMG_CK_VERTEX_G(vg);
+
+ VMOVE(&(poly_int->poly[face_count].verts[pt_no*3]),
vg->coord);
+ VMOVE(&(poly_int->poly[face_count].norms[pt_no*3]),
norm);
+
+ pt_no++;
+ }
+ face_count++;
+ }
+ }
+ }
+ }
+
+ poly_int->magic = RT_PG_INTERNAL_MAGIC;
+ nmg_km(dup_m);
+
+ return 1;
+}
+
+/**
+ * Convert an NMG to a BOT solid
+ */
+struct rt_bot_internal *
+nmg_bot(struct shell *s, struct bu_list *vlfree, const struct bn_tol *tol)
+{
+ struct rt_bot_internal *bot;
+ struct bu_ptbl nmg_vertices;
+ struct bu_ptbl nmg_faces;
+ size_t i, face_no;
+ struct vertex *v;
+
+ NMG_CK_SHELL(s);
+ BN_CK_TOL(tol);
+
+ /* first convert the NMG to triangles */
+ (void)nmg_triangulate_shell(s, vlfree, tol);
+
+ /* make a list of all the vertices */
+ nmg_vertex_tabulate(&nmg_vertices, &s->l.magic, vlfree);
+
+ /* and a list of all the faces */
+ nmg_face_tabulate(&nmg_faces, &s->l.magic, vlfree);
+
+ /* now build the BOT */
+ BU_ALLOC(bot, struct rt_bot_internal);
+
+ bot->magic = RT_BOT_INTERNAL_MAGIC;
+ bot->mode = RT_BOT_SOLID;
+ bot->orientation = RT_BOT_CCW;
+ bot->bot_flags = 0;
+
+ bot->num_vertices = BU_PTBL_LEN(&nmg_vertices);
+ bot->num_faces = 0;
+
+ /* count the number of triangles */
+ for (i=0; i<BU_PTBL_LEN(&nmg_faces); i++) {
+ struct face *f;
+ struct faceuse *fu;
+ struct loopuse *lu;
+
+ f = (struct face *)BU_PTBL_GET(&nmg_faces, i);
+ NMG_CK_FACE(f);
+
+ fu = f->fu_p;
+
+ if (fu->orientation != OT_SAME) {
+ fu = fu->fumate_p;
+ if (fu->orientation != OT_SAME) {
+ bu_log("nmg_bot(): Face has no OT_SAME use!\n");
+ bu_free((char *)bot->vertices, "BOT vertices");
+ bu_free((char *)bot->faces, "BOT faces");
+ bu_free((char *)bot, "BOT");
+ return (struct rt_bot_internal *)NULL;
+ }
+ }
+
+ for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd)) {
+ if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
+ continue;
+ bot->num_faces++;
+ }
+ }
+
+ bot->faces = (int *)bu_calloc(bot->num_faces * 3, sizeof(int), "BOT
faces");
+ bot->vertices = (fastf_t *)bu_calloc(bot->num_vertices * 3,
sizeof(fastf_t), "BOT vertices");
+
+ bot->thickness = (fastf_t *)NULL;
+ bot->face_mode = (struct bu_bitv *)NULL;
+
+ /* fill in the vertices */
+ for (i=0; i<BU_PTBL_LEN(&nmg_vertices); i++) {
+ struct vertex_g *vg;
+
+ v = (struct vertex *)BU_PTBL_GET(&nmg_vertices, i);
+ NMG_CK_VERTEX(v);
+
+ vg = v->vg_p;
+ NMG_CK_VERTEX_G(vg);
+
+ VMOVE(&bot->vertices[i*3], vg->coord);
+ }
+
+ /* fill in the faces */
+ face_no = 0;
+ for (i=0; i<BU_PTBL_LEN(&nmg_faces); i++) {
+ struct face *f;
+ struct faceuse *fu;
+ struct loopuse *lu;
+
+ f = (struct face *)BU_PTBL_GET(&nmg_faces, i);
+ NMG_CK_FACE(f);
+
+ fu = f->fu_p;
+
+ if (fu->orientation != OT_SAME) {
+ fu = fu->fumate_p;
+ if (fu->orientation != OT_SAME) {
+ bu_log("nmg_bot(): Face has no OT_SAME use!\n");
+ bu_free((char *)bot->vertices, "BOT vertices");
+ bu_free((char *)bot->faces, "BOT faces");
+ bu_free((char *)bot, "BOT");
+ return (struct rt_bot_internal *)NULL;
+ }
+ }
+
+ for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd)) {
+ struct edgeuse *eu;
+ size_t vertex_no=0;
+
+ if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
+ continue;
+
+ for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
+ if (vertex_no > 2) {
+ bu_log("nmg_bot(): Face has not been triangulated!\n");
+ bu_free((char *)bot->vertices, "BOT vertices");
+ bu_free((char *)bot->faces, "BOT faces");
+ bu_free((char *)bot, "BOT");
+ return (struct rt_bot_internal *)NULL;
+ }
+
+ v = eu->vu_p->v_p;
+ NMG_CK_VERTEX(v);
+
+
+ bot->faces[ face_no*3 + vertex_no ] =
bu_ptbl_locate(&nmg_vertices, (long *)v);
+
+ vertex_no++;
+ }
+
+ face_no++;
+ }
+ }
+
+ bu_ptbl_free(&nmg_vertices);
+ bu_ptbl_free(&nmg_faces);
+
+ return bot;
+}
+
/*
* Local Variables:
* mode: C
Modified: brlcad/trunk/src/librt/primitives/nmg/nmg_misc.c
===================================================================
--- brlcad/trunk/src/librt/primitives/nmg/nmg_misc.c 2016-10-11 23:07:50 UTC
(rev 69028)
+++ brlcad/trunk/src/librt/primitives/nmg/nmg_misc.c 2016-10-11 23:30:56 UTC
(rev 69029)
@@ -9051,671 +9051,7 @@
return break_count;
}
-
-HIDDEN int
-Shell_is_arb(struct shell *s, struct bu_ptbl *tab, struct bu_list *vlfree)
-{
- struct faceuse *fu;
- struct face *f;
- size_t four_verts=0;
- size_t three_verts=0;
- size_t face_count=0;
- size_t loop_count;
-
- NMG_CK_SHELL(s);
-
- nmg_vertex_tabulate(tab, &s->l.magic, vlfree);
-
- if (BU_PTBL_LEN(tab) > 8 || BU_PTBL_LEN(tab) < 4)
- goto not_arb;
-
- for (BU_LIST_FOR (fu, faceuse, &s->fu_hd)) {
- struct loopuse *lu;
- vect_t fu_norm;
-
- NMG_CK_FACEUSE(fu);
-
- if (fu->orientation != OT_SAME)
- continue;
-
- f = fu->f_p;
- NMG_CK_FACE(f);
-
- if (*f->g.magic_p != NMG_FACE_G_PLANE_MAGIC)
- goto not_arb;
-
- NMG_GET_FU_NORMAL(fu_norm, fu);
-
- loop_count = 0;
- 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)
- goto not_arb;
-
- loop_count++;
-
- /* face must be a single loop */
- if (loop_count > 1)
- goto not_arb;
-
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
- struct edgeuse *eu_radial;
- struct faceuse *fu_radial;
- struct face *f_radial;
- vect_t norm_radial;
- vect_t eu_dir;
- vect_t cross;
- fastf_t dot;
-
- NMG_CK_EDGEUSE(eu);
-
- eu_radial = nmg_next_radial_eu(eu, s, 0);
-
- /* Can't have any dangling faces */
- if (eu_radial == eu || eu_radial == eu->eumate_p)
- goto not_arb;
-
- fu_radial = nmg_find_fu_of_eu(eu_radial);
- NMG_CK_FACEUSE(fu_radial);
-
- if (fu_radial->orientation != OT_SAME)
- fu_radial = fu_radial->fumate_p;
-
- f_radial = fu_radial->f_p;
- NMG_CK_FACE(f_radial);
-
- /* faces must be planar */
- if (*f_radial->g.magic_p != NMG_FACE_G_PLANE_MAGIC)
- goto not_arb;
-
-
- /* Make sure shell is convex by checking that edgeuses
- * run in direction fu_norm X norm_radial
- */
- NMG_GET_FU_NORMAL(norm_radial, fu_radial);
-
- dot = VDOT(norm_radial, fu_norm);
-
- if (!NEAR_EQUAL(dot, 1.0, 0.00001)) {
-
- VCROSS(cross, fu_norm, norm_radial);
-
- if (eu->orientation == OT_NONE) {
- VSUB2(eu_dir, eu->vu_p->v_p->vg_p->coord,
eu->eumate_p->vu_p->v_p->vg_p->coord);
- if (eu->orientation != OT_SAME) {
- VREVERSE(eu_dir, eu_dir);
- }
- } else {
- VMOVE(eu_dir, eu->g.lseg_p->e_dir);
- }
-
- if (eu->orientation == OT_SAME || eu->orientation ==
OT_NONE) {
- if (VDOT(cross, eu_dir) < 0.0)
- goto not_arb;
- } else {
- if (VDOT(cross, eu_dir) > 0.0)
- goto not_arb;
- }
- }
- }
- }
- }
-
- /* count face types */
- for (BU_LIST_FOR (fu, faceuse, &s->fu_hd)) {
- struct loopuse *lu;
- int vert_count=0;
-
- if (fu->orientation != OT_SAME)
- continue;
-
- face_count++;
- for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd)) {
- struct edgeuse *eu;
-
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd))
- vert_count++;
- }
-
- if (vert_count == 3)
- three_verts++;
- else if (vert_count == 4)
- four_verts++;
- }
-
- /* must have only three and four vertices in each face */
- if (face_count != three_verts + four_verts)
- goto not_arb;
-
- /* which type of arb is this?? */
- switch (BU_PTBL_LEN(tab)) {
- case 4: /* each face must have 3 vertices */
- if (three_verts != 4 || four_verts != 0)
- goto not_arb;
- break;
- case 5: /* one face with 4 verts, four with 3 verts */
- if (four_verts != 1 || three_verts != 4)
- goto not_arb;
- break;
- case 6: /* three faces with 4 verts, two with 3 verts */
- if (three_verts != 2 || four_verts != 3)
- goto not_arb;
- break;
- case 7: /* four faces with 4 verts, two with 3 verts */
- if (four_verts != 4 || three_verts != 2)
- goto not_arb;
- break;
- case 8: /* each face must have 4 vertices */
- if (four_verts != 6 || three_verts != 0)
- goto not_arb;
- break;
- }
-
- return BU_PTBL_LEN(tab);
-
-
-not_arb:
- bu_ptbl_free(tab);
- return 0;
-}
-
-
/**
- * Converts an NMG to an ARB, if possible.
- *
- * NMG must have been coplanar face merged and simplified
- *
- * Returns:
- * 1 - Equivalent ARB was constructed
- * 0 - Cannot construct an equivalent ARB
- *
- * The newly constructed arb is in "arb_int"
- */
-int
-nmg_to_arb(const struct model *m, struct rt_arb_internal *arb_int)
-{
- struct nmgregion *r;
- struct shell *s;
- struct faceuse *fu;
- struct loopuse *lu;
- struct edgeuse *eu;
- struct vertex *v;
- struct edgeuse *eu_start;
- struct faceuse *fu1;
- struct bu_ptbl tab = BU_PTBL_INIT_ZERO;
- int face_verts;
- int i, j;
- int found;
- int ret_val = 0;
-
- NMG_CK_MODEL(m);
-
- r = BU_LIST_FIRST(nmgregion, &m->r_hd);
-
- /* must be a single region */
- if (BU_LIST_NEXT_NOT_HEAD(&r->l, &m->r_hd))
- return 0;
-
- s = BU_LIST_FIRST(shell, &r->s_hd);
- NMG_CK_SHELL(s);
-
- /* must be a single shell */
- if (BU_LIST_NEXT_NOT_HEAD(&s->l, &r->s_hd))
- return 0;
-
- switch (Shell_is_arb(s, &tab, &RTG.rtg_vlfree)) {
- case 0:
- ret_val = 0;
- break;
- case 4:
- v = (struct vertex *)BU_PTBL_GET(&tab, 0);
- NMG_CK_VERTEX(v);
- VMOVE(arb_int->pt[0], v->vg_p->coord);
- v = (struct vertex *)BU_PTBL_GET(&tab, 1);
- NMG_CK_VERTEX(v);
- VMOVE(arb_int->pt[1], v->vg_p->coord);
- v = (struct vertex *)BU_PTBL_GET(&tab, 2);
- NMG_CK_VERTEX(v);
- VMOVE(arb_int->pt[2], v->vg_p->coord);
- VMOVE(arb_int->pt[3], v->vg_p->coord);
- v = (struct vertex *)BU_PTBL_GET(&tab, 3);
- NMG_CK_VERTEX(v);
- VMOVE(arb_int->pt[4], v->vg_p->coord);
- VMOVE(arb_int->pt[5], v->vg_p->coord);
- VMOVE(arb_int->pt[6], v->vg_p->coord);
- VMOVE(arb_int->pt[7], v->vg_p->coord);
-
- bu_ptbl_free(&tab);
- ret_val = 1;
- break;
- case 5:
- fu = BU_LIST_FIRST(faceuse, &s->fu_hd);
- face_verts = 0;
- while (face_verts != 4) {
- face_verts = 0;
- fu = BU_LIST_PNEXT_CIRC(faceuse, &fu->l);
- lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd))
- face_verts++;
- }
- NMG_CK_FACEUSE(fu);
- if (fu->orientation != OT_SAME)
- fu = fu->fumate_p;
- NMG_CK_FACEUSE(fu);
-
- lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
- j = 0;
- eu_start = BU_LIST_FIRST(edgeuse, &lu->down_hd);
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
- VMOVE(arb_int->pt[j], eu->vu_p->v_p->vg_p->coord);
- j++;
- }
-
- eu = eu_start->radial_p;
- eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
- eu = eu->eumate_p;
- for (i=0; i<4; i++) {
- VMOVE(arb_int->pt[j], eu->vu_p->v_p->vg_p->coord);
- j++;
- }
-
- bu_ptbl_free(&tab);
- ret_val = 1;
- break;
- case 6:
- fu = BU_LIST_FIRST(faceuse, &s->fu_hd);
- face_verts = 0;
- while (face_verts != 3) {
- face_verts = 0;
- fu = BU_LIST_PNEXT_CIRC(faceuse, &fu->l);
- lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd))
- face_verts++;
- }
- NMG_CK_FACEUSE(fu);
- if (fu->orientation != OT_SAME)
- fu = fu->fumate_p;
- NMG_CK_FACEUSE(fu);
-
- lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
-
- eu_start = BU_LIST_FIRST(edgeuse, &lu->down_hd);
- eu = eu_start;
- VMOVE(arb_int->pt[1], eu->vu_p->v_p->vg_p->coord);
- eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
- VMOVE(arb_int->pt[0], eu->vu_p->v_p->vg_p->coord);
- eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
- VMOVE(arb_int->pt[4], eu->vu_p->v_p->vg_p->coord);
- VMOVE(arb_int->pt[5], eu->vu_p->v_p->vg_p->coord);
-
- eu = eu_start->radial_p;
- eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
- eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
- eu = eu->radial_p->eumate_p;
- VMOVE(arb_int->pt[2], eu->vu_p->v_p->vg_p->coord);
- eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
- VMOVE(arb_int->pt[3], eu->vu_p->v_p->vg_p->coord);
- eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
- VMOVE(arb_int->pt[6], eu->vu_p->v_p->vg_p->coord);
- VMOVE(arb_int->pt[7], eu->vu_p->v_p->vg_p->coord);
-
- bu_ptbl_free(&tab);
- ret_val = 1;
- break;
- case 7:
- found = 0;
- fu = BU_LIST_FIRST(faceuse, &s->fu_hd);
- while (!found) {
- int verts4=0, verts3=0;
-
- lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
- struct loopuse *lu1;
- struct edgeuse *eu1;
- int vert_count=0;
-
- fu1 = nmg_find_fu_of_eu(eu->radial_p);
- lu1 = BU_LIST_FIRST(loopuse, &fu1->lu_hd);
- for (BU_LIST_FOR (eu1, edgeuse, &lu1->down_hd))
- vert_count++;
-
- if (vert_count == 4)
- verts4++;
- else if (vert_count == 3)
- verts3++;
- }
-
- if (verts4 == 2 && verts3 == 2)
- found = 1;
- }
- if (fu->orientation != OT_SAME)
- fu = fu->fumate_p;
- NMG_CK_FACEUSE(fu);
-
- lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
- j = 0;
- eu_start = BU_LIST_FIRST(edgeuse, &lu->down_hd);
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
- VMOVE(arb_int->pt[j], eu->vu_p->v_p->vg_p->coord);
- j++;
- }
-
- eu = eu_start->radial_p;
- eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
- eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
- eu = eu->radial_p->eumate_p;
- fu1 = nmg_find_fu_of_eu(eu);
- if (nmg_faces_are_radial(fu, fu1)) {
- eu = eu_start->radial_p;
- eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
- eu = eu->radial_p->eumate_p;
- }
- for (i=0; i<4; i++) {
- VMOVE(arb_int->pt[j], eu->vu_p->v_p->vg_p->coord);
- j++;
- eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
- }
-
- bu_ptbl_free(&tab);
- ret_val = 1;
- break;
- case 8:
- fu = BU_LIST_FIRST(faceuse, &s->fu_hd);
- NMG_CK_FACEUSE(fu);
- if (fu->orientation != OT_SAME)
- fu = fu->fumate_p;
- NMG_CK_FACEUSE(fu);
-
- lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
- j = 0;
- eu_start = BU_LIST_FIRST(edgeuse, &lu->down_hd);
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
- VMOVE(arb_int->pt[j], eu->vu_p->v_p->vg_p->coord);
- j++;
- }
-
- eu = eu_start->radial_p;
- eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
- eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
- eu = eu->radial_p->eumate_p;
- for (i=0; i<4; i++) {
- VMOVE(arb_int->pt[j], eu->vu_p->v_p->vg_p->coord);
- j++;
- eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l);
- }
-
- bu_ptbl_free(&tab);
- ret_val = 1;
- break;
- default:
- bu_bomb("Shell_is_arb screwed up");
- break;
- }
- if (ret_val)
- arb_int->magic = RT_ARB_INTERNAL_MAGIC;
- return ret_val;
-}
-
-
-/**
- * Converts an NMG to a TGC, if possible.
- *
- *
- * NMG must have been coplanar face merged and simplified
- *
- * Returns:
- * 1 - Equivalent TGC was constructed
- * 0 - Cannot construct an equivalent TGC
- *
- * The newly constructed tgc is in "tgc_int"
- *
- * Currently only supports RCC, and creates circumscribed RCC
- */
-int
-nmg_to_tgc(
- const struct model *m,
- struct rt_tgc_internal *tgc_int,
- const struct bn_tol *tol)
-{
- struct nmgregion *r;
- struct shell *s;
- struct faceuse *fu;
- struct loopuse *lu;
- struct edgeuse *eu;
- struct faceuse *fu_base=(struct faceuse *)NULL;
- struct faceuse *fu_top=(struct faceuse *)NULL;
- int three_vert_faces=0;
- int four_vert_faces=0;
- int many_vert_faces=0;
- int base_vert_count=0;
- int top_vert_count=0;
- point_t sum = VINIT_ZERO;
- int vert_count=0;
- fastf_t one_over_vert_count;
- point_t base_center;
- fastf_t min_base_r_sq;
- fastf_t max_base_r_sq;
- fastf_t sum_base_r_sq;
- fastf_t ave_base_r_sq;
- fastf_t base_r;
- point_t top_center;
- fastf_t min_top_r_sq;
- fastf_t max_top_r_sq;
- fastf_t sum_top_r_sq;
- fastf_t ave_top_r_sq;
- fastf_t top_r;
- plane_t top_pl = HINIT_ZERO;
- plane_t base_pl = HINIT_ZERO;
- vect_t plv_1, plv_2;
-
- NMG_CK_MODEL(m);
-
- BN_CK_TOL(tol);
-
- r = BU_LIST_FIRST(nmgregion, &m->r_hd);
-
- /* must be a single region */
- if (BU_LIST_NEXT_NOT_HEAD(&r->l, &m->r_hd))
- return 0;
-
- s = BU_LIST_FIRST(shell, &r->s_hd);
- NMG_CK_SHELL(s);
-
- /* must be a single shell */
- if (BU_LIST_NEXT_NOT_HEAD(&s->l, &r->s_hd))
- return 0;
-
- for (BU_LIST_FOR (fu, faceuse, &s->fu_hd)) {
- int lu_count=0;
-
- NMG_CK_FACEUSE(fu);
- if (fu->orientation != OT_SAME)
- continue;
-
- vert_count = 0;
-
- for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd)) {
-
- NMG_CK_LOOPUSE(lu);
-
- if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
- return 0;
-
- lu_count++;
- if (lu_count > 1)
- return 0;
-
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd))
- vert_count++;
- }
-
- if (vert_count < 3)
- return 0;
-
- if (vert_count == 4)
- four_vert_faces++;
- else if (vert_count == 3)
- three_vert_faces++;
- else {
- many_vert_faces++;
- if (many_vert_faces > 2)
- return 0;
-
- if (many_vert_faces == 1) {
- fu_base = fu;
- base_vert_count = vert_count;
- NMG_GET_FU_PLANE(base_pl, fu_base);
- } else if (many_vert_faces == 2) {
- fu_top = fu;
- top_vert_count = vert_count;
- NMG_GET_FU_PLANE(top_pl, fu_top);
- }
- }
- }
- /* if there are any three vertex faces,
- * there must be an even number of them
- */
- if (three_vert_faces%2)
- return 0;
-
- /* base and top must have same number of vertices */
- if (base_vert_count != top_vert_count)
- return 0;
-
- /* Must have correct number of side faces */
- if ((base_vert_count != four_vert_faces) &&
- (base_vert_count*2 != three_vert_faces))
- return 0;
-
- if (!NEAR_EQUAL(VDOT(top_pl, base_pl), -1.0, tol->perp))
- return 0;
-
- /* This looks like a good candidate,
- * Calculate center of base and top faces
- */
-
- if (fu_base) {
- vert_count = 0;
- VSETALL(sum, 0.0);
- lu = BU_LIST_FIRST(loopuse, &fu_base->lu_hd);
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
- struct vertex_g *vg;
-
- NMG_CK_EDGEUSE(eu);
-
- NMG_CK_VERTEXUSE(eu->vu_p);
- NMG_CK_VERTEX(eu->vu_p->v_p);
- vg = eu->vu_p->v_p->vg_p;
- NMG_CK_VERTEX_G(vg);
-
- VADD2(sum, sum, vg->coord);
- vert_count++;
- }
-
- one_over_vert_count = 1.0/(fastf_t)vert_count;
- VSCALE(base_center, sum, one_over_vert_count);
-
- /* Calculate Average Radius */
- min_base_r_sq = MAX_FASTF;
- max_base_r_sq = (-min_base_r_sq);
- sum_base_r_sq = 0.0;
- lu = BU_LIST_FIRST(loopuse, &fu_base->lu_hd);
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
- struct vertex_g *vg;
- vect_t rad_vect;
- fastf_t r_sq;
-
- vg = eu->vu_p->v_p->vg_p;
-
- VSUB2(rad_vect, vg->coord, base_center);
- r_sq = MAGSQ(rad_vect);
- if (r_sq > max_base_r_sq)
- max_base_r_sq = r_sq;
- if (r_sq < min_base_r_sq)
- min_base_r_sq = r_sq;
-
- sum_base_r_sq += r_sq;
- }
-
- ave_base_r_sq = sum_base_r_sq * one_over_vert_count;
-
- base_r = sqrt(max_base_r_sq);
-
- if (!NEAR_ZERO((max_base_r_sq - ave_base_r_sq)/ave_base_r_sq, 0.001) ||
- !NEAR_ZERO((min_base_r_sq - ave_base_r_sq)/ave_base_r_sq, 0.001))
- return 0;
-
- VSETALL(sum, 0.0);
- lu = BU_LIST_FIRST(loopuse, &fu_top->lu_hd);
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
- struct vertex_g *vg;
-
- NMG_CK_EDGEUSE(eu);
-
- NMG_CK_VERTEXUSE(eu->vu_p);
- NMG_CK_VERTEX(eu->vu_p->v_p);
- vg = eu->vu_p->v_p->vg_p;
- NMG_CK_VERTEX_G(vg);
-
- VADD2(sum, sum, vg->coord);
- }
-
- VSCALE(top_center, sum, one_over_vert_count);
-
- /* Calculate Average Radius */
- min_top_r_sq = MAX_FASTF;
- max_top_r_sq = (-min_top_r_sq);
- sum_top_r_sq = 0.0;
- lu = BU_LIST_FIRST(loopuse, &fu_top->lu_hd);
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
- struct vertex_g *vg;
- vect_t rad_vect;
- fastf_t r_sq;
-
- vg = eu->vu_p->v_p->vg_p;
-
- VSUB2(rad_vect, vg->coord, top_center);
- r_sq = MAGSQ(rad_vect);
- if (r_sq > max_top_r_sq)
- max_top_r_sq = r_sq;
- if (r_sq < min_top_r_sq)
- min_top_r_sq = r_sq;
-
- sum_top_r_sq += r_sq;
- }
-
- ave_top_r_sq = sum_top_r_sq * one_over_vert_count;
- top_r = sqrt(max_top_r_sq);
-
- if (!NEAR_ZERO((max_top_r_sq - ave_top_r_sq)/ave_top_r_sq, 0.001) ||
- !NEAR_ZERO((min_top_r_sq - ave_top_r_sq)/ave_top_r_sq, 0.001))
- return 0;
-
-
- VMOVE(tgc_int->v, base_center);
- VSUB2(tgc_int->h, top_center, base_center);
-
- bn_vec_perp(plv_1, top_pl);
- VCROSS(plv_2, top_pl, plv_1);
- VUNITIZE(plv_1);
- VUNITIZE(plv_2);
- VSCALE(tgc_int->a, plv_1, base_r);
- VSCALE(tgc_int->b, plv_2, base_r);
- VSCALE(tgc_int->c, plv_1, top_r);
- VSCALE(tgc_int->d, plv_2, top_r);
-
- tgc_int->magic = RT_TGC_INTERNAL_MAGIC;
-
- }
-
- return 1;
-}
-
-
-/**
* Checks if lu is convex
*
* Returns:
@@ -9773,160 +9109,7 @@
}
-/**
- * XXX This routine is deprecated in favor of BoTs
- */
-int
-nmg_to_poly(const struct model *m, struct rt_pg_internal *poly_int, struct
bu_list *vlfree, const struct bn_tol *tol)
-{
- struct nmgregion *r;
- struct shell *s;
- struct faceuse *fu;
- struct loopuse *lu;
- struct edgeuse *eu;
- struct model *dup_m;
- struct nmgregion *dup_r;
- struct shell *dup_s;
- int max_count;
- int count_npts;
- int face_count=0;
- NMG_CK_MODEL(m);
-
- BN_CK_TOL(tol);
-
- for (BU_LIST_FOR (r, nmgregion, &m->r_hd)) {
- for (BU_LIST_FOR (s, shell, &r->s_hd)) {
- if (nmg_check_closed_shell(s, tol))
- return 0;
- }
- }
-
- dup_m = nmg_mm();
- dup_r = nmg_mrsv(dup_m);
- dup_s = BU_LIST_FIRST(shell, &dup_r->s_hd);
-
- 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)) {
- if (fu->orientation != OT_SAME)
- continue;
- (void)nmg_dup_face(fu, dup_s);
- }
- }
- }
-
- for (BU_LIST_FOR (dup_r, nmgregion, &dup_m->r_hd)) {
- for (BU_LIST_FOR (dup_s, shell, &dup_r->s_hd)) {
- for (BU_LIST_FOR (fu, faceuse, &dup_s->fu_hd)) {
- NMG_CK_FACEUSE(fu);
-
- /* only do OT_SAME faces */
- if (fu->orientation != OT_SAME)
- continue;
-
- /* count vertices in loops */
- max_count = 0;
- for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd)) {
- NMG_CK_LOOPUSE(lu);
- if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
- continue;
-
- if (lu->orientation != OT_SAME) {
- /* triangulate holes */
- max_count = 6;
- break;
- }
-
- count_npts = 0;
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd))
- count_npts++;
-
- if (count_npts > 5) {
- max_count = count_npts;
- break;
- }
- if (!nmg_lu_is_convex(lu, vlfree, tol)) {
- /* triangulate non-convex faces */
- max_count = 6;
- break;
- }
- }
-
- /* if any loop has more than 5 vertices, triangulate the face */
- if (max_count > 5) {
- if (RTG.NMG_debug & DEBUG_BASIC)
- bu_log("nmg_to_poly: triangulating fu %p\n", (void
*)fu);
- nmg_triangulate_fu(fu, vlfree, tol);
- }
-
- for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd)) {
- NMG_CK_LOOPUSE(lu);
- if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
- continue;
-
- face_count++;
- }
- }
- }
- }
- poly_int->npoly = face_count;
- poly_int->poly = (struct rt_pg_face_internal *)bu_calloc(face_count,
- sizeof(struct
rt_pg_face_internal), "nmg_to_poly: poly");
-
- face_count = 0;
- for (BU_LIST_FOR (dup_r, nmgregion, &dup_m->r_hd)) {
- for (BU_LIST_FOR (dup_s, shell, &dup_r->s_hd)) {
- for (BU_LIST_FOR (fu, faceuse, &dup_s->fu_hd)) {
- vect_t norm;
-
- NMG_CK_FACEUSE(fu);
-
- /* only do OT_SAME faces */
- if (fu->orientation != OT_SAME)
- continue;
-
- NMG_GET_FU_NORMAL(norm, fu);
-
- for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd)) {
- int pt_no=0;
-
- if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
- continue;
-
- /* count vertices in loop */
- count_npts = 0;
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd))
- count_npts++;
-
- poly_int->poly[face_count].npts = count_npts;
- poly_int->poly[face_count].verts = (fastf_t *)
bu_calloc(3*count_npts, sizeof(fastf_t), "nmg_to_poly: verts");
- poly_int->poly[face_count].norms = (fastf_t *)
bu_calloc(3*count_npts, sizeof(fastf_t), "nmg_to_poly: norms");
-
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
- struct vertex_g *vg;
-
- vg = eu->vu_p->v_p->vg_p;
- NMG_CK_VERTEX_G(vg);
-
- VMOVE(&(poly_int->poly[face_count].verts[pt_no*3]),
vg->coord);
- VMOVE(&(poly_int->poly[face_count].norms[pt_no*3]),
norm);
-
- pt_no++;
- }
- face_count++;
- }
- }
- }
- }
-
- poly_int->magic = RT_PG_INTERNAL_MAGIC;
- nmg_km(dup_m);
-
- return 1;
-}
-
-
int
nmg_simplify_shell_edges(struct shell *s, const struct bn_tol *tol)
{
@@ -10776,148 +9959,6 @@
/**
- * Convert an NMG to a BOT solid
- */
-struct rt_bot_internal *
-nmg_bot(struct shell *s, struct bu_list *vlfree, const struct bn_tol *tol)
-{
- struct rt_bot_internal *bot;
- struct bu_ptbl nmg_vertices;
- struct bu_ptbl nmg_faces;
- size_t i, face_no;
- struct vertex *v;
-
- NMG_CK_SHELL(s);
- BN_CK_TOL(tol);
-
- /* first convert the NMG to triangles */
- (void)nmg_triangulate_shell(s, vlfree, tol);
-
- /* make a list of all the vertices */
- nmg_vertex_tabulate(&nmg_vertices, &s->l.magic, vlfree);
-
- /* and a list of all the faces */
- nmg_face_tabulate(&nmg_faces, &s->l.magic, vlfree);
-
- /* now build the BOT */
- BU_ALLOC(bot, struct rt_bot_internal);
-
- bot->magic = RT_BOT_INTERNAL_MAGIC;
- bot->mode = RT_BOT_SOLID;
- bot->orientation = RT_BOT_CCW;
- bot->bot_flags = 0;
-
- bot->num_vertices = BU_PTBL_LEN(&nmg_vertices);
- bot->num_faces = 0;
-
- /* count the number of triangles */
- for (i=0; i<BU_PTBL_LEN(&nmg_faces); i++) {
- struct face *f;
- struct faceuse *fu;
- struct loopuse *lu;
-
- f = (struct face *)BU_PTBL_GET(&nmg_faces, i);
- NMG_CK_FACE(f);
-
- fu = f->fu_p;
-
- if (fu->orientation != OT_SAME) {
- fu = fu->fumate_p;
- if (fu->orientation != OT_SAME) {
- bu_log("nmg_bot(): Face has no OT_SAME use!\n");
- bu_free((char *)bot->vertices, "BOT vertices");
- bu_free((char *)bot->faces, "BOT faces");
- bu_free((char *)bot, "BOT");
- return (struct rt_bot_internal *)NULL;
- }
- }
-
- for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd)) {
- if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
- continue;
- bot->num_faces++;
- }
- }
-
- bot->faces = (int *)bu_calloc(bot->num_faces * 3, sizeof(int), "BOT
faces");
- bot->vertices = (fastf_t *)bu_calloc(bot->num_vertices * 3,
sizeof(fastf_t), "BOT vertices");
-
- bot->thickness = (fastf_t *)NULL;
- bot->face_mode = (struct bu_bitv *)NULL;
-
- /* fill in the vertices */
- for (i=0; i<BU_PTBL_LEN(&nmg_vertices); i++) {
- struct vertex_g *vg;
-
- v = (struct vertex *)BU_PTBL_GET(&nmg_vertices, i);
- NMG_CK_VERTEX(v);
-
- vg = v->vg_p;
- NMG_CK_VERTEX_G(vg);
-
- VMOVE(&bot->vertices[i*3], vg->coord);
- }
-
- /* fill in the faces */
- face_no = 0;
- for (i=0; i<BU_PTBL_LEN(&nmg_faces); i++) {
- struct face *f;
- struct faceuse *fu;
- struct loopuse *lu;
-
- f = (struct face *)BU_PTBL_GET(&nmg_faces, i);
- NMG_CK_FACE(f);
-
- fu = f->fu_p;
-
- if (fu->orientation != OT_SAME) {
- fu = fu->fumate_p;
- if (fu->orientation != OT_SAME) {
- bu_log("nmg_bot(): Face has no OT_SAME use!\n");
- bu_free((char *)bot->vertices, "BOT vertices");
- bu_free((char *)bot->faces, "BOT faces");
- bu_free((char *)bot, "BOT");
- return (struct rt_bot_internal *)NULL;
- }
- }
-
- for (BU_LIST_FOR (lu, loopuse, &fu->lu_hd)) {
- struct edgeuse *eu;
- size_t vertex_no=0;
-
- if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
- continue;
-
- for (BU_LIST_FOR (eu, edgeuse, &lu->down_hd)) {
- if (vertex_no > 2) {
- bu_log("nmg_bot(): Face has not been triangulated!\n");
- bu_free((char *)bot->vertices, "BOT vertices");
- bu_free((char *)bot->faces, "BOT faces");
- bu_free((char *)bot, "BOT");
- return (struct rt_bot_internal *)NULL;
- }
-
- v = eu->vu_p->v_p;
- NMG_CK_VERTEX(v);
-
-
- bot->faces[ face_no*3 + vertex_no ] =
bu_ptbl_locate(&nmg_vertices, (long *)v);
-
- vertex_no++;
- }
-
- face_no++;
- }
- }
-
- bu_ptbl_free(&nmg_vertices);
- bu_ptbl_free(&nmg_faces);
-
- return bot;
-}
-
-
-/**
* create wire edges corresponding to the lines in the vlist. The wire
* edges are created in the specified shell
*/
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits