Beispiel #1
0
def dual_contour(data, res, dims, coarse_level):
    # Compute vertices
    dc_verts = []
    vindex = {}
    for x, y, z in it.product(np.arange(dims['xmin'], dims['xmax'], res), np.arange(dims['ymin'], dims['ymax'], res),
                              np.arange(dims['zmin'], dims['zmax'], res)):
        o = np.array([float(x), float(y), float(z)])

        cube_signs = []
        # Get signs for cube
        for v in cube_verts:
            position = (o + v * res)
            key = tuple(position)
            c = True
            if key in data:
                c = data[key] > 0
            cube_signs.append(c)

        if all(cube_signs) or not any(cube_signs):
            continue

        # Estimate hermite data
        h_data = []
        for e in cube_edges:
            if cube_signs[e[0]] != cube_signs[e[1]]:
                h_data.append(estimate_hermite(data, o + cube_verts[e[0]] * res, o + cube_verts[e[1]] * res))

        counter = 0
        v = np.array([0.0, 0.0, 0.0])

        for p in h_data:
            v += np.array(p)
            counter += 1

        v /= 1.0 * counter

        # Throw out failed solutions
        if la.norm(v - o) > 2 * res:
            continue

        # Emit one vertex per every cube that crosses
        vindex[tuple(o)] = len(dc_verts)
        dc_verts.append(v)

    # Construct faces
    dc_quads = []
    for x, y, z in it.product(np.arange(dims['xmin'], dims['xmax'], res), np.arange(dims['ymin'], dims['ymax'], res),
                              np.arange(dims['zmin'], dims['zmax'], res)):
        if not (x, y, z) in vindex:
            continue

        # Emit one edge per each edge that crosses
        o = np.array([float(x), float(y), float(z)])
        for i in range(3):
            for j in range(i):
                if tuple(o + res * dirs[i]) in vindex and tuple(o + res * dirs[j]) in vindex and tuple(
                                o + res * (dirs[i] + dirs[j])) in vindex:
                    k = 3 - (i + j)  # normal id
                    c = True
                    d = True
                    key_ij = tuple(o + res * dirs[i] + res * dirs[j])
                    key_ijk = tuple(o + res * dirs[i] + res * dirs[j] + res * dirs[k])
                    if key_ij in data:
                        c = data[key_ij] > 0
                    if key_ijk in data:
                        d = data[key_ijk] > 0
                    if c != d:
                        dc_quads.append([vindex[tuple(o)], vindex[tuple(o + res * dirs[i])],
                                         vindex[tuple(o + res * dirs[i] + res * dirs[j])],
                                         vindex[tuple(o + res * dirs[j])]])
    if coarse_level:
        dc_verts, dc_quads = resolve_manifold_edges(dc_verts, vindex, dc_quads, data, res)

    return np.array(dc_verts), dc_quads
Beispiel #2
0
def dual_contour(dataset, res_fine, is_coarse_level, do_manifold_treatment):
    """
    Applies the dual contouring algorithm to the dataset
    :param dataset: input dataset
    :param res_fine: resolution of the finest level
    :param is_coarse_level: bool gives information whether this is the coarse level
    :param do_manifold_treatment: bool states whether manifold edges should be resolved
    :return: vertices, quads and manifold edges
    """

    # Compute vertices
    dc_verts = []
    vindex = {}

    res = dataset._resolution

    print "+ generating vertices +"
    voxel_count = 0
    voxel_total = dataset.get_total_voxels()
    number_of_cube_verts = np.size(cube_verts, 0)
    for x, y, z in dataset.get_grid_iterator():
        if voxel_count % ((voxel_total + 100) / 100) == 0:
            print "%d%% generating vertices: processing voxel %d of %d." % (
                100 * voxel_count / voxel_total, voxel_count, voxel_total)
        voxel_count += 1
        o = np.array([float(x), float(y), float(z)])

        cube_signs = np.zeros(number_of_cube_verts, dtype=bool)
        # Get signs for cube
        for i in range(number_of_cube_verts):
            position = (o + cube_verts[i, :] * res)
            key = tuple(position)
            cube_signs[i] = dataset[key]

        if all(cube_signs) or not any(cube_signs):
            continue

        # Estimate hermite data
        h_data = []
        for e in cube_edges:
            if cube_signs[e[0]] != cube_signs[e[1]]:
                h_data.append(
                    estimate_hermite(dataset, o + cube_verts[e[0]] * res, o + cube_verts[e[1]] * res, res, res_fine))

        counter = 0
        v = np.array([0.0, 0.0, 0.0])

        for p in h_data:
            v += np.array(p)
            counter += 1

        v /= 1.0 * counter

        # Emit one vertex per every cube that crosses
        vindex[tuple(o)] = len(dc_verts)
        dc_verts.append(v)

    dc_quads = []
    if is_coarse_level:
        # Construct faces
        print "+ generating faces +"
        voxel_count = 0
        for x, y, z in dataset.get_grid_iterator():
            if voxel_count % ((voxel_total + 100) / 100) == 0:
                print "%d%% generating faces: processing voxel %d of %d." % (
                    100 * voxel_count / voxel_total, voxel_count, voxel_total)
            voxel_count += 1
            if not (x, y, z) in vindex:
                continue

            # Emit one edge per each edge that crosses
            o = np.array([float(x), float(y), float(z)])
            for i in range(3):
                for j in range(i):
                    if tuple(o + res * dirs[i]) in vindex and \
                                    tuple(o + res * dirs[j]) in vindex and \
                                    tuple(o + res * (dirs[i] + dirs[j])) \
                                    in vindex:
                        k = 3 - (i + j)  # normal id
                        c = True
                        d = True
                        key_ij = tuple(o + res * dirs[i] + res * dirs[j])
                        key_ijk = tuple(o + res * dirs[i] + res * dirs[j] + res * dirs[k])
                        if dataset.point_is_inside(key_ij):
                            c = dataset[key_ij]
                        if dataset.point_is_inside(key_ijk):
                            d = dataset[key_ijk]
                        if c != d:
                            dc_quads.append([vindex[tuple(o)],
                                             vindex[tuple(o + res * dirs[i])],
                                             vindex[tuple(o + res * dirs[i] + res * dirs[j])],
                                             vindex[tuple(o + res * dirs[j])]])

    dc_manifold_edges = []
    if do_manifold_treatment:
        print "+ manifold treatment +"
        dc_verts, dc_quads, dc_manifold_edges, not_resolved_edges = resolve_manifold_edges(dc_verts, vindex, dc_quads,
                                                                                           dataset)
    else:
        dc_manifold_edges = []
        not_resolved_edges = []

    return np.array(dc_verts), np.array(dc_quads), dc_manifold_edges, not_resolved_edges