Beispiel #1
0
/**
 * R T _ M E T A B A L L _ T E S S
 *
 * Tessellate a metaball.
 */
int
rt_metaball_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
{
    struct rt_metaball_internal *mb;
    fastf_t mtol, radius;
    point_t center, min, max;
    fastf_t i, j, k, finalstep = +INFINITY;
    struct bu_vls times = BU_VLS_INIT_ZERO;
    struct wdb_metaballpt *mbpt;
    struct shell *s;
    int numtri = 0;

    if (r == NULL || m == NULL)
	return -1;
    *r = NULL;

    NMG_CK_MODEL(m);

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

    rt_prep_timer();

    /* since this geometry isn't necessarily prepped, we have to figure out the
     * finalstep and bounding box manually. */
    for (BU_LIST_FOR(mbpt, wdb_metaballpt, &mb->metaball_ctrl_head))
	V_MIN(finalstep, mbpt->fldstr);
    finalstep /= (fastf_t)1e5;

    radius = rt_metaball_get_bounding_sphere(&center, mb->threshold, mb);
    if(radius < 0) {	/* no control points */
	bu_log("Attempting to tesselate metaball with no control points");
	return -1;
    }
    rt_metaball_bbox(ip, &min, &max, tol);

    /* TODO: get better sampling tolerance, unless this is "good enough" */
    mtol = ttol->abs;
    V_MAX(mtol, ttol->rel * radius * 10);
    V_MAX(mtol, tol->dist);

    *r = nmg_mrsv(m);	/* new empty nmg */
    s = BU_LIST_FIRST(shell, &(*r)->s_hd);

    /* the incredibly naïve approach. Time could be cut in half by simply
     * caching 4 point values, more by actually marching or doing active
     * refinement. This is the simplest pattern for now.
     */
    for (i = min[X]; i < max[X]; i += mtol)
	for (j = min[Y]; j < max[Y]; j += mtol)
	    for (k = min[Z]; k < max[Z]; k += mtol) {
		point_t p[8];
		int pv = 0;

		/* generate the vertex values */
#define MEH(c,di,dj,dk) VSET(p[c], i+di, j+dj, k+dk); pv |= rt_metaball_point_inside((const point_t *)&p[c], mb) << c;
		MEH(0, 0, 0, mtol);
		MEH(1, mtol, 0, mtol);
		MEH(2, mtol, 0, 0);
		MEH(3, 0, 0, 0);
		MEH(4, 0, mtol, mtol);
		MEH(5, mtol, mtol, mtol);
		MEH(6, mtol, mtol, 0);
		MEH(7, 0, mtol, 0);
#undef MEH

		if ( pv != 0 && pv != 255 ) {	/* entire cube is either inside or outside */
		    point_t edges[12];
		    int rval;

		    /* compute the edge values (if needed) */
#define MEH(a,b,c) if(!(pv&(1<<b)&&pv&(1<<c))) { \
    rt_metaball_find_intersection(edges+a, mb, (const point_t *)(p+b), (const point_t *)(p+c), mtol, finalstep); \
}

		    /* magic numbers! an edge, then the two attached vertices.
		     * For edge/vertex mapping, refer to the awesome ascii art
		     * at the beginning of this file. */
		    MEH(0 ,0,1);
		    MEH(1 ,1,2);
		    MEH(2 ,2,3);
		    MEH(3 ,0,3);
		    MEH(4 ,4,5);
		    MEH(5 ,5,6);
		    MEH(6 ,6,7);
		    MEH(7 ,4,7);
		    MEH(8 ,0,4);
		    MEH(9 ,1,5);
		    MEH(10,2,6);
		    MEH(11,3,7);
#undef MEH

		    rval = nmg_mc_realize_cube(s, pv, (point_t *)edges, tol);
		    numtri += rval;
		    if(rval < 0) {
			bu_log("Error attempting to realize a cube O.o\n");
			return rval;
		    }
		}
	    }

    nmg_mark_edges_real(&s->l.magic);
    nmg_region_a(*r, tol);

    nmg_model_fuse(m, tol);

    rt_get_timer(&times, NULL);
    bu_log("metaball tesselate (%d triangles): %s\n", numtri, bu_vls_addr(&times));

    return 0;
}
Beispiel #2
0
int main ( int arfc, char ** arfv ) {
  char output_filename[80]={0};
  int i, count;
  int data, * pdata;

  MPI_Status ms = {0};

  pdata = &data;

  MEH(MPI_Init(&arfc, &arfv));
  MEH(MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank));
  MEH(MPI_Comm_size(MPI_COMM_WORLD, &mpi_size));

  sprintf(output_filename, "output-%d", mpi_rank);

  if(NULL != (OUTPUT = fopen(output_filename, "w"))) {
    fprintf(stderr, "[%f] %d opened %s for write\n", MPI_Wtime(), mpi_rank, output_filename);
  } else {
    fprintf(OUTPUT, "[%f] %d could not open %s for write, bailing\n", MPI_Wtime(), mpi_rank, output_filename);
  }

  srand(time(NULL));

  if ( arfc >= 2 ) {
    count = atoi(arfv[1]);
    fprintf(OUTPUT, "[%f] %d converting first argument %s to %d\n", MPI_Wtime(), mpi_rank, arfv[1], count);
  }

  if ( count < 0 ) count = DEFAULT_COUNT;

  fprintf(OUTPUT, "[%f] %d attempting %d iterations\n", MPI_Wtime(), mpi_rank, count);

  for ( i = 0; i < count; ++ i ) {
    switch(mpi_rank) {

      case MPI_RANK_MASTER:
        // MPI_RANK_MASTER receives a number from MPI_RANK_SOURCE and forwards to MPI_RANK_TARGET

        MEH(MPI_Recv(pdata, 1, MPI_INT, MPI_ANY_SOURCE, ARBITRARY_TAG, MPI_COMM_WORLD, &ms));
        fprintf(OUTPUT, "[%f] %d received %d from %d, seq %d\n", MPI_Wtime(), mpi_rank, data, ms.MPI_SOURCE, i);

        MEH(MPI_Send(pdata, 1, MPI_INT, MPI_RANK_TARGET, ARBITRARY_TAG, MPI_COMM_WORLD));
        fprintf(OUTPUT, "[%f] %d sent %d to %d, seq %d\n", MPI_Wtime(), mpi_rank, data, MPI_RANK_TARGET, i);

        break;

      case MPI_RANK_SOURCE:
        // MPI_RANK_MASTER generates a pseudorandom number and sends to MPI_RANK_MASTER

        data = rand();

        MEH(MPI_Send(pdata, 1, MPI_INT, MPI_RANK_MASTER, ARBITRARY_TAG, MPI_COMM_WORLD));
        fprintf(OUTPUT, "[%f] %d sent %d to %d, seq %d\n", MPI_Wtime(), mpi_rank, data, MPI_RANK_MASTER, i);

        break;

      case MPI_RANK_TARGET:
        // MPI_RANK_TARGET receives a random number from MPI_RANK_MASTER

        MEH(MPI_Recv(pdata, 1, MPI_INT, MPI_ANY_SOURCE, ARBITRARY_TAG, MPI_COMM_WORLD, &ms));
        fprintf(OUTPUT, "[%f] %d received %d from %d, seq %d\n", MPI_Wtime(), mpi_rank, data, ms.MPI_SOURCE, i);

        break;
    }
  }

  fclose(OUTPUT);

  MEH(MPI_Finalize());
  return 0;
}