Ejemplo n.º 1
0
// Evaluates a region voxel-by-voxel, storing the output in the data
// member of the tristate struct.
bool Mesher::load_packed(const Region& r)
{
    // Only load the packed matrix if we have few enough voxels.
    const unsigned voxels = (r.ni+1) * (r.nj+1) * (r.nk+1);
    if (voxels >= MIN_VOLUME)
        return false;

    // We've already run interval evaluation for this region
    // (at the beginning of triangulate_region), so here we'll
    // just disable inactive nodes.
    disable_nodes(tree);

    // Flatten a 3D region into a 1D list of points that
    // touches every point in the region, one by one.
    int q = 0;
    for (unsigned k=0; k <= r.nk; ++k) {
        for (unsigned j=0; j <= r.nj; ++j) {
            for (unsigned i=0; i <= r.ni; ++i) {
                X[q] = r.X[i];
                Y[q] = r.Y[j];
                Z[q] = r.Z[k];
                q++;
            }
        }
    }

    // Make a dummy region that has the newly-flattened point arrays as the
    // X, Y, Z coordinate data arrays (so that we can run eval_r on it).
    packed.imin = r.imin;
    packed.jmin = r.jmin;
    packed.kmin = r.kmin;
    packed.ni = r.ni;
    packed.nj = r.nj;
    packed.nk = r.nk;
    packed.X = X;
    packed.Y = Y;
    packed.Z = Z;
    packed.voxels = voxels;

    // Run eval_r and copy the data out
    memcpy(data, eval_r(tree, packed), voxels * sizeof(float));
    has_data = true;

    return true;
}
Ejemplo n.º 2
0
void render8(MathTree* tree, Region region,
             uint8_t** img, volatile int* halt,
             void (*callback)())
{
    // Special interrupt system, set asynchronously by on high
    if (*halt)  return;

    // Render pixel-by-pixel if we're below a certain size.
    if (region.voxels > 0 && region.voxels < MIN_VOLUME) {
        if (callback)   (*callback)();
        region8(tree, region, img);
        return;
    }


    // Pre-emptively halt evaluation if all the points in this
    // region are already light.
    uint8_t L = region.L[region.nk] >> 8;
    bool cull = true;
    for (int row = region.jmin; cull && row < region.jmin + region.nj; ++row) {
        for (int col = region.imin; cull && col < region.imin + region.ni; ++col) {
            if (L > img[row][col]) {
                cull = false;
                break;
            }
        }
    }
    if (cull) return;

    Interval X = {region.X[0], region.X[region.ni]},
             Y = {region.Y[0], region.Y[region.nj]},
             Z = {region.Z[0], region.Z[region.nk]};

    Interval result = eval_i(tree, X, Y, Z);

    // If we're inside the object, fill with color.
    if (result.upper < 0) {
        for (int row = region.jmin; row < region.jmin + region.nj; ++row) {
            for (int col = region.imin; col < region.imin + region.ni; ++col) {
                if (L > img[row][col])  img[row][col] = L;
            }
        }
    }

    // In unambiguous cases, return immediately
    if (result.upper < 0 || result.lower >= 0)  return;

#if PRUNE
    disable_nodes(tree);
    disable_nodes_binary(tree);
#endif

    // Subdivide and recurse if we're not at voxel size.
    if (region.ni*region.nj*region.nk > 1) {
        Region A, B;

        bisect(region, &A, &B);

        render8(tree, B, img, halt, callback);
        render8(tree, A, img, halt, callback);
    }

#if PRUNE
    enable_nodes(tree);
#endif

}