Esempio n. 1
0
def test_modes():
    import mitsuba

    # Check that switching to double precision mode works
    eradiate.set_mode("mono_double")
    # We expect that the kernel variant is appropriately selected
    assert mitsuba.variant() == "scalar_mono_double"

    # Check that switching to mono mode works
    eradiate.set_mode("mono")
    # We expect that the kernel variant is appropriately selected
    assert mitsuba.variant() == "scalar_mono"
def create_stairs_packet(num_steps):
    assert mitsuba.variant() == 'packet_rgb'

    from mitsuba.render import Mesh

    size_step = 1.0 / num_steps

    m = Mesh("stairs", vertex_struct, 4 * num_steps, index_struct,
             4 * num_steps - 2)
    v = m.vertices()
    f = m.faces()

    for i in range(num_steps):
        h = i * size_step
        s1 = i * size_step
        s2 = (i + 1) * size_step
        k = 4 * i

        v[k + 0] = (0.0, s1, h)
        v[k + 1] = (1.0, s1, h)
        v[k + 2] = (0.0, s2, h)
        v[k + 3] = (1.0, s2, h)

        f[k] = (k, k + 1, k + 2)
        f[k + 1] = (k + 1, k + 3, k + 2)
        if i < num_steps - 1:
            f[k + 2] = (k + 2, k + 3, k + 5)
            f[k + 3] = (k + 5, k + 4, k + 2)

    m.recompute_bbox()
    return m
Esempio n. 3
0
    def check(self) -> None:
        """
        Perform basic checks on the dictionary:

        * check that the ``"type"`` parameter is included;
        * check if the variant for which the kernel dictionary was created is
          the same as the current one.

        Raises
        ------

        ValueError
            If the ``"type"`` parameter is missing.

        :class:`.KernelVariantError`
            If the variant for which the kernel dictionary was created is
            not the same as the current one
        """
        variant = mitsuba.variant()
        if self.variant != variant:
            raise KernelVariantError(
                f"scene dictionary created for kernel variant '{self.variant}', "
                f"incompatible with current variant '{variant}'"
            )

        if "type" not in self:
            raise ValueError("kernel scene dictionary is missing a 'type' parameter")
Esempio n. 4
0
 def __init__(self, path, split_files=False):
     from mitsuba import variant
     if not variant():
         mitsuba.set_variant('scalar_rgb')
     from mitsuba.core import PluginManager
     self.pmgr = PluginManager.instance()
     self.split_files = split_files
     self.scene_data = [
         {
             'type': 'scene'
         },  #MAIN
         {},  #MATS
         {},  #GEOM
         {},  #EMIT
         {}
     ]  #CAMS
     self.com_count = 0  # Counter for comment ids
     self.exported_ids = set()
     self.copy_count = {
         'tex': 0,
         'mesh': 0,
         'spectrum': 0
     }  # Counters for giving unique names to copied files
     self.copied_paths = {}
     self.files = []
     self.file_names = []  # Relative paths to the fragment files
     self.file_tabs = []
     self.file_stack = []
     self.current_file = Files.MAIN
     self.directory = ''  # scene foler
     self.set_filename(path)
def check_scene(int_name, scene_name, is_empty=False):
    from mitsuba.core.xml import load_string
    from mitsuba.core import Bitmap, Struct

    variant_name = mitsuba.variant()

    print("variant_name:", variant_name)

    integrator = make_integrator(int_name, "")
    scene = SCENES[scene_name]['factory']()
    integrator_type = {
        'direct': 'direct',
        'depth': 'depth',
        # All other integrators: 'full'
    }.get(int_name, 'full')
    sensor = scene.sensors()[0]

    avg = SCENES[scene_name][integrator_type]
    film = sensor.film()

    status = integrator.render(scene, sensor)
    assert status, "Rendering ({}) failed".format(variant_name)

    if False:
        _save(film, int_name, suffix='_' + variant_name)

    converted = film.bitmap(raw=True).convert(Bitmap.PixelFormat.RGBA, Struct.Type.Float32, False)
    values = np.array(converted, copy=False)
    means = np.mean(values, axis=(0, 1))
    # Very noisy images, so we add a tolerance
    assert ek.allclose(means, avg, rtol=5e-2), \
        "Mismatch: {} integrator, {} scene, {}".format(
            int_name, scene_name, variant_name)

    return np.array(film.bitmap(raw=False), copy=True)
Esempio n. 6
0
def get_ref_fname(scene_path):
    for color_mode in color_modes:
        if color_mode in mitsuba.variant():
            return join(
                dirname(scene_path), 'refs',
                os.path.splitext(basename(scene_path))[0] + '_ref_' +
                color_mode + '.exr')
    assert False
Esempio n. 7
0
def get_ref_fname(scene_fname):
    for color_mode in color_modes:
        if color_mode in mitsuba.variant():
            ref_fname = join(dirname(scene_fname), 'refs', splitext(
                basename(scene_fname))[0] + '_ref_' + color_mode + '.exr')
            var_fname = ref_fname.replace('.exr', '_var.exr')
            return ref_fname, var_fname
    assert False
Esempio n. 8
0
def _kernel_dict_get_mts_variant():
    variant = mitsuba.variant()

    if variant is not None:
        return variant
    else:
        raise KernelVariantError(
            "a kernel variant must be selected to create a KernelDict instance"
        )
Esempio n. 9
0
def fresolver_append_path(func):
    """Function decorator that adds the mitsuba project root
    to the FileResolver's search path. This is useful in particular
    for tests that e.g. load scenes, and need to specify paths to resources.

    The file resolver is restored to its previous state once the test's
    execution has finished.
    """
    if mitsuba.variant() == None:
        mitsuba.set_variant('scalar_rgb')

    from mitsuba.core import Thread, FileResolver
    par = os.path.dirname

    # Get the path to the source file from which this function is
    # being called.
    # Source: https://stackoverflow.com/a/24439444/3792942
    caller = getframeinfo(stack()[1][0])
    caller_path = par(caller.filename)

    # Heuristic to find the project's root directory
    def is_root(path):
        if not path:
            return False
        children = os.listdir(path)
        return ('ext' in children) and ('include' in children) \
               and ('src' in children) and ('resources' in children)

    root_path = caller_path
    while not is_root(root_path) and (par(root_path) != root_path):
        root_path = par(root_path)

    # The @wraps decorator properly sets __name__ and other properties, so that
    # pytest-xdist can keep track of the original test function.
    @wraps(func)
    def f(*args, **kwargs):
        # New file resolver
        thread = Thread.thread()
        fres_old = thread.file_resolver()
        fres = FileResolver(fres_old)

        # Append current test directory and project root to the
        # search path.
        fres.append(caller_path)
        fres.append(root_path)

        thread.set_file_resolver(fres)

        # Run actual function
        res = func(*args, **kwargs)

        # Restore previous file resolver
        thread.set_file_resolver(fres_old)

        return res

    return f
Esempio n. 10
0
    def get_plugin_tag(self, plugin_type):
        '''
        Get the corresponding tag of a given plugin (e.g. 'bsdf' for 'diffuse')
        If the given type (e.g. 'transform') is not a plugin, returns None.

        Params
        ------

        plugin_type: Name of the type (e.g. 'diffuse', 'ply'...)
        '''
        from mitsuba import variant
        class_ =  self.pmgr.get_plugin_class(plugin_type, variant())
        if not class_: # If get_plugin_class returns None, there is not corresponding plugin
            return None
        class_ = class_.parent()
        while class_.alias() == class_.name():
            class_ = class_.parent()
        return class_.alias()
Esempio n. 11
0
def test10_ray_intersect_preliminary(variants_all_rgb):

    if 'packet' in mitsuba.variant():
        pytest.skip(
            "pi.compute_surface_interaction isn't bound for packet modes")

    from mitsuba.core import xml, Ray3f, Vector3f, UInt32
    from mitsuba.render import HitComputeFlags

    scene = xml.load_string('''
        <scene version="2.0.0">
            <shape type="obj">
                <string name="filename" value="resources/data/common/meshes/rectangle.obj"/>
            </shape>
        </scene>
    ''')

    ray = Ray3f(Vector3f(-0.3, -0.3, -10.0), Vector3f(0.0, 0.0, 1.0), 0, [])
    pi = scene.ray_intersect_preliminary(ray)

    assert ek.allclose(pi.t, 10)
    assert pi.prim_index == 0
    assert ek.allclose(pi.prim_uv, [0.35, 0.3])

    si = pi.compute_surface_interaction(ray)
    assert ek.allclose(si.t, 10)
    assert ek.allclose(si.p, [-0.3, -0.3, 0.0])
    assert ek.allclose(si.uv, [0.35, 0.35])
    assert ek.allclose(si.dp_du, [2.0, 0.0, 0.0])
    assert ek.allclose(si.dp_dv, [0.0, 2.0, 0.0])

    ray = Ray3f(Vector3f(0.3, 0.3, -10.0), Vector3f(0.0, 0.0, 1.0), 0, [])
    pi = scene.ray_intersect_preliminary(ray)
    assert ek.allclose(pi.t, 10)
    assert pi.prim_index == 1
    assert ek.allclose(pi.prim_uv, [0.3, 0.35])

    si = pi.compute_surface_interaction(ray)
    assert ek.allclose(si.t, 10)
    assert ek.allclose(si.p, [0.3, 0.3, 0.0])
    assert ek.allclose(si.uv, [0.65, 0.65])
    assert ek.allclose(si.dp_du, [2.0, 0.0, 0.0])
    assert ek.allclose(si.dp_dv, [0.0, 2.0, 0.0])
Esempio n. 12
0
def test_render(variants_all, scene_fname):
    from mitsuba.core import Bitmap, Struct, Thread

    scene_dir = dirname(scene_fname)

    if os.path.split(scene_dir)[1] in EXCLUDE_FOLDERS:
        pytest.skip(f"Skip rendering scene {scene_fname}")

    Thread.thread().file_resolver().append(scene_dir)

    ref_fname = get_ref_fname(scene_fname)
    assert os.path.exists(ref_fname)

    scene = mitsuba.core.xml.load_file(scene_fname,
                                       parameters=[('spp', str(32))])
    scene.integrator().render(scene, scene.sensors()[0])

    film = scene.sensors()[0].film()

    cur_bitmap = film.bitmap(raw=True).convert(Bitmap.PixelFormat.RGB,
                                               Struct.Type.Float32, False)
    cur_image = np.array(cur_bitmap, copy=False)

    ref_bitmap = Bitmap(ref_fname).convert(Bitmap.PixelFormat.RGB,
                                           Struct.Type.Float32, False)
    ref_image = np.array(ref_bitmap, copy=False)

    error = np.mean(np.mean(np.abs(ref_image - cur_image)))
    threshold = 0.5 * np.mean(np.mean(ref_image))
    success = error < threshold

    if not success:
        print("Failed. error: {} // threshold: {}".format(error, threshold))

        # Write rendered image to a file
        cur_fname = os.path.splitext(
            scene_fname)[0] + '_render_' + mitsuba.variant() + '.exr'
        cur_bitmap.write(cur_fname)
        print('Saved rendered image to: ' + cur_fname)

        assert False
Esempio n. 13
0
def _check_variant():
    variant = mitsuba.variant()
    if variant not in _SUPPORTED_VARIANTS:
        raise KernelVariantError(f"unsupported kernel variant '{variant}'")
Esempio n. 14
0
def test_render(variants_all, scene_fname):
    from mitsuba.core import Bitmap, Struct, Thread, set_thread_count

    scene_dir = dirname(scene_fname)

    if os.path.split(scene_dir)[1] in EXCLUDE_FOLDERS:
        pytest.skip(f"Skip rendering scene {scene_fname}")

    Thread.thread().file_resolver().prepend(scene_dir)

    ref_fname, ref_var_fname = get_ref_fname(scene_fname)
    if not (exists(ref_fname) and exists(ref_var_fname)):
        pytest.skip("Non-existent reference data.")

    ref_bmp = read_rgb_bmp_to_xyz(ref_fname)
    ref_img = np.array(ref_bmp, copy=False)

    ref_var_bmp = read_rgb_bmp_to_xyz(ref_var_fname)
    ref_var_img = np.array(ref_var_bmp, copy=False)

    significance_level = 0.01

    # Compute spp budget
    sample_budget = int(2e6)
    pixel_count = ek.hprod(ref_bmp.size())
    spp = sample_budget // pixel_count

    # Load and render
    scene = mitsuba.core.xml.load_file(scene_fname, spp=spp)
    scene.integrator().render(scene, scene.sensors()[0])

    # Compute variance image
    bmp = scene.sensors()[0].film().bitmap(raw=False)
    img, var_img = bitmap_extract(bmp)

    # Compute Z-test p-value
    p_value = z_test(img, spp, ref_img, ref_var_img)

    # Apply the Sidak correction term, since we'll be conducting multiple independent
    # hypothesis tests. This accounts for the fact that the probability of a failure
    # increases quickly when several hypothesis tests are run in sequence.
    alpha = 1.0 - (1.0 - significance_level) ** (1.0 / pixel_count)

    success = (p_value > alpha)

    if (np.count_nonzero(success) / 3) >= (0.9975 * pixel_count):
        print('Accepted the null hypothesis (min(p-value) = %f, significance level = %f)' %
              (np.min(p_value), alpha))
    else:
        print('Reject the null hypothesis (min(p-value) = %f, significance level = %f)' %
              (np.min(p_value), alpha))

        output_dir = join(scene_dir, 'error_output')

        if not exists(output_dir):
            os.makedirs(output_dir)

        output_prefix = join(output_dir, splitext(
            basename(scene_fname))[0] + '_' + mitsuba.variant())

        img_rgb_bmp = xyz_to_rgb_bmp(img)

        fname = output_prefix + '_img.exr'
        img_rgb_bmp.write(fname)
        print('Saved rendered image to: ' + fname)

        var_fname = output_prefix + '_var.exr'
        xyz_to_rgb_bmp(var_img).write(var_fname)
        print('Saved variance image to: ' + var_fname)

        err_fname = output_prefix + '_error.exr'
        err_img = 0.02 * np.array(img_rgb_bmp)
        err_img[~success] = 1.0
        err_bmp = Bitmap(err_img).write(err_fname)
        print('Saved error image to: ' + err_fname)

        pvalue_fname = output_prefix + '_pvalue.exr'
        xyz_to_rgb_bmp(p_value).write(pvalue_fname)
        print('Saved error image to: ' + pvalue_fname)

        assert False
Esempio n. 15
0
def test02_render_empty_scene(variants_all_rgb, int_name):
    if not mitsuba.variant().startswith('gpu'):
        check_scene(int_name, 'empty', is_empty=True)
import mitsuba

if mitsuba.variant() == None:
    mitsuba.set_variant('scalar_rgb')

from mitsuba.core import Struct

# Some helper functions to generate simple meshes
vertex_struct = Struct() \
    .append("x", Struct.Type.Float32) \
    .append("y", Struct.Type.Float32) \
    .append("z", Struct.Type.Float32)
vdt = vertex_struct.dtype()

index_struct = Struct() \
    .append("i0", Struct.Type.UInt32) \
    .append("i1", Struct.Type.UInt32) \
    .append("i2", Struct.Type.UInt32)
idt = vertex_struct.dtype()


def create_single_triangle():
    from mitsuba.render import Mesh

    m = Mesh("tri", vertex_struct, 3, index_struct, 1)
    v = m.vertices()
    f = m.faces()
    v[0] = (0, 0, 0)
    v[1] = (1, 0.2, 0)
    v[2] = (0.2, 1, 0)
    f[0] = (0, 1, 2)