示例#1
0
文件: bottess.c 项目: kanzure/brlcad
int
soup_add_face(struct soup_s *s, point_t a, point_t b, point_t c, const struct bn_tol *tol) {
    plane_t p;

    /* solve the plane */
    bn_mk_plane_3pts(p, a, b, c, tol);

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

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

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


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

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

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

	nmg_vertex_gv(v[i], p);
    }

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

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

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

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

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

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

    for (i=0; i < num_pts; ++i) {
	if (BU_LIST_IS_EMPTY(&v[i]->vu_hd)) continue;
	FREE_VERTEX(v[i]);
    }
    bu_free((char *)v, "vertex array");
    return s;
}
示例#3
0
文件: util.c 项目: kanzure/brlcad
int
coplanar_2d_coord_sys(point_t *origin_pnt, vect_t *u_axis, vect_t *v_axis, const point_t *points_3d, int n)
{
    int i = 0;
    int have_normal = 0;
    plane_t plane;
    fastf_t dist_pt_pt = 0.0;
    fastf_t vdot = 1.0;
    point_t p_farthest;
    int p_farthest_index = 0;
    vect_t normal = VINIT_ZERO;
    const struct bn_tol tol = {BN_TOL_MAGIC, BN_TOL_DIST/2.0, BN_TOL_DIST*BN_TOL_DIST/4.0, 1.0e-6, 1.0-1.0e-6};

    /* Step 1 - find center point */
    VSETALL(*origin_pnt, 0.0);
    for (i = 0; i < n; i++) {
	VADD2(*origin_pnt, *origin_pnt, points_3d[i]);
    }
    VSCALE(*origin_pnt, *origin_pnt, 1.0/n);

    /* Step 2 - find furthest points from the center point */
    VSETALL(p_farthest, 0.0);
    for (i = 0; i < n; i++) {
	fastf_t curr_dist = DIST_PT_PT_SQ(*origin_pnt, points_3d[i]);
	if (curr_dist > dist_pt_pt) {
	    dist_pt_pt = curr_dist;
	    VMOVE(p_farthest, points_3d[i]);
	    p_farthest_index = i;
	}
    }
    VSUB2(*u_axis, p_farthest, *origin_pnt);
    VUNITIZE(*u_axis);

    /* Step 3 - find normal vector of plane holding points */
    i = 0;
    dist_pt_pt = DIST_PT_PT(*origin_pnt, p_farthest);
    while (i < n) {
	if (i != p_farthest_index) {
	    vect_t temp_vect;
	    fastf_t curr_vdot;
	    VSUB2(temp_vect, points_3d[i], *origin_pnt);
	    VUNITIZE(temp_vect);
	    curr_vdot = fabs(VDOT(temp_vect, *u_axis));
	    if (curr_vdot < vdot) {
		if (!bn_mk_plane_3pts(plane, *origin_pnt, p_farthest, points_3d[i], &tol)) {
		    VSET(normal, plane[0], plane[1], plane[2]);
		    have_normal = 1;
		    vdot = curr_vdot;
		}
	    }
	}
	i++;
    }
    if (!have_normal) return -1;
    VUNITIZE(normal);

    /* Step 4 - use vectors from steps 2 and 3 to find y axis vector */
    VCROSS(*v_axis, *u_axis, normal);
    VUNITIZE(*v_axis);

    return 0;
}
示例#4
0
文件: solid.c 项目: cciechad/brlcad
int
read_arbn(char *name)
{
    int	npt;			/* # vertex pts to be read in */
    int	npe;			/* # planes from 3 vertex points */
    int	neq;			/* # planes from equation */
    int	nae;			/* # planes from az, el & vertex index */
    int	nface;			/* total number of faces */
    double	*input_points = (double *)0;
    double	*vertex = (double *)0;	/* vertex list of final solid */
    int	last_vertex;		/* index of first unused vertex */
    int	max_vertex;		/* size of vertex array */
    int	*used = (int *)0;	/* plane eqn use count */
    plane_t	*eqn = (plane_t *)0;	/* plane equations */
    int	cur_eq = 0;		/* current (free) equation number */
    int	symm = 0;		/* symmetry about Y used */
    register int	i;
    int	j;
    int	k;
    register int	m;
    point_t	cent;			/* centroid of arbn */
    struct bn_tol	tol;

    /* XXX The tolerance here is sheer guesswork */
    tol.magic = BN_TOL_MAGIC;
    tol.dist = 0.005;
    tol.dist_sq = tol.dist * tol.dist;
    tol.perp = 1e-6;
    tol.para = 1 - tol.perp;

    npt = getint( scard, 10+0*10, 10 );
    npe = getint( scard, 10+1*10, 10 );
    neq = getint( scard, 10+2*10, 10 );
    nae = getint( scard, 10+3*10, 10 );

    nface = npe + neq + nae;
    if ( npt < 1 )  {
        /* Having one point is necessary to compute centroid */
        printf("arbn defined without at least one point\n");
bad:
        if (npt>0) eat( (npt+1)/2 );	/* vertex input_points */
        if (npe>0) eat( (npe+5)/6 );	/* vertex pt index numbers */
        if (neq>0) eat( neq );		/* plane eqns? */
        if (nae>0) eat( (nae+1)/2 );	/* az el & vertex index? */
        return(-1);
    }

    /* Allocate storage for plane equations */
    eqn = (plane_t *)bu_malloc(nface*sizeof(plane_t), "eqn");

    /* Allocate storage for per-plane use count */
    used = (int *)bu_malloc(nface*sizeof(int), "used");

    if ( npt >= 1 )  {
        /* Obtain vertex input_points */
        input_points = (double *)bu_malloc(npt*3*sizeof(double), "input_points");

        if ( getxsoldata( input_points, npt*3, sol_work ) < 0 )
            goto bad;
    }

    /* Get planes defined by three points, 6 per card */
    for ( i=0; i<npe; i += 6 )  {
        if ( get_line( scard, sizeof(scard), "arbn vertex point indices" ) == EOF )  {
            printf("too few cards for arbn %d\n",
                   sol_work);
            return(-1);
        }
        for ( j=0; j<6; j++ )  {
            int	q, r, s;
            point_t	a, b, c;

            q = getint( scard, 10+j*10+0, 4 );
            r = getint( scard, 10+j*10+4, 3 );
            s = getint( scard, 10+j*10+7, 3 );

            if ( q == 0 || r == 0 || s == 0 ) continue;

            if ( q < 0 )  {
                VMOVE( a, &input_points[((-q)-1)*3] );
                a[Y] = -a[Y];
                symm = 1;
            } else {
                VMOVE( a, &input_points[((q)-1)*3] );
            }

            if ( r < 0 )  {
                VMOVE( b, &input_points[((-r)-1)*3] );
                b[Y] = -b[Y];
                symm = 1;
            } else {
                VMOVE( b, &input_points[((r)-1)*3] );
            }

            if ( s < 0 )  {
                VMOVE( c, &input_points[((-s)-1)*3] );
                c[Y] = -c[Y];
                symm = 1;
            } else {
                VMOVE( c, &input_points[((s)-1)*3] );
            }
            if ( bn_mk_plane_3pts( eqn[cur_eq], a, b, c, &tol ) < 0 )  {
                printf("arbn degenerate plane\n");
                VPRINT("a", a);
                VPRINT("b", b);
                VPRINT("c", c);
                continue;
            }
            cur_eq++;
        }
    }

    /* Get planes defined by their equation */
    for ( i=0; i < neq; i++ )  {
        register double	scale;
        if ( get_line( scard, sizeof(scard), "arbn plane equation card" ) == EOF )  {
            printf("too few cards for arbn %d\n",
                   sol_work);
            return(-1);
        }
        eqn[cur_eq][0] = getdouble( scard, 10+0*10, 10 );
        eqn[cur_eq][1] = getdouble( scard, 10+1*10, 10 );
        eqn[cur_eq][2] = getdouble( scard, 10+2*10, 10 );
        eqn[cur_eq][3] = getdouble( scard, 10+3*10, 10 );
        scale = MAGNITUDE(eqn[cur_eq]);
        if ( scale < SMALL )  {
            printf("arbn plane normal too small\n");
            continue;
        }
        scale = 1/scale;
        VSCALE( eqn[cur_eq], eqn[cur_eq], scale );
        eqn[cur_eq][3] *= scale;
        cur_eq++;
    }

    /* Get planes defined by azimuth, elevation, and pt, 2 per card */
    for ( i=0; i < nae;  i += 2 )  {
        if ( get_line( scard, sizeof(scard), "arbn az/el card" ) == EOF )  {
            printf("too few cards for arbn %d\n",
                   sol_work);
            return(-1);
        }
        for ( j=0; j<2; j++ )  {
            double	az, el;
            int	vert_no;
            double	cos_el;
            point_t	pt;

            az = getdouble( scard, 10+j*30+0*10, 10 ) * bn_degtorad;
            el = getdouble( scard, 10+j*30+1*10, 10 ) * bn_degtorad;
            vert_no = getint( scard, 10+j*30+2*10, 10 );
            if ( vert_no == 0 )  break;
            cos_el = cos(el);
            eqn[cur_eq][X] = cos(az)*cos_el;
            eqn[cur_eq][Y] = sin(az)*cos_el;
            eqn[cur_eq][Z] = sin(el);

            if ( vert_no < 0 )  {
                VMOVE( pt, &input_points[((-vert_no)-1)*3] );
                pt[Y] = -pt[Y];
            } else {
                VMOVE( pt, &input_points[((vert_no)-1)*3] );
            }
            eqn[cur_eq][3] = VDOT(pt, eqn[cur_eq]);
            cur_eq++;
        }
    }
    if ( nface != cur_eq )  {
        printf("arbn expected %d faces, got %d\n", nface, cur_eq);
        return(-1);
    }

    /* Average all given points together to find centroid */
    /* This is why there must be at least one (two?) point given */
    VSETALL(cent, 0);
    for ( i=0; i<npt; i++ )  {
        VADD2( cent, cent, &input_points[i*3] );
    }
    VSCALE( cent, cent, 1.0/npt );
    if ( symm )  cent[Y] = 0;

    /* Point normals away from centroid */
    for ( i=0; i<nface; i++ )  {
        double	dist;

        dist = VDOT( eqn[i], cent ) - eqn[i][3];
        /* If dist is negative, 'cent' is inside halfspace */
#define DIST_TOL	(1.0e-8)
#define DIST_TOL_SQ	(1.0e-10)
        if ( dist < -DIST_TOL )  continue;
        if ( dist > DIST_TOL )  {
            /* Flip halfspace over */
            VREVERSE( eqn[i], eqn[i] );
            eqn[i][3] = -eqn[i][3];
        } else {
            /* Centroid lies on this face */
            printf("arbn centroid lies on face\n");
            return(-1);
        }

    }

    /* Release storage for input points */
    bu_free( (char *)input_points, "input_points" );
    input_points = (double *)0;


    /*
     *  ARBN must be convex.  Test for concavity.
     *  Byproduct is an enumeration of all the verticies.
     */
    last_vertex = max_vertex = 0;

    /* Zero face use counts */
    for ( i=0; i<nface; i++ )  {
        used[i] = 0;
    }
    for ( i=0; i<nface-2; i++ )  {
        for ( j=i+1; j<nface-1; j++ )  {
            double	dot;
            int	point_count;	/* # points on this line */

            /* If normals are parallel, no intersection */
            dot = VDOT( eqn[i], eqn[j] );
            if ( !NEAR_ZERO( dot, 0.999999 ) )  continue;

            point_count = 0;
            for ( k=j+1; k<nface; k++ )  {
                point_t	pt;

                if ( bn_mkpoint_3planes( pt, eqn[i], eqn[j], eqn[k] ) < 0 )  continue;

                /* See if point is outside arb */
                for ( m=0; m<nface; m++ )  {
                    if ( i==m || j==m || k==m )  continue;
                    if ( VDOT(pt, eqn[m])-eqn[m][3] > DIST_TOL )
                        goto next_k;
                }
                /* See if vertex already was found */
                for ( m=0; m<last_vertex; m++ )  {
                    vect_t	dist;
                    VSUB2( dist, pt, &vertex[m*3] );
                    if ( MAGSQ(dist) < DIST_TOL_SQ )
                        goto next_k;
                }

                /*
                 *  Add point to vertex array.
                 *  If more room needed, realloc.
                 */
                if ( last_vertex >= max_vertex )  {
                    if ( max_vertex == 0 )   {
                        max_vertex = 3;
                        vertex = (double *)bu_malloc( max_vertex*3*sizeof(double), "vertex" );
                    } else {
                        max_vertex *= 10;
                        vertex = (double *)bu_realloc( (char *)vertex, max_vertex*3*sizeof(double), "vertex" );
                    }
                }

                VMOVE( &vertex[last_vertex*3], pt );
                last_vertex++;
                point_count++;

                /* Increment "face used" counts */
                used[i]++;
                used[j]++;
                used[k]++;
next_k:
                ;
            }
            if ( point_count > 2 )  {
                printf("arbn: warning, point_count on line=%d\n", point_count);
            }
        }
    }

    /* If any planes were not used, then arbn is not convex */
    for ( i=0; i<nface; i++ )  {
        if ( used[i] != 0 )  continue;	/* face was used */
        printf("arbn face %d unused, solid is not convex\n", i);
        return(-1);
    }

    /* Write out the solid ! */
    i = mk_arbn( outfp, name, nface, eqn );

    if ( input_points )  bu_free( (char *)input_points, "input_points" );
    if ( vertex )  bu_free( (char *)vertex, "vertex" );
    if ( eqn )  bu_free( (char *)eqn, "eqn" );
    if ( used )  bu_free( (char *)used, "used" );

    return(i);
}
示例#5
0
void
make_3manifold_bits(struct bn_tol *tol)
{
    plane_t plane;
    struct faceuse *fu_end;

    memset((char *)vertl, 0, sizeof(vertl));
    memset((char *)f_vertl, 0, sizeof(f_vertl));

    /* front right */
    f_vertl[0] = &vertl[0];
    f_vertl[1] = &vertl[1];
    f_vertl[2] = &vertl[2];
    f_vertl[3] = &vertl[3];
    fr_fu = fu = nmg_cmface(s, f_vertl, 4);
    nmg_vertex_g(vertl[0],  100.0, 100.0, 100.0);
    nmg_vertex_g(vertl[1],   50.0, 100.0, 100.0);
    nmg_vertex_g(vertl[2],   50.0,   0.0, 100.0);
    nmg_vertex_g(vertl[3],  100.0,   0.0, 100.0);
    (void)nmg_fu_planeeqn(fu, tol);

    /* make top right */
    f_vertl[0] = &vertl[0];
    f_vertl[1] = &vertl[4];
    f_vertl[2] = &vertl[5];
    f_vertl[3] = &vertl[1];
    fu = nmg_cmface(s, f_vertl, 4);
    nmg_vertex_g(vertl[4],  100.0, 100.0,   0.0);
    nmg_vertex_g(vertl[5],   50.0, 100.0,   0.0);
    (void)nmg_fu_planeeqn(fu, tol);


    /* back right */
    f_vertl[0] = &vertl[5];
    f_vertl[1] = &vertl[4];
    f_vertl[2] = &vertl[6];
    f_vertl[3] = &vertl[7];
    fu = nmg_cmface(s, f_vertl, 4);
    nmg_vertex_g(vertl[6],  100.0,   0.0,   0.0);
    nmg_vertex_g(vertl[7],   50.0,   0.0,   0.0);
    (void)nmg_fu_planeeqn(fu, tol);

    /* bottom right */
    f_vertl[0] = &vertl[7];
    f_vertl[1] = &vertl[6];
    f_vertl[2] = &vertl[3];
    f_vertl[3] = &vertl[2];
    fu = nmg_cmface(s, f_vertl, 4);
    (void)nmg_fu_planeeqn(fu, tol);

    /* right end */
    f_vertl[0] = &vertl[3];
    f_vertl[1] = &vertl[6];
    f_vertl[2] = &vertl[4];
    f_vertl[3] = &vertl[0];
    fu = nmg_cmface(s, f_vertl, 4);
    (void)nmg_fu_planeeqn(fu, tol);


    /* make split top */
    f_vertl[0] = &vertl[1];
    f_vertl[1] = &vertl[5];
    f_vertl[2] = &vertl[8];
    f_vertl[3] = &vertl[9];
    tc_fu = fu = nmg_cmface(s, f_vertl, 4);
    nmg_vertex_g(vertl[8],   25.0, 100.0,   0.0);
    nmg_vertex_g(vertl[9],   25.0, 100.0, 100.0);
    (void)nmg_fu_planeeqn(fu, tol);

    f_vertl[0] = &vertl[9];
    f_vertl[1] = &vertl[8];
    f_vertl[2] = &vertl[12];
    f_vertl[3] = &vertl[13];
    fu = nmg_cmface(s, f_vertl, 4);
    nmg_vertex_g(vertl[12],   0.0, 100.0,   0.0);
    nmg_vertex_g(vertl[13],   0.0, 100.0, 100.0);
    (void)nmg_fu_planeeqn(fu, tol);


    /* make split & funky front side
     * we make the convex face first, make the second (non-convex) portion
     * after the face normal has been computed.
     */
    f_vertl[0] = &vertl[14];
    f_vertl[1] = &vertl[18];
    f_vertl[2] = &vertl[15];
    f_vertl[3] = &vertl[16];
    fl_fu = fu = nmg_cmface(s, f_vertl, 4);
    nmg_vertex_g(vertl[14],   0.0,  25.0, 100.0);
    nmg_vertex_g(vertl[15],  25.0,   0.0, 100.0);
    nmg_vertex_g(vertl[16],  25.0,  25.0, 100.0);
    nmg_vertex_g(vertl[18],   0.0,   0.0, 100.0);
    (void)nmg_fu_planeeqn(fu, tol);

    f_vertl[0] = &vertl[1];
    f_vertl[1] = &vertl[9];
    f_vertl[2] = &vertl[10];
    f_vertl[3] = &vertl[9];
    f_vertl[4] = &vertl[13];
    f_vertl[5] = &vertl[14];
    f_vertl[6] = &vertl[16];
    f_vertl[7] = &vertl[15];
    f_vertl[8] = &vertl[2];
    nmg_jf(fu, nmg_cmface(s, f_vertl, 9));
    nmg_vertex_g(vertl[10],  25.0,  75.0, 100.0);


    /* make split back side */
    f_vertl[0] = &vertl[5];
    f_vertl[1] = &vertl[7];
    f_vertl[2] = &vertl[17];
    f_vertl[3] = &vertl[12];
    f_vertl[4] = &vertl[8];
    f_vertl[5] = &vertl[11];
    f_vertl[6] = &vertl[8];
    bl_fu = fu = nmg_cmface(s, f_vertl, 7);
    nmg_vertex_g(vertl[11],  25.0,  75.0,   0.0);
    nmg_vertex_g(vertl[17],   0.0,   0.0,   0.0);

    /* this face isn't strictly convex, so we have to make the plane
     * equation the old-fashioned way.
     */
    bn_mk_plane_3pts(plane,
		     vertl[7]->vg_p->coord,
		     vertl[17]->vg_p->coord,
		     vertl[12]->vg_p->coord,
		     tol);
    nmg_face_g(fu, plane);


    /* make funky end */
    f_vertl[0] = &vertl[14];
    f_vertl[1] = &vertl[20];
    f_vertl[2] = &vertl[19];
    f_vertl[3] = &vertl[18];
    fu_end = fu = nmg_cmface(s, f_vertl, 4);
    nmg_vertex_g(vertl[19],   0.0,   0.0,  75.0);
    nmg_vertex_g(vertl[20],   0.0,  25.0,  75.0);
    (void)nmg_fu_planeeqn(fu, tol);

    f_vertl[0] = &vertl[12];
    f_vertl[1] = &vertl[17];
    f_vertl[2] = &vertl[19];
    f_vertl[3] = &vertl[20];
    f_vertl[4] = &vertl[14];
    f_vertl[5] = &vertl[13];
    nmg_jf(fu, nmg_cmface(s, f_vertl, 6));


    /* make funky bottom */
    f_vertl[0] = &vertl[15];
    f_vertl[1] = &vertl[18];
    f_vertl[2] = &vertl[19];
    f_vertl[3] = &vertl[21];
    ul_fu = fu = nmg_cmface(s, f_vertl, 4);
    nmg_vertex_g(vertl[21],  25.0,   0.0,  75.0);
    (void)nmg_fu_planeeqn(fu, tol);

    f_vertl[0] = &vertl[7];
    f_vertl[1] = &vertl[2];
    f_vertl[2] = &vertl[15];
    f_vertl[3] = &vertl[21];
    f_vertl[4] = &vertl[19];
    f_vertl[5] = &vertl[17];
    nmg_jf(fu, nmg_cmface(s, f_vertl, 6));


    /* now create the (3manifold) hole through the object */

    /* make the holes in the end face */
    f_vertl[0] = &vertl[29];
    f_vertl[1] = &vertl[28];
    f_vertl[2] = &vertl[27];
    f_vertl[3] = &vertl[26];
    fu = nmg_cmface(s, f_vertl, 4);
    nmg_vertex_g(vertl[26],  0.0,   60.0, 10.0);
    nmg_vertex_g(vertl[27],  0.0,   60.0, 25.0);
    nmg_vertex_g(vertl[28],  0.0,   40.0, 25.0);
    nmg_vertex_g(vertl[29],  0.0,   40.0, 10.0);

    /* GROSS HACK XXX
     * we reverse the orientation of the faceuses and loopuses
     * so that we can make the hole as a face, and transfer the hole
     * to an existing face
     */

    lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
    lu->orientation = OT_OPPOSITE;
    lu->lumate_p->orientation = OT_OPPOSITE;

    fu->orientation = OT_OPPOSITE;
    fu->fumate_p->orientation = OT_SAME;

    nmg_jf(fu_end, fu->fumate_p);


    f_vertl[0] = &vertl[22];
    f_vertl[1] = &vertl[23];
    f_vertl[2] = &vertl[24];
    f_vertl[3] = &vertl[25];
    fu = nmg_cmface(s, f_vertl, 4);
    nmg_vertex_g(vertl[22],  10.0, 60.0,  0.0);
    nmg_vertex_g(vertl[23],  25.0,  60.0,  0.0);
    nmg_vertex_g(vertl[24],  25.0,  40.0,  0.0);
    nmg_vertex_g(vertl[25],  10.0, 40.0,  0.0);

    /* GROSS HACK XXX
     * we reverse the orientation of the faceuses and loopuses
     * so that we can make the hole as a face, and transfer the hole
     * to an existing face.
     */

    lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
    lu->orientation = OT_OPPOSITE;
    lu->lumate_p->orientation = OT_OPPOSITE;

    fu->orientation = OT_OPPOSITE;
    fu->fumate_p->orientation = OT_SAME;

    nmg_jf(bl_fu, fu->fumate_p);


    /* make the top of the hole */
    f_vertl[0] = &vertl[22];
    f_vertl[1] = &vertl[23];
    f_vertl[2] = &vertl[27];
    f_vertl[3] = &vertl[26];
    fu = nmg_cmface(s, f_vertl, 4);
    (void)nmg_fu_planeeqn(fu, tol);


    /* make the bottom of the hole */
    f_vertl[0] = &vertl[24];
    f_vertl[1] = &vertl[25];
    f_vertl[2] = &vertl[29];
    f_vertl[3] = &vertl[28];
    fu = nmg_cmface(s, f_vertl, 4);
    (void)nmg_fu_planeeqn(fu, tol);


    /* make origin-ward side of the hole */
    f_vertl[0] = &vertl[22];
    f_vertl[1] = &vertl[26];
    f_vertl[2] = &vertl[29];
    f_vertl[3] = &vertl[25];
    fu = nmg_cmface(s, f_vertl, 4);
    (void)nmg_fu_planeeqn(fu, tol);

    /* make last side of hole */
    f_vertl[0] = &vertl[23];
    f_vertl[1] = &vertl[24];
    f_vertl[2] = &vertl[28];
    f_vertl[3] = &vertl[27];
    fu = nmg_cmface(s, f_vertl, 4);
    (void)nmg_fu_planeeqn(fu, tol);


    /* now make the void in the center of the solid */

    /* void bottom */
    f_vertl[0] = &vertl[41];
    f_vertl[1] = &vertl[40];
    f_vertl[2] = &vertl[39];
    f_vertl[3] = &vertl[38];
    fu = nmg_cmface(s, f_vertl, 4);
    nmg_vertex_g(vertl[38],  85.0, 40.0, 60.0);
    nmg_vertex_g(vertl[39],  65.0, 40.0, 60.0);
    nmg_vertex_g(vertl[40],  65.0, 40.0, 40.0);
    nmg_vertex_g(vertl[41],  85.0, 40.0, 40.0);
    (void)nmg_fu_planeeqn(fu, tol);


    /* void top */
    f_vertl[0] = &vertl[42];
    f_vertl[1] = &vertl[43];
    f_vertl[2] = &vertl[44];
    f_vertl[3] = &vertl[45];
    fu = nmg_cmface(s, f_vertl, 4);
    nmg_vertex_g(vertl[42],  85.0, 60.0, 40.0);
    nmg_vertex_g(vertl[43],  85.0, 60.0, 60.0);
    nmg_vertex_g(vertl[44],  65.0, 60.0, 60.0);
    nmg_vertex_g(vertl[45],  65.0, 60.0, 40.0);
    (void)nmg_fu_planeeqn(fu, tol);


    /* void front */
    f_vertl[0] = &vertl[44];
    f_vertl[1] = &vertl[43];
    f_vertl[2] = &vertl[38];
    f_vertl[3] = &vertl[39];
    fu = nmg_cmface(s, f_vertl, 4);
    (void)nmg_fu_planeeqn(fu, tol);

    /* void back */
    f_vertl[0] = &vertl[42];
    f_vertl[1] = &vertl[45];
    f_vertl[2] = &vertl[40];
    f_vertl[3] = &vertl[41];
    fu = nmg_cmface(s, f_vertl, 4);
    (void)nmg_fu_planeeqn(fu, tol);


    /* void left */
    f_vertl[0] = &vertl[45];
    f_vertl[1] = &vertl[44];
    f_vertl[2] = &vertl[39];
    f_vertl[3] = &vertl[40];
    fu = nmg_cmface(s, f_vertl, 4);
    (void)nmg_fu_planeeqn(fu, tol);

    /* void right */
    f_vertl[0] = &vertl[42];
    f_vertl[1] = &vertl[41];
    f_vertl[2] = &vertl[38];
    f_vertl[3] = &vertl[43];
    fu = nmg_cmface(s, f_vertl, 4);
    (void)nmg_fu_planeeqn(fu, tol);


}
示例#6
0
int bn_tri_tri_isect_coplanar(point_t V0, point_t V1, point_t V2,
			      point_t U0, point_t U1, point_t U2, int area_flag)
{
    int ret;
    fastf_t A[3];
    short i0, i1;
    point_t E1, E2, N;
    plane_t P1, P2;
    static const struct bn_tol tol = {
	BN_TOL_MAGIC, EPSILON, EPSILON*EPSILON, 1e-6, 1-1e-6
    };

    /* compute plane of triangle (V0, V1, V2) */
    ret = bn_mk_plane_3pts(P1, V0, V1, V2, &tol);
    if (ret) return -1;
    /* compute plane of triangle (U0, U1, U2) */
    ret = bn_mk_plane_3pts(P2, U0, U1, U2, &tol);
    if (ret) return -1;
    /* verify that triangles are coplanar */
    if (bn_coplanar(P1, P2, &tol) <= 0) return -1;

    /* first project onto an axis-aligned plane, that maximizes the area */
    /* of the triangles, compute indices: i0, i1. */
    VSUB2(E1, V1, V0);
    VSUB2(E2, V2, V0);
    VCROSS(N, E1, E2);

    A[0]=FABS(N[0]);
    A[1]=FABS(N[1]);
    A[2]=FABS(N[2]);
    if (A[0]>A[1]) {
	if (A[0]>A[2]) {
	    i0=1;      /* A[0] is greatest */
	    i1=2;
	} else {
	    i0=0;      /* A[2] is greatest */
	    i1=1;
	}
    } else {
	/* A[0]<=A[1] */
	if (A[2]>A[1]) {
	    i0=0;      /* A[2] is greatest */
	    i1=1;
	} else {
	    i0=0;      /* A[1] is greatest */
	    i1=2;
	}
    }

    /* test all edges of triangle 1 against the edges of triangle 2 */
    if (!area_flag) {
	EDGE_AGAINST_TRI_EDGES(V0, V1, U0, U1, U2);
	EDGE_AGAINST_TRI_EDGES(V1, V2, U0, U1, U2);
	EDGE_AGAINST_TRI_EDGES(V2, V0, U0, U1, U2);
    } else {
	EDGE_AGAINST_TRI_EDGES_AREA(V0, V1, U0, U1, U2);
	EDGE_AGAINST_TRI_EDGES_AREA(V1, V2, U0, U1, U2);
	EDGE_AGAINST_TRI_EDGES_AREA(V2, V0, U0, U1, U2);
    }

    /* finally, test if tri1 is totally contained in tri2 or vice versa */
    POINT_IN_TRI(V0, U0, U1, U2);
    POINT_IN_TRI(U0, V0, V1, V2);

    return 0;
}