Example #1
0
def test_directional(mode_mono):
    from mitsuba.core.xml import load_dict

    # We need a default spectral config
    ctx = KernelDictContext()

    # Constructor
    d = DirectionalIllumination()
    assert load_dict(onedict_value(d.kernel_dict(ctx))) is not None

    # Check if a more detailed spec is valid
    d = DirectionalIllumination(irradiance={"type": "uniform", "value": 1.0})
    assert load_dict(onedict_value(d.kernel_dict(ctx))) is not None

    # Check if solar irradiance spectrum can be used
    d = DirectionalIllumination(irradiance={"type": "solar_irradiance"})
    assert load_dict(onedict_value(d.kernel_dict(ctx))) is not None

    # Check if specification from a float works
    d = DirectionalIllumination(irradiance=1.0)
    assert load_dict(onedict_value(d.kernel_dict(ctx))) is not None

    # Check if specification from a constant works
    d = DirectionalIllumination(irradiance=ureg.Quantity(1.0, "W/m^2/nm"))
    assert load_dict(onedict_value(d.kernel_dict(ctx))) is not None
    with pytest.raises(pinttr.exceptions.UnitsError):  # Wrong units
        DirectionalIllumination(irradiance=ureg.Quantity(1.0, "W/m^2/sr/nm"))
def test04_surface_area(variant_scalar_rgb):
    from mitsuba.core import xml, Transform4f

    # Unifomly-scaled rectangle
    rect = xml.load_dict({
        "type":
        "rectangle",
        "to_world":
        Transform4f([[2, 0, 0, 0], [0, 2, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
    })
    assert ek.allclose(rect.surface_area(), 2.0 * 2.0 * 2.0 * 2.0)

    # Rectangle sheared along the Z-axis
    rect = xml.load_dict({
        "type":
        "rectangle",
        "to_world":
        Transform4f([[1, 0, 0, 0], [0, 1, 0, 0], [1, 0, 1, 0], [0, 0, 0, 1]])
    })
    assert ek.allclose(rect.surface_area(), 2.0 * 2.0 * ek.sqrt(2.0))

    # Rectangle sheared along the X-axis (shouldn't affect surface_area)
    rect = xml.load_dict({
        "type":
        "rectangle",
        "to_world":
        Transform4f([[1, 1, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
    })
    assert ek.allclose(rect.surface_area(), 2.0 * 2.0)
Example #3
0
def example_scene(shape, scale=1.0, translate=[0, 0, 0], angle=0.0):
    from mitsuba.core import xml, ScalarTransform4f as T

    to_world = T.translate(translate) * T.rotate([0, 1, 0],
                                                 angle) * T.scale(scale)

    shape2 = shape.copy()
    shape2['to_world'] = to_world

    s = xml.load_dict({'type': 'scene', 'shape': shape2})

    s_inst = xml.load_dict({
        'type': 'scene',
        'group_0': {
            'type': 'shapegroup',
            'shape': shape
        },
        'instance': {
            'type': 'instance',
            "group": {
                "type": "ref",
                "id": "group_0"
            },
            'to_world': to_world
        }
    })

    return s, s_inst
def test01_create(variant_scalar_rgb):
    from mitsuba.core import xml, ScalarTransform4f

    s = xml.load_dict({"type": "sphere"})
    assert s is not None
    assert s.primitive_count() == 1
    assert ek.allclose(s.surface_area(), 4 * ek.pi)

    # Test transforms order in constructor

    rot = ScalarTransform4f.rotate([1.0, 0.0, 0.0], 35)

    s1 = xml.load_dict({
        "type": "sphere",
        "radius": 2.0,
        "center": [1, 0, 0],
        "to_world": rot
    })

    s2 = xml.load_dict({
        "type":
        "sphere",
        "to_world":
        rot * ScalarTransform4f.translate([1, 0, 0]) *
        ScalarTransform4f.scale(2)
    })

    assert str(s1) == str(s2)
Example #5
0
def test8_dict_unreferenced_attribute_error(variants_all_rgb):
    from mitsuba.core import xml
    with pytest.raises(Exception) as e:
        xml.load_dict({
            "type" : "point",
            "foo": 0.44
        })
    e.match("Unreferenced attribute")
Example #6
0
def test2_dict_missing_type(variants_all_rgb):
    from mitsuba.core import xml
    with pytest.raises(Exception) as e:
        xml.load_dict({
            "center" : [0, 0, -10],
            "radius" : 10.0,
        })
    e.match("""Missing key 'type'""")
def test03_ray_intersect(variant_scalar_rgb):
    from mitsuba.core import xml, Ray3f, Transform4f

    # Scalar
    scene = xml.load_dict({
        "type": "scene",
        "foo": {
            "type": "rectangle",
            "to_world": Transform4f.scale((2.0, 0.5, 1.0))
        }
    })

    n = 15
    coords = ek.linspace(Float, -1, 1, n)
    rays = [
        Ray3f(o=[a, a, 5], d=[0, 0, -1], time=0.0, wavelengths=[])
        for a in coords
    ]
    si_scalar = []
    valid_count = 0
    for i in range(n):
        its_found = scene.ray_test(rays[i])
        si = scene.ray_intersect(rays[i])

        assert its_found == (abs(coords[i]) <= 0.5)
        assert si.is_valid() == its_found
        si_scalar.append(si)
        valid_count += its_found

    assert valid_count == 7

    try:
        mitsuba.set_variant('packet_rgb')
        from mitsuba.core import xml, Ray3f as Ray3fX
    except ImportError:
        pytest.skip("packet_rgb mode not enabled")

    # Packet
    scene_p = xml.load_dict({
        "type": "scene",
        "foo": {
            "type": "rectangle",
            "to_world": Transform4f.scale((2.0, 0.5, 1.0))
        }
    })

    packet = Ray3fX.zero(n)
    for i in range(n):
        packet[i] = rays[i]

    si_p = scene_p.ray_intersect(packet)
    its_found_p = scene_p.ray_test(packet)

    assert ek.all(si_p.is_valid() == its_found_p)

    for i in range(n):
        assert ek.allclose(si_p.t[i], si_scalar[i].t)
Example #8
0
def test10_xml_rgb(variants_scalar_all):
    from mitsuba.python.xml import dict_to_xml
    from mitsuba.core.xml import load_dict, load_file
    from mitsuba.core import Thread, ScalarColor3f
    fr = Thread.thread().file_resolver()
    mts_root = str(fr[len(fr) - 1])
    filepath = os.path.join(mts_root, 'resources/data/scenes/dict10/dict.xml')
    fr.append(os.path.dirname(filepath))

    d1 = {
        'type': 'scene',
        'point': {
            "type": "point",
            "intensity": {
                "type": "rgb",
                "value": ScalarColor3f(0.5, 0.2, 0.5)
            }
        }
    }

    d2 = {
        'type': 'scene',
        'point': {
            "type": "point",
            "intensity": {
                "type": "rgb",
                "value": [0.5, 0.2, 0.5]  # list -> ScalarColor3f
            }
        }
    }

    dict_to_xml(d1, filepath)
    s1 = load_file(filepath)
    dict_to_xml(d2, filepath)
    s2 = load_file(filepath)
    s3 = load_dict(d1)
    assert str(s1) == str(s2)
    assert str(s1) == str(s3)

    d1 = {
        'type': 'scene',
        'point': {
            "type": "point",
            "intensity": {
                "type": "rgb",
                "value": 0.5  # float -> ScalarColor3f
            }
        }
    }

    dict_to_xml(d1, filepath)
    s1 = load_file(filepath)
    s2 = load_dict(d1)
    assert str(s1) == str(s2)
    rmtree(os.path.split(filepath)[0])
Example #9
0
def test10_dict_expand_nested_object(variant_scalar_rgb):
    from mitsuba.core import xml
    # Nested dictionary objects should be expanded
    b0 = xml.load_dict({
        "type" : "diffuse",
        "reflectance" : {
            "type" : "bitmap",
            "filename" : "resources/data/common/textures/museum.exr"
        }
    })

    b1 = xml.load_string("""
        <bsdf type="diffuse" version="2.0.0">
            <texture type="bitmap" name="reflectance">
                <string name="filename" value="resources/data/common/textures/museum.exr"/>
            </texture>
        </bsdf>
    """)

    assert str(b0) == str(b1)

    # Check that root object isn't expanded
    texture = xml.load_dict({
            "type" : "bitmap",
            "filename" : "resources/data/common/textures/museum.exr"
    })
    assert len(texture.expand()) == 1

    # But we should be able to use this object in another dict, and it will be expanded
    b3 = xml.load_dict({
        "type" : "diffuse",
        "reflectance" : texture
    })
    assert str(b0) == str(b3)

    # Object should be expanded when used through a reference
    scene = xml.load_dict({
        "type" : "scene",
        "mytexture" : {
            "type" : "bitmap",
            "filename" : "resources/data/common/textures/museum.exr"
        },
        "shape1" : {
            "type" : "sphere",
            "bsdf" : {
                "type" : "diffuse",
                "reflectance" : {
                    "type" : "ref",
                    "id" : "mytexture"
                }
            }
        },
    })
    assert str(b0) == str(scene.shapes()[0].bsdf())
Example #10
0
def test_incoming_flux_integrator(variant_scalar_rgb, radiance):
    """
    We test the recorded power density of the irradiance meter, by creating a simple scene:
    The irradiance meter is attached to a sphere with unit radius at the coordinate origin
    surrounded by a constant environment emitter.
    We render the scene with the path tracer integrator and compare the recorded  power
    density with our theoretical expectation.
    We expect the average value to be \\pi * L with L the radiance of the constant
    emitter.
    """

    from mitsuba.core import Spectrum, Bitmap, Struct, ScalarVector3f
    from mitsuba.core.xml import load_dict

    scene_dict = {
        "type": "scene",
        "sensor": sensor_shape_dict(1, ScalarVector3f(0, 0, 0)),
        "emitter": constant_emitter_dict(radiance),
        "integrator": {"type": "path"}
    }

    scene = load_dict(scene_dict)
    sensor = scene.sensors()[0]

    scene.integrator().render(scene, sensor)
    film = sensor.film()

    img = film.bitmap(raw=True).convert(Bitmap.PixelFormat.Y,
                                        Struct.Type.Float32, srgb_gamma=False)
    image_np = np.array(img)

    ek.allclose(image_np, (radiance * ek.pi))
Example #11
0
def create_camera(o,
                  d,
                  fov=34,
                  fov_axis="x",
                  s_open=1.5,
                  s_close=5,
                  aperture=0.1,
                  focus_dist=15):
    from mitsuba.core.xml import load_dict
    from mitsuba.core import ScalarTransform4f, ScalarVector3f
    t = [o[0] + d[0], o[1] + d[1], o[2] + d[2]]

    camera_dict = {
        "type": "thinlens",
        "near_clip": 1.0,
        "far_clip": 35.0,
        "focus_distance": focus_dist,
        "aperture_radius": aperture,
        "fov": fov,
        "fov_axis": fov_axis,
        "shutter_open": s_open,
        "shutter_close": s_close,
        "to_world": ScalarTransform4f.look_at(origin=o, target=t, up=[0, 1,
                                                                      0]),
        "film": {
            "type": "hdrfilm",
            "width": 512,
            "height": 256,
        }
    }

    return load_dict(camera_dict)
Example #12
0
def test03_ray_intersect_instance(variants_all_rgb):
    from mitsuba.core import xml, Ray3f, ScalarVector3f, ScalarTransform4f as T
    """Check that we can the correct instance pointer when tracing a ray"""

    scene = xml.load_dict({
        'type': 'scene',
        'group_0': {
            'type': 'shapegroup',
            'shape': {
                'type': 'rectangle'
            }
        },
        'instance_00': {
            'type': 'instance',
            "group": {
                "type": "ref",
                "id": "group_0"
            },
            'to_world': T.translate([-0.5, -0.5, 0.0]) * T.scale(0.5)
        },
        'instance_01': {
            'type': 'instance',
            "group": {
                "type": "ref",
                "id": "group_0"
            },
            'to_world': T.translate([-0.5, 0.5, 0.0]) * T.scale(0.5)
        },
        'instance_10': {
            'type': 'instance',
            "group": {
                "type": "ref",
                "id": "group_0"
            },
            'to_world': T.translate([0.5, -0.5, 0.0]) * T.scale(0.5)
        },
        'shape': {
            'type': 'rectangle',
            'to_world': T.translate([0.5, 0.5, 0.0]) * T.scale(0.5)
        }
    })

    ray = Ray3f([-0.5, -0.5, -12], [0.0, 0.0, 1.0], 0.0, [])
    pi = scene.ray_intersect_preliminary(ray)
    assert '[0.5, 0, 0, -0.5]' in str(pi)
    assert '[0, 0.5, 0, -0.5]' in str(pi)

    ray = Ray3f([-0.5, 0.5, -12], [0.0, 0.0, 1.0], 0.0, [])
    pi = scene.ray_intersect_preliminary(ray)
    assert '[0.5, 0, 0, -0.5]' in str(pi)
    assert '[0, 0.5, 0, 0.5]' in str(pi)

    ray = Ray3f([0.5, -0.5, -12], [0.0, 0.0, 1.0], 0.0, [])
    pi = scene.ray_intersect_preliminary(ray)
    assert '[0.5, 0, 0, 0.5]' in str(pi)
    assert '[0, 0.5, 0, -0.5]' in str(pi)

    ray = Ray3f([0.5, 0.5, -12], [0.0, 0.0, 1.0], 0.0, [])
    pi = scene.ray_intersect_preliminary(ray)
    assert 'instance = nullptr' in str(pi) or 'instance = [nullptr]' in str(pi)
def test01_create(variant_scalar_rgb):
    from mitsuba.core import xml

    s = xml.load_dict({"type": "rectangle"})
    assert s is not None
    assert s.primitive_count() == 1
    assert ek.allclose(s.surface_area(), 4.0)
Example #14
0
def test01_xml_save_plugin(variant_scalar_rgb):
    from mitsuba.core import xml
    from mitsuba.core import Thread
    from mitsuba.python.xml import dict_to_xml
    fr = Thread.thread().file_resolver()
    # Add the path to the mitsuba root folder, so that files are always saved in mitsuba/resources/...
    # This way we know where to look for the file in case the unit test fails
    mts_root = str(fr[len(fr) - 1])
    filepath = os.path.join(mts_root, 'resources/data/scenes/dict01/dict.xml')
    fr.append(os.path.dirname(filepath))
    scene_dict = {
        "type": "sphere",
        "center": [0, 0, -10],
        "radius": 10.0,
    }
    dict_to_xml(scene_dict, filepath)
    s1 = xml.load_dict({
        'type': 'scene',
        'sphere': {
            "type": "sphere",
            "center": [0, 0, -10],
            "radius": 10.0,
        }
    })
    s2 = xml.load_file(filepath)
    assert str(s1) == str(s2)
    rmtree(os.path.split(filepath)[0])
def create_emitter_and_spectrum(lookat, cutoff_angle, s_key='d65'):
    from mitsuba.core.xml import load_dict

    spectrum = load_dict(spectrum_strings[s_key])
    expanded = spectrum.expand()
    if len(expanded) == 1:
        spectrum = expanded[0]

    emitter = load_dict({
        'type': 'spot',
        'cutoff_angle': cutoff_angle,
        'to_world': lookat,
        'intensity': spectrum
    })

    return emitter, spectrum
def test04_sample_direct(variant_scalar_rgb):
    from mitsuba.core import xml, Ray3f
    from mitsuba.render import Interaction3f

    sphere = xml.load_dict({"type": "sphere"})

    def sample_cone(sample, cos_theta_max):
        cos_theta = (1 - sample[1]) + sample[1] * cos_theta_max
        sin_theta = ek.sqrt(1 - cos_theta * cos_theta)
        phi = 2 * ek.pi * sample[0]
        s, c = ek.sin(phi), ek.cos(phi)
        return [c * sin_theta, s * sin_theta, cos_theta]

    it = Interaction3f.zero()
    it.p = [0, 0, -3]
    it.t = 0
    sin_cone_angle = 1.0 / it.p[2]
    cos_cone_angle = ek.sqrt(1 - sin_cone_angle**2)

    for xi_1 in ek.linspace(Float, 0, 1, 10):
        for xi_2 in ek.linspace(Float, 1e-3, 1 - 1e-3, 10):
            sample = sphere.sample_direction(it, [xi_2, 1 - xi_1])
            d = sample_cone([xi_1, xi_2], cos_cone_angle)
            its = sphere.ray_intersect(Ray3f(it.p, d, 0, []))
            assert ek.allclose(d, sample.d, atol=1e-5, rtol=1e-5)
            assert ek.allclose(its.t, sample.dist, atol=1e-5, rtol=1e-5)
            assert ek.allclose(its.p, sample.p, atol=1e-5, rtol=1e-5)
Example #17
0
def test01_create(variant_scalar_rgb):
    from mitsuba.core import xml, ScalarTransform4f

    s = xml.load_dict({
        'type': 'shapegroup',
        'shape_01': {
            'type': 'sphere',
            'radius': 1.0,
            'to_world': ScalarTransform4f.translate([-2, 0, 0])
        },
        'shape_02': {
            'type': 'sphere',
            'radius': 1.0,
            'to_world': ScalarTransform4f.translate([2, 0, 0])
        }
    })

    b = s.bbox()
    assert s is not None
    assert s.primitive_count() == 2
    assert s.effective_primitive_count() == 0
    assert s.surface_area() == 0
    assert ek.allclose(b.center(), [0, 0, 0])
    assert ek.allclose(b.min, [-3, -1, -1])
    assert ek.allclose(b.max, [3, 1, 1])
Example #18
0
def test09_xml_decompose_transform(variant_scalar_rgb):
    from mitsuba.python.xml import dict_to_xml
    from mitsuba.core.xml import load_dict, load_file
    from mitsuba.core import Transform4f, Vector3f, Thread
    fr = Thread.thread().file_resolver()
    mts_root = str(fr[len(fr) - 1])
    filepath = os.path.join(mts_root, 'resources/data/scenes/dict09/dict.xml')
    fr.append(os.path.dirname(filepath))
    scene_dict = {
        'type': 'scene',
        'cam': {
            'type':
            'perspective',
            'fov_axis':
            'x',
            'fov':
            35,
            'to_world':
            Transform4f.look_at(Vector3f(15, 42.3,
                                         25), Vector3f(1.0, 0.0, 0.5),
                                Vector3f(1.0, 0.0, 0.0))
        }
    }
    dict_to_xml(scene_dict, filepath)
    s1 = load_file(filepath)
    s2 = load_dict(scene_dict)
    vects = [Vector3f(0, 0, 1), Vector3f(0, 1, 0), Vector3f(1, 0, 0)]
    tr1 = s1.sensors()[0].world_transform().eval(0)
    tr2 = s2.sensors()[0].world_transform().eval(0)
    for vec in vects:
        assert tr1.transform_point(vec) == tr2.transform_point(vec)
    rmtree(os.path.split(filepath)[0])
Example #19
0
def test08_xml_defaults(variant_scalar_rgb):
    from mitsuba.python.xml import dict_to_xml
    from mitsuba.core import Thread
    from mitsuba.core.xml import load_dict, load_file
    fr = Thread.thread().file_resolver()
    mts_root = str(fr[len(fr) - 1])
    filepath = os.path.join(mts_root, 'resources/data/scenes/dict08/dict.xml')
    fr.append(os.path.dirname(filepath))
    spp = 250
    resx = 1920
    resy = 1080
    scene_dict = {
        'type': 'scene',
        'cam': {
            'type': 'perspective',
            'fov_axis': 'x',
            'fov': 35,
            'sampler': {
                'type': 'independent',
                'sample_count': spp  # --> default
            },
            'film': {
                'type': 'hdrfilm',
                'width': resx,  # --> default
                'height': resy  # --> default
            }
        }
    }
    dict_to_xml(scene_dict, filepath)
    # Load a file using default values
    s1 = load_file(filepath)
    s2 = load_dict(scene_dict)
    assert str(s1.sensors()[0].film()) == str(s2.sensors()[0].film())
    assert str(s1.sensors()[0].sampler()) == str(s2.sensors()[0].sampler())
    # Set new parameters
    spp = 45
    resx = 2048
    resy = 485
    # Load a file with options for the rendering parameters
    s3 = load_file(filepath, spp=spp, resx=resx, resy=resy)
    scene_dict['cam']['sampler']['sample_count'] = spp
    scene_dict['cam']['film']['width'] = resx
    scene_dict['cam']['film']['height'] = resy
    s4 = load_dict(scene_dict)
    assert str(s3.sensors()[0].film()) == str(s4.sensors()[0].film())
    assert str(s3.sensors()[0].sampler()) == str(s4.sensors()[0].sampler())
    rmtree(os.path.split(filepath)[0])
Example #20
0
def test5_dict_nested_object(variants_all_rgb):
    from mitsuba.core import xml

    bsdf = xml.load_dict({"type" : "diffuse"})

    s1 = xml.load_dict({
        "type" : "sphere",
        "bsdf" : bsdf
    })

    s2 = xml.load_string("""
        <shape type="sphere" version="2.0.0">
            <bsdf type="diffuse"/>
        </shape>
    """)

    assert str(s1.bsdf()) == str(s2.bsdf())
Example #21
0
def test03_ray_intersect(variant_scalar_rgb):
    from mitsuba.core import xml, Ray3f, Transform4f

    for r in [1, 2, 4]:
        for l in [1, 5]:
            s = xml.load_dict({
                "type": "scene",
                "foo": {
                    "type": "cylinder",
                    "to_world": Transform4f.scale((r, r, l))
                }
            })

            # grid size
            n = 10
            for x in ek.linspace(Float, -1, 1, n):
                for z in ek.linspace(Float, -1, 1, n):
                    x = 1.1 * r * x
                    z = 1.1 * l * z

                    ray = Ray3f(o=[x, -10, z],
                                d=[0, 1, 0],
                                time=0.0,
                                wavelengths=[])
                    si_found = s.ray_test(ray)
                    si = s.ray_intersect(ray)

                    assert si_found == si.is_valid()
                    assert si_found == ek.allclose(si.p[0]**2 + si.p[1]**2,
                                                   r**2)

                    if si_found:
                        ray = Ray3f(o=[x, -10, z],
                                    d=[0, 1, 0],
                                    time=0.0,
                                    wavelengths=[])

                        si = s.ray_intersect(ray)
                        ray_u = Ray3f(ray)
                        ray_v = Ray3f(ray)
                        eps = 1e-4
                        ray_u.o += si.dp_du * eps
                        ray_v.o += si.dp_dv * eps
                        si_u = s.ray_intersect(ray_u)
                        si_v = s.ray_intersect(ray_v)

                        dn = si.shape.normal_derivative(si, True, True)

                        if si_u.is_valid():
                            dp_du = (si_u.p - si.p) / eps
                            dn_du = (si_u.n - si.n) / eps
                            assert ek.allclose(dp_du, si.dp_du, atol=2e-2)
                            assert ek.allclose(dn_du, dn[0], atol=2e-2)
                        if si_v.is_valid():
                            dp_dv = (si_v.p - si.p) / eps
                            dn_dv = (si_v.n - si.n) / eps
                            assert ek.allclose(dp_dv, si.dp_dv, atol=2e-2)
                            assert ek.allclose(dn_dv, dn[1], atol=2e-2)
Example #22
0
def test01_ldsampler_scalar(variant_scalar_rgb):
    from mitsuba.core import xml

    sampler = xml.load_dict({
        "type" : "ldsampler",
        "sample_count" : 1024,
    })

    check_uniform_scalar_sampler(sampler)
def test01_orthogonal_scalar(variant_scalar_rgb):
    from mitsuba.core import xml

    sampler = xml.load_dict({
        "type": "orthogonal",
        "sample_count": 1369,
    })

    check_uniform_scalar_sampler(sampler, res=4, atol=4.0)
def test02_orthogonal_wavefront(variant_gpu_rgb):
    from mitsuba.core import xml

    sampler = xml.load_dict({
        "type": "orthogonal",
        "sample_count": 1369,
    })

    check_uniform_wavefront_sampler(sampler, atol=4.0)
Example #25
0
def test02_ldsampler_wavefront(variant_gpu_rgb):
    from mitsuba.core import xml

    sampler = xml.load_dict({
        "type" : "ldsampler",
        "sample_count" : 1024,
    })

    check_uniform_wavefront_sampler(sampler)
Example #26
0
def test3_dict_simple_field(variants_all_rgb):
    from mitsuba.core import xml, ScalarPoint3f
    import numpy as np

    s1 = xml.load_dict({
        "type" : "sphere",
        "center" : ScalarPoint3f(0, 0, -10),
        "radius" : 10.0,
        "flip_normals" : False,
    })

    s2 = xml.load_dict({
        "type" : "sphere",
        "center" : [0, 0, -10], # list -> ScalarPoint3f
        "radius" : 10, # int -> float
        "flip_normals" : False,
    })

    s3 = xml.load_dict({
        "type" : "sphere",
        "center" : np.array([0, 0, -10]), # numpy array -> ScalarPoint3f
        "radius" : 10.0,
        "flip_normals" : False,
    })

    s4 = xml.load_dict({
        "type" : "sphere",
        "center" : (0, 0, -10), # tuple -> ScalarPoint3f
        "radius" : 10.0,
        "flip_normals" : False,
    })

    s5 = xml.load_string("""
        <shape type="sphere" version="2.0.0">
            <point name="center" value="0.0 0.0 -10.0"/>
            <float name="radius" value="10.0"/>
            <boolean name="flip_normals" value="false"/>
        </shape>
    """)

    assert str(s1) == str(s2)
    assert str(s1) == str(s3)
    assert str(s1) == str(s4)
    assert str(s1) == str(s5)
Example #27
0
def test7_dict_spectrum(variants_scalar_all):
    from mitsuba.core import xml

    e1 = xml.load_dict({
        "type" : "point",
        "intensity" : {
            "type" : "spectrum",
            "value" : [(400, 0.1), (500, 0.2), (600, 0.4), (700, 0.1)]
        }
    })

    e2 = xml.load_string("""
        <emitter type="point" version="2.0.0">
            <spectrum name="intensity" value="400:0.1 500:0.2 600:0.4 700:0.1"/>
        </emitter>
    """)

    assert str(e1) == str(e2)

    e1 = xml.load_dict({
        "type" : "point",
        "intensity" : {
            "type" : "spectrum",
            "value" : 0.44
        }
    })

    e2 = xml.load_string("""
        <emitter type="point" version="2.0.0">
            <spectrum name="intensity" value="0.44"/>
        </emitter>
    """)

    assert str(e1) == str(e2)

    with pytest.raises(Exception) as e:
        xml.load_dict({
            "type" : "point",
            "intensity" : {
                "type" : "spectrum",
                "value" : [(400, 0.1), (500, 0.2), (300, 0.4)]
            }
        })
    e.match("Wavelengths must be specified in increasing order")
Example #28
0
def test02_error(variant_scalar_rgb):
    from mitsuba.core import xml

    error = "Nested instancing is not permitted"
    with pytest.raises(RuntimeError, match='.*{}.*'.format(error)):
        xml.load_dict({
            'type': 'shapegroup',
            'shape_01': {
                'type': 'instance',
                'shapegroup': {
                    'type': 'shapegroup',
                    'shape_01': {
                        'type': 'sphere',
                    },
                }
            },
        })

    error = "Nested ShapeGroup is not permitted"
    with pytest.raises(RuntimeError, match='.*{}.*'.format(error)):
        xml.load_dict({
            'type': 'shapegroup',
            'shape_01': {
                'type': 'shapegroup',
                'shape': {
                    'type': 'sphere'
                },
            },
        })

    error = "Instancing of emitters is not supported"
    with pytest.raises(RuntimeError, match='.*{}.*'.format(error)):
        xml.load_dict({
            'type': 'shapegroup',
            'shape_01': {
                'type': 'sphere',
                'emitter': {
                    'type': 'area'
                }
            },
        })

    error = "Instancing of sensors is not supported"
    with pytest.raises(RuntimeError, match='.*{}.*'.format(error)):
        xml.load_dict({
            'type': 'shapegroup',
            'shape_01': {
                'type': 'sphere',
                'sensor': {
                    'type': 'perspective'
                }
            },
        })
Example #29
0
def test6_dict_rgb(variants_scalar_all):
    from mitsuba.core import xml, ScalarColor3f

    e1 = xml.load_dict({
        "type" : "point",
        "intensity" : {
            "type": "rgb",
            "value" : ScalarColor3f(0.5, 0.2, 0.5)
        }
    })

    e2 = xml.load_dict({
        "type" : "point",
        "intensity" : {
            "type": "rgb",
            "value" : [0.5, 0.2, 0.5] # list -> ScalarColor3f
        }
    })

    e3 = xml.load_string("""
        <emitter type="point" version="2.0.0">
            <rgb name="intensity" value="0.5, 0.2, 0.5"/>
        </emitter>
    """)

    assert str(e1) == str(e2)
    assert str(e1) == str(e3)

    e1 = xml.load_dict({
        "type" : "point",
        "intensity" : {
            "type": "rgb",
            "value" : 0.5 # float -> ScalarColor3f
        }
    })

    e2 = xml.load_string("""
        <emitter type="point" version="2.0.0">
            <rgb name="intensity" value="0.5"/>
        </emitter>
    """)

    assert str(e1) == str(e2)
Example #30
0
def test05_differentiable_surface_interaction_ray_forward(
        variant_gpu_autodiff_rgb):
    from mitsuba.core import xml, Ray3f, Vector3f, UInt32

    shape = xml.load_dict({'type': 'sphere'})

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

    ek.set_requires_gradient(ray.o)
    ek.set_requires_gradient(ray.d)

    # If the ray origin is shifted along the x-axis, so does si.p
    si = pi.compute_surface_interaction(ray)
    ek.forward(ray.o.x)
    assert ek.allclose(ek.gradient(si.p), [1, 0, 0])

    # If the ray origin is shifted along the z-axis, so does si.p
    si = pi.compute_surface_interaction(ray)
    ek.forward(ray.o.z)
    assert ek.allclose(ek.gradient(si.p), [0, 0, 1])

    # If the ray origin is shifted along the y-axis, so does si.t
    si = pi.compute_surface_interaction(ray)
    ek.forward(ray.o.y)
    assert ek.allclose(ek.gradient(si.t), -1)

    # If the ray direction is shifted along the x-axis, so does si.p
    si = pi.compute_surface_interaction(ray)
    ek.forward(ray.d.x)
    assert ek.allclose(ek.gradient(si.p), [9, 0, 0])

    # If the ray origin is shifted tangent to the sphere (azimuth), so si.uv.x move by 1 / 2pi
    ek.set_requires_gradient(ray.o)
    si = shape.ray_intersect(ray)
    ek.forward(ray.o.x)
    assert ek.allclose(ek.gradient(si.uv), [1 / (2.0 * ek.pi), 0])

    # If the ray origin is shifted tangent to the sphere (inclination), so si.uv.y move by 2 / 2pi
    ek.set_requires_gradient(ray.o)
    si = shape.ray_intersect(ray)
    ek.forward(ray.o.z)
    assert ek.allclose(ek.gradient(si.uv), [0, -2 / (2.0 * ek.pi)])

    # # If the ray origin is shifted along the x-axis, so does si.n
    ek.set_requires_gradient(ray.o)
    si = shape.ray_intersect(ray)
    ek.forward(ray.o.x)
    assert ek.allclose(ek.gradient(si.n), [1, 0, 0])

    # # If the ray origin is shifted along the z-axis, so does si.n
    ek.set_requires_gradient(ray.o)
    si = shape.ray_intersect(ray)
    ek.forward(ray.o.z)
    assert ek.allclose(ek.gradient(si.n), [0, 0, 1])