예제 #1
0
 def test_input(value, valid):
     expected = (r'.*unreferenced property ."test_number".*' if valid
                 else r'could not parse floating point value "{}".'.format(value))
     with pytest.raises(Exception, match=expected):
         xml.load_string("""<scene version="2.0.0">
                    <float name="test_number" value="{}"/>
                    </scene>""".format(value))
예제 #2
0
def test12_missing_attribute(variant_scalar_rgb):
    from mitsuba.core import xml

    with pytest.raises(Exception) as e:
        xml.load_string("""<scene version="2.0.0">
                   <integer name="a"/></scene>""")
    e.match('missing attribute "value" in element "integer".')
예제 #3
0
def test03_invalid_root_node(variant_scalar_rgb):
    from mitsuba.core import xml

    with pytest.raises(Exception) as e:
        xml.load_string('<?xml version="1.0"?><integer name="a" '
                   'value="10"></integer>')
    e.match('root element "integer" must be an object')
예제 #4
0
def create_emitter_and_spectrum(lookat, cutoff_angle, s_key='d65'):
    from mitsuba.core.xml import load_string
    emitter = load_string("""<emitter version='2.0.0' type='spot'>
                                <float name='cutoff_angle' value='{ca}'/>
                                <transform name='to_world'>
                                    <lookat origin='{px}, {py}, {pz}' target='{tx}, {ty}, {tz}' up='{ux}, {uy}, {uz}'/>
                                </transform>
                                {s}
                             </emitter>""".format(ca=cutoff_angle,
                                                  px=lookat["pos"][0],
                                                  py=lookat["pos"][1],
                                                  pz=lookat["pos"][2],
                                                  tx=lookat["target"][0],
                                                  ty=lookat["target"][1],
                                                  tz=lookat["target"][2],
                                                  ux=lookat["up"][0],
                                                  uy=lookat["up"][1],
                                                  uz=lookat["up"][2],
                                                  s=spectrum_strings[s_key]))
    spectrum = load_string(spectrum_strings[s_key])
    expanded = spectrum.expand()
    if len(expanded) == 1:
        spectrum = expanded[0]

    return emitter, spectrum
def test01_create(variant_scalar_rgb):
    from mitsuba.render import BSDFFlags
    from mitsuba.core.xml import load_string

    bsdf = load_string("""<bsdf version="2.0.0" type="blendbsdf">
        <bsdf type="diffuse"/>
        <bsdf type="diffuse"/>
        <spectrum name="weight" value="0.2"/>
    </bsdf>""")
    assert bsdf is not None
    assert bsdf.component_count() == 2
    assert bsdf.flags(0) == BSDFFlags.DiffuseReflection | BSDFFlags.FrontSide
    assert bsdf.flags(1) == BSDFFlags.DiffuseReflection | BSDFFlags.FrontSide
    assert bsdf.flags() == bsdf.flags(0) | bsdf.flags(1)

    bsdf = load_string("""<bsdf version="2.0.0" type="blendbsdf">
        <bsdf type="roughconductor"/>
        <bsdf type="diffuse"/>
        <spectrum name="weight" value="0.2"/>
    </bsdf>""")
    assert bsdf is not None
    assert bsdf.component_count() == 2
    assert bsdf.flags(0) == BSDFFlags.GlossyReflection | BSDFFlags.FrontSide
    assert bsdf.flags(1) == BSDFFlags.DiffuseReflection | BSDFFlags.FrontSide
    assert bsdf.flags() == bsdf.flags(0) | bsdf.flags(1)
예제 #6
0
def test14_missing_parameter(variant_scalar_rgb):
    from mitsuba.core import xml

    with pytest.raises(Exception) as e:
        xml.load_string("""<scene version="2.0.0">
                   <shape type="ply"/>
                   </scene>""")
    e.match('Property "filename" has not been specified')
예제 #7
0
def test11_unknown_attribute(variant_scalar_rgb):
    from mitsuba.core import xml

    with pytest.raises(Exception) as e:
        xml.load_string("""<scene version="2.0.0">
                   <shape type="ply" param2="abc">
                   </shape></scene>""")
    e.match('unexpected attribute "param2" in element "shape".')
예제 #8
0
def test10_unknown_id(variant_scalar_rgb):
    from mitsuba.core import xml

    with pytest.raises(Exception) as e:
        xml.load_string("""<scene version="2.0.0">
                   <ref id="unknown"/>
                   </scene>""")
    e.match('reference to unknown object "unknown"')
예제 #9
0
def test06_reserved_id(variant_scalar_rgb):
    from mitsuba.core import xml

    with pytest.raises(Exception) as e:
        xml.load_string('<scene version="2.0.0">' +
                   '<shape type="ply" id="_test"/></scene>')
    e.match('invalid id "_test" in element "shape": leading underscores '
        'are reserved for internal identifiers.')
예제 #10
0
def test06_reserved_name(variant_scalar_rgb):
    from mitsuba.core import xml

    with pytest.raises(Exception) as e:
        xml.load_string('<scene version="2.0.0">' + '<shape type="ply">' +
                        '<integer name="_test" value="1"/></shape></scene>')
    e.match('invalid parameter name "_test" in element "integer": '
            'leading underscores are reserved for internal identifiers.')
예제 #11
0
def test18_invalid_boolean(variant_scalar_rgb):
    from mitsuba.core import xml

    with pytest.raises(Exception) as e:
        xml.load_string("""<scene version="2.0.0">
                   <boolean name="10" value="a"/>
                   </scene>""")
    e.match('could not parse boolean value "a"'
            ' -- must be "true" or "false".')
예제 #12
0
def test04_valid_root_node(variant_scalar_rgb):
    from mitsuba.core import xml
    from mitsuba.render import Scene

    obj1 = xml.load_string('<?xml version="1.0"?>\n<scene version="2.0.0">'
                      '</scene>')
    obj2 = xml.load_string('<scene version="2.0.0"></scene>')
    assert type(obj1) is Scene
    assert type(obj2) is Scene
예제 #13
0
def test08_incorrect_nesting(variant_scalar_rgb):
    from mitsuba.core import xml

    with pytest.raises(Exception) as e:
        xml.load_string("""<scene version="2.0.0">
                   <shape type="ply">
                   <translate name="value" x="0" y="1" z="2"/>
                   </shape></scene>""")
    e.match('transform operations can only occur in a transform node')
예제 #14
0
 def check_scene(xml, count, error=None):
     xml = """<scene version="2.0.0">
         {}
     </scene>""".format(xml)
     if error is None:
         scene = load_string(xml)
         assert len(scene.emitters()) == count
     else:
         with pytest.raises(RuntimeError, match='.*{}.*'.format(error)):
             load_string(xml)
예제 #15
0
파일: test_xml.py 프로젝트: pangor/mitsuba2
def test22_fileresolver_unchanged(variant_scalar_rgb):
    from mitsuba.core import xml, Thread

    fs_backup = Thread.thread().file_resolver()

    xml.load_string("""<scene version="2.0.0">
                            <path value="/tmp"/>
                        </scene>""")

    assert fs_backup == Thread.thread().file_resolver()
예제 #16
0
def test15_incorrect_parameter_type(variant_scalar_rgb):
    from mitsuba.core import xml

    with pytest.raises(Exception) as e:
        xml.load_string("""<scene version="2.0.0">
                   <shape type="ply">
                      <float name="filename" value="1.0"/>
                   </shape></scene>""")
    e.match('The property "filename" has the wrong type'
            ' \\(expected <string>\\).')
예제 #17
0
def test07_incorrect_nesting(variant_scalar_rgb):
    from mitsuba.core import xml

    with pytest.raises(Exception) as e:
        xml.load_string("""<scene version="2.0.0">
                   <shape type="ply">
                   <integer name="value" value="1">
                   <float name="value" value="1"/>
                   </integer></shape></scene>""")
    e.match('node "float" cannot occur as child of a property')
예제 #18
0
파일: test_xml.py 프로젝트: pangor/mitsuba2
def test21_path_at_root_only(variant_scalar_rgb):
    from mitsuba.core import xml

    err_str = 'can only be child of root'
    with pytest.raises(Exception) as e:
        xml.load_string("""<scene version="2.0.0">
                            <bsdf type="dielectric">
                                <path value="/tmp"/>
                            </bsdf>
                        </scene>""")
    e.match(err_str)
예제 #19
0
def create_emitter_and_spectrum(s_key='d65'):
    from mitsuba.core.xml import load_string
    emitter = load_string("""<emitter version='2.0.0' type='constant'>
                                {s}
                             </emitter>""".format(s=spectrum_strings[s_key]))
    spectrum = load_string(spectrum_strings[s_key])
    expanded = spectrum.expand()
    if len(expanded) == 1:
        spectrum = expanded[0]

    return emitter, spectrum
예제 #20
0
def test09_incorrect_nesting(variant_scalar_rgb):
    from mitsuba.core import xml

    with pytest.raises(Exception) as e:
        xml.load_string("""<scene version="2.0.0">
                   <shape type="ply">
                   <transform name="toWorld">
                   <integer name="value" value="10"/>
                   </transform>
                   </shape></scene>""")
    e.match('transform nodes can only contain transform operations')
예제 #21
0
파일: test_xml.py 프로젝트: pangor/mitsuba2
def test23_unreferenced_object(variant_scalar_rgb):
    from mitsuba.core import xml

    plugins = [('bsdf', 'diffuse'), ('emitter', 'point'),
               ('shape', 'sphere'), ('sensor', 'perspective')]

    for interface, name in plugins:
        with pytest.raises(Exception) as e:
            xml.load_string("""<{interface} version="2.0.0" type="{name}">
                                    <rgb name="aaa" value="0.5"/>
                                </{interface}>""".format(interface=interface, name=name))
        e.match("unreferenced object")
예제 #22
0
def test05_duplicate_id(variant_scalar_rgb):
    from mitsuba.core import xml

    with pytest.raises(Exception) as e:
        xml.load_string("""
        <scene version="2.0.0">
            <shape type="ply" id="my_id"/>
            <shape type="ply" id="my_id"/>
        </scene>
        """)
    e.match('Error while loading "<string>" \\(at line 4, col 14\\):'
        ' "shape" has duplicate id "my_id" \\(previous was at line 3,'
        ' col 14\\)')
예제 #23
0
def test19_invalid_vector(variant_scalar_rgb):
    from mitsuba.core import xml

    err_str = 'could not parse floating point value "a"'
    err_str2 = '"value" attribute must have exactly 1 or 3 elements'
    err_str3 = 'can\'t mix and match "value" and "x"/"y"/"z" attributes'

    with pytest.raises(Exception) as e:
        xml.load_string("""<scene version="2.0.0">
                   <vector name="10" x="a" y="b" z="c"/>
                   </scene>""")
    e.match(err_str)

    with pytest.raises(Exception) as e:
        xml.load_string("""<scene version="2.0.0">
                   <vector name="10" value="a, b, c"/>
                   </scene>""")
    e.match(err_str)

    with pytest.raises(Exception) as e:
        xml.load_string("""<scene version="2.0.0">
                   <vector name="10" value="1, 2"/>
                   </scene>""")
    e.match(err_str2)

    with pytest.raises(Exception) as e:
        xml.load_string("""<scene version="2.0.0">
                   <vector name="10" value="1, 2, 3" x="4"/>
                   </scene>""")
    e.match(err_str3)
예제 #24
0
def create_emitter_and_spectrum(pos, s_key='d65'):
    from mitsuba.core.xml import load_string
    emitter = load_string("""<emitter version='2.0.0' type='point'>
                                <point name='position' x='{x}' y='{y}' z='{z}'/>
                                {s}
                             </emitter>""".format(x=pos[0],
                                                  y=pos[1],
                                                  z=pos[2],
                                                  s=spectrum_strings[s_key]))
    spectrum = load_string(spectrum_strings[s_key])
    expanded = spectrum.expand()
    if len(expanded) == 1:
        spectrum = expanded[0]

    return emitter, spectrum
예제 #25
0
def create_camera(o, d, fov=34, fov_axis='x', s_open=1.5, s_close=5):
    from mitsuba.core.xml import load_string
    return load_string("""<sensor version='2.0.0' type='perspective'>
                              <float name='near_clip' value='1'/>
                              <float name='far_clip' value='35'/>
                              <float name='focus_distance' value='15'/>
                              <float name='fov' value='{fov}'/>
                              <string name='fov_axis' value='{fov_axis}'/>
                              <float name='shutter_open' value='{so}'/>
                              <float name='shutter_close' value='{sc}'/>
                              <transform name="to_world">
                                  <lookat origin="{ox}, {oy}, {oz}"
                                          target="{tx}, {ty}, {tz}"
                                          up    =" 0.0,  1.0,  0.0"/>
                              </transform>
                              <film type="hdrfilm">
                                  <integer name="width" value="512"/>
                                  <integer name="height" value="256"/>
                              </film>
                          </sensor> """.format(ox=o[0],
                                               oy=o[1],
                                               oz=o[2],
                                               tx=o[0] + d[0],
                                               ty=o[1] + d[1],
                                               tz=o[2] + d[2],
                                               fov=fov,
                                               fov_axis=fov_axis,
                                               so=s_open,
                                               sc=s_close))
def create_medium_scene(phase_function='isotropic', spp=8):
    scene = load_string(f"""
        <scene version='2.0.0'>
            <integrator type="volpath"/>
            <sensor type="perspective">
                <transform name="to_world">
                    <lookat target="0.0,   0.0, 1.0"
                            origin="0.0, 14.0, 1.0"
                            up    ="0.0,   0.0, 1.0"/>
                </transform>
                <film type="hdrfilm">
                    <integer name="width" value="32"/>
                    <integer name="height" value="32"/>
                    <string name="pixel_format" value="rgb" />
                </film>
                <sampler type="independent">
                    <integer name="sample_count" value="{spp}"/>
                </sampler>
            </sensor>
            <emitter type="constant" />
            <shape type="ply">
                <string name="filename" value="resources/data/ply/teapot.ply"/>
                <bsdf type="null" />
                <medium name="interior" type="homogeneous">
                    <rgb name="sigma_t" value="1.0, 1.0, 1.0"/>
                    <rgb name="albedo" value="0.99, 0.4, 0.4"/>
                    <phase type="{phase_function}"/>
                    <boolean name="sample_emitters" value="true"/>
                </medium>
            </shape>
        </scene>
    """)
    assert scene is not None
    return scene
예제 #27
0
def test11_parameters_grad_enabled(variant_gpu_autodiff_rgb):
    from mitsuba.core.xml import load_string

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

    assert shape.parameters_grad_enabled() == False

    # Get the shape's parameters
    params = traverse(shape)

    # Only parameters of the shape should affect the result of that method
    bsdf_param_key = 'bsdf.reflectance.value'
    ek.set_requires_gradient(params[bsdf_param_key])
    params.set_dirty(bsdf_param_key)
    params.update()
    assert shape.parameters_grad_enabled() == False

    # When setting one of the shape's param to require gradient, method should return True
    shape_param_key = 'vertex_positions_buf'
    ek.set_requires_gradient(params[shape_param_key])
    params.set_dirty(shape_param_key)
    params.update()
    assert shape.parameters_grad_enabled() == True
def test02_eval_all(variant_scalar_rgb):
    from mitsuba.core import Frame3f
    from mitsuba.render import BSDFFlags, BSDFContext, SurfaceInteraction3f
    from mitsuba.core.xml import load_string
    from mitsuba.core.math import InvPi

    weight = 0.2

    bsdf = load_string("""<bsdf version="2.0.0" type="blendbsdf">
        <bsdf type="diffuse">
            <spectrum name="reflectance" value="0.0"/>
        </bsdf>
        <bsdf type="diffuse">
            <spectrum name="reflectance" value="1.0"/>
        </bsdf>
        <spectrum name="weight" value="{}"/>
    </bsdf>""".format(weight))

    si = SurfaceInteraction3f()
    si.t = 0.1
    si.p = [0, 0, 0]
    si.n = [0, 0, 1]
    si.sh_frame = Frame3f(si.n)
    si.wi = [0, 0, 1]

    wo = [0, 0, 1]
    ctx = BSDFContext()

    # Evaluate the blend of both components
    expected = (1 - weight) * 0.0 * InvPi + weight * 1.0 * InvPi
    value    = bsdf.eval(ctx, si, wo)
    assert ek.allclose(value, expected)
예제 #29
0
def test04_sample_direct(variant_scalar_rgb):
    from mitsuba.core.xml import load_string
    from mitsuba.core import Ray3f
    from mitsuba.render import Interaction3f

    if mitsuba.core.MTS_ENABLE_EMBREE:
        pytest.skip("EMBREE enabled")

    sphere = load_string('<shape type="sphere" version="2.0.0"/>')

    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)
예제 #30
0
def test14_differentiable_surface_interaction_ray_backward(
        variant_gpu_autodiff_rgb):
    from mitsuba.core import xml, Ray3f, Vector3f, UInt32

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

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

    ek.set_requires_gradient(ray.o)

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

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