Пример #1
0
def test05_round_and_saturation():
    s1 = Struct().append('val', Struct.Type.Float32)
    s2 = Struct().append('val', Struct.Type.Int8)
    s = StructConverter(s1, s2)
    values = [-0.55, -0.45, 0, 0.45, 0.55, 127, 128, -127, -200]
    check_conversion(s, '@fffffffff', '@bbbbbbbbb', values,
                     [-1, 0, 0, 0, 1, 127, 127, -127, -128])
Пример #2
0
def test03_convert(param):
    p1, p2 = param
    s1 = Struct().append('val', p1[1])
    s2 = Struct().append('val', p2[1])
    s = StructConverter(s1, s2)
    values = list(range(10))
    if Struct.is_signed(p1[1]) and Struct.is_signed(p2[1]):
        values += list(range(-10, 0))
    max_range = int(min(Struct.range(p1[1])[1], Struct.range(p2[1])[1]))
    if max_range > 1024:
        values += list(range(1000, 1024))

    # Native -> Native
    check_conversion(s, '@' + p1[0] * len(values),
                        '@' + p2[0] * len(values), values)

    # LE -> BE
    s1 = Struct(byte_order=Struct.ByteOrder.BigEndian).append('val', p1[1])
    s2 = Struct(byte_order=Struct.ByteOrder.LittleEndian).append('val', p2[1])
    s = StructConverter(s1, s2)
    check_conversion(s, '>' + p1[0] * len(values),
                        '<' + p2[0] * len(values), values)

    # BE -> LE
    s1 = Struct(byte_order=Struct.ByteOrder.LittleEndian).append('val', p1[1])
    s2 = Struct(byte_order=Struct.ByteOrder.BigEndian).append('val', p2[1])
    s = StructConverter(s1, s2)
    check_conversion(s, '<' + p1[0] * len(values),
                        '>' + p2[0] * len(values), values)
Пример #3
0
def test06_round_and_saturation_normalized():
    s1 = Struct().append('val', Struct.Type.Float32)
    s2 = Struct().append('val', Struct.Type.Int8, Struct.Flags.Normalized)
    s = StructConverter(s1, s2)
    f = 1.0 / 127.0
    values = [-0.55 * f, -0.45 * f, 0, 0.45 * f, 0.55 * f, 1, 2, -1, -2]
    check_conversion(s, '@fffffffff', '@bbbbbbbbb', values,
                     [-1, 0, 0, 0, 1, 127, 127, -127, -128])
Пример #4
0
def test02_passthrough(param):
    s = Struct().append('val', param[1])
    ss = StructConverter(s, s)
    values = list(range(10))
    if Struct.is_signed(param[1]):
        values += list(range(-10, 0))
    check_conversion(ss, '@' + param[0] * len(values),
                     '@' + param[0] * len(values), values)
Пример #5
0
def test10_gamma_2():
    s = StructConverter(
        Struct().append('v', Struct.Type.Float32),
        Struct().append('v', Struct.Type.UInt8,
                        Struct.Flags.Normalized | Struct.Flags.Gamma))

    src_data = list(np.linspace(0, 1, 256))
    dest_data = [np.uint8(np.round(to_srgb(x) * 255)) for x in src_data]

    check_conversion(s, '@' + ('f' * 256), '@' + ('B' * 256), src_data,
                     dest_data)
Пример #6
0
def test09_gamma_1():
    s = StructConverter(
        Struct().append('v', Struct.Type.UInt8,
                        Struct.Flags.Normalized | Struct.Flags.Gamma),
        Struct().append('v', Struct.Type.Float32)
    )

    src_data = list(range(256))
    dest_data = [from_srgb(x / 255.0) for x in src_data]

    check_conversion(s, '@' + ('B' * 256), '@' + ('f' * 256),
                     src_data, dest_data, err_thresh=1e-5)
Пример #7
0
def test17_alpha_2():
    """Tests that alpha (un)premultiplication does not allow multiple alpha channels"""
    src_struct = Struct() \
        .append('value1', Struct.Type.Float32, Struct.Flags.PremultipliedAlpha) \
        .append('alpha', Struct.Type.Float32, Struct.Flags.Alpha) \
        .append('alpha2', Struct.Type.Float32, Struct.Flags.Alpha)
    dst_struct = Struct() \
        .append('value1', Struct.Type.Float32) \
        .append('alpha', Struct.Type.Float32, Struct.Flags.Alpha) \
        .append('alpha2', Struct.Type.Float32, Struct.Flags.Alpha)
    with pytest.raises(RuntimeError):
        s = StructConverter(src_struct, dst_struct)
        check_conversion(s, '@fff', '@fff', (0.5, 0.8, 0.6))
Пример #8
0
def test16_alpha_1():
    """Tests alpha (un)premultiplication for linear floating point structs"""
    src_struct = Struct() \
                .append('value1', Struct.Type.Float32, Struct.Flags.PremultipliedAlpha) \
                .append('value2', Struct.Type.Float32) \
                .append('alpha', Struct.Type.Float32, Struct.Flags.Alpha)
    dst_struct = Struct() \
                .append('value1', Struct.Type.Float32) \
                .append('value2', Struct.Type.Float32, Struct.Flags.PremultipliedAlpha) \
                .append('alpha', Struct.Type.Float32, Struct.Flags.Alpha)
    s = StructConverter(src_struct, dst_struct)
    check_conversion(s, '@fff', '@fff',
                     (0.5, 0.8, 0.5), (1.0, 0.4, 0.5))
Пример #9
0
def test18_alpha_3():
    """Tests that multiple alpha channels are allowed if no conversion is requested"""
    src_struct = Struct() \
        .append('value1', Struct.Type.Float32, Struct.Flags.PremultipliedAlpha) \
        .append('value2', Struct.Type.Float32) \
        .append('alpha', Struct.Type.Float32, Struct.Flags.Alpha) \
        .append('alpha2', Struct.Type.Float32, Struct.Flags.Alpha)
    dst_struct = Struct() \
        .append('value1', Struct.Type.Float32, Struct.Flags.PremultipliedAlpha) \
        .append('value2', Struct.Type.Float32) \
        .append('alpha', Struct.Type.Float32, Struct.Flags.Alpha) \
        .append('alpha2', Struct.Type.Float32, Struct.Flags.Alpha)
    s = StructConverter(src_struct, dst_struct)
    check_conversion(s, '@ffff', '@ffff',
                     (0.5, 0.8, 0.5, 0.7))
Пример #10
0
def test14_weight(param):
    src = Struct() \
        .append('value1', param[1], Struct.Flags.Normalized) \
        .append('value2', param[1], Struct.Flags.Normalized) \
        .append('weight', param[1], Struct.Flags.Normalized | Struct.Flags.Weight)

    target = Struct().append('value1', Struct.Type.Float32) \
                     .append('value2', Struct.Type.Float32)

    s = StructConverter(src, src)
    check_conversion(s, '@' + param[0] * 3, '@' + param[0] * 3, (10, 20, 20),
                     (10, 20, 20))

    s = StructConverter(src, target)
    check_conversion(s, '@' + param[0] * 3, '@ff', (10, 20, 20), (0.5, 1.0))
Пример #11
0
def test07_roundtrip_normalization(param):
    s1 = Struct().append('val', param[1], Struct.Flags.Normalized)
    s2 = Struct().append('val', Struct.Type.Float32)
    s = StructConverter(s1, s2)
    max_range = 1.0
    if Struct.is_integer(param[1]):
        max_range = float(Struct.range(param[1])[1])
    values_in = list(range(10))
    values_out = [i / max_range for i in range(10)]
    check_conversion(s, '@' + (param[0] * 10), '@' + ('f' * 10),
                     values_in, values_out)

    s = StructConverter(s2, s1)
    check_conversion(s, '@' + ('f' * 10), '@' + (param[0] * 10),
                     values_out, values_in)
Пример #12
0
def test11_assert_value(param):
    s = StructConverter(
        Struct().append('v', param[1], default=10, flags=Struct.Flags.Assert),
        Struct().append('v', param[1]))
    check_conversion(s, '@' + param[0], '@' + param[0], (10, ), (10, ))
    with pytest.raises(RuntimeError):
        check_conversion(s, '@' + param[0], '@' + param[0], (11, ), (11, ))

    s = StructConverter(
        Struct().append('v1', param[1], default=10,
                        flags=Struct.Flags.Assert).append('v2', param[1]),
        Struct().append('v2', param[1]))
    check_conversion(s, '@' + param[0] * 2, '@' + param[0], (10, 10), (10, ))
    with pytest.raises(RuntimeError):
        check_conversion(s, '@' + param[0] * 2, '@' + param[0], (11, 11),
                         (11, ))
Пример #13
0
def test01_create_mesh(variant_scalar_rgb):
    from mitsuba.core import Struct, float_dtype
    from mitsuba.render import Mesh

    vertex_struct = Struct() \
        .append("x", Struct.Type.Float32) \
        .append("y", Struct.Type.Float32) \
        .append("z", Struct.Type.Float32)

    index_struct = Struct() \
        .append("i0", Struct.Type.UInt32) \
        .append("i1", Struct.Type.UInt32) \
        .append("i2", Struct.Type.UInt32)
    m = Mesh("MyMesh", vertex_struct, 3, index_struct, 2)
    v = m.vertices()
    v[0] = (0.0, 0.0, 0.0)
    v[1] = (0.0, 0.0, 1.0)
    v[2] = (0.0, 1.0, 0.0)
    m.recompute_bbox()

    if float_dtype == 'f':
        assert str(m) == """Mesh[
  name = "MyMesh",
  bbox = BoundingBox3f[
    min = [0, 0, 0],
    max = [0, 1, 1]
  ],
  vertex_struct = Struct<12>[
    float32 x; // @0
    float32 y; // @4
    float32 z; // @8
  ],
  vertex_count = 3,
  vertices = [36 B of vertex data],
  face_struct = Struct<12>[
    uint32 i0; // @0
    uint32 i1; // @4
    uint32 i2; // @8
  ],
  face_count = 2,
  faces = [24 B of face data],
  disable_vertex_normals = 0,
  surface_area = 0
]"""
    else:
        assert str(m) == """Mesh[
Пример #14
0
def test03_missing_field(param):
    s1 = Struct().append('val1', param[1]) \
                 .append('val3', param[1])
    s2 = Struct().append('val1', param[1]) \
                 .append('val2', param[1], Struct.Flags.Default, 123) \
                 .append('val3', param[1])
    s = StructConverter(s1, s2)

    values = list(range(10))
    if Struct.is_signed(param[1]):
        values += list(range(-10, 0))
    output = []
    for k in range(len(values) // 2):
        output += [values[k * 2], 123, values[k * 2 + 1]]

    check_conversion(s, '@' + param[0] * len(values),
                        '@' + param[0] * (len(values) + len(values) // 2),
                     values, output)
Пример #15
0
def test04_normal_weighting_scheme(variant_scalar_rgb):
    from mitsuba.core import Struct, float_dtype, Vector3f
    from mitsuba.render import Mesh
    import numpy as np
    """Tests the weighting scheme that is used to compute surface normals."""
    vertex_struct = Struct() \
        .append("x", Struct.Type.Float32) \
        .append("y", Struct.Type.Float32) \
        .append("z", Struct.Type.Float32) \
        .append("nx", Struct.Type.Float32) \
        .append("ny", Struct.Type.Float32) \
        .append("nz", Struct.Type.Float32)

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

    m = Mesh("MyMesh", vertex_struct, 5, index_struct, 2)
    v = m.vertices()

    a, b = 1.0, 0.5
    v['x'] = Float([0, -a, a, -b, b])
    v['y'] = Float([0, 1, 1, 0, 0])
    v['z'] = Float([0, 0, 0, 1, 1])

    n0 = Vector3f(0.0, 0.0, -1.0)
    n1 = Vector3f(0.0, 1.0, 0.0)
    angle_0 = ek.pi / 2.0
    angle_1 = ek.acos(3.0 / 5.0)
    n2 = n0 * angle_0 + n1 * angle_1
    n2 /= ek.norm(n2)
    n = np.vstack([n2, n0, n0, n1, n1])

    f = m.faces()
    f[0] = (0, 1, 2)
    f[1] = (0, 3, 4)
    m.recompute_vertex_normals()
    assert ek.allclose(v['nx'], n[:, 0], 5e-4)
    assert ek.allclose(v['ny'], n[:, 1], 5e-4)
    assert ek.allclose(v['nz'], n[:, 2], 5e-4)
Пример #16
0
def test08_roundtrip_normalization_int2int(param):
    if Struct.is_float(param[1]):
        return
    s1_type = Struct.Type.Int8 if Struct.is_signed(param[1]) else Struct.Type.UInt8
    s1_dtype = 'b' if Struct.is_signed(param[1]) else 'B'
    s1_range = Struct.range(s1_type)
    s2_range = Struct.range(param[1])
    s1 = Struct().append('val', s1_type, Struct.Flags.Normalized)
    s2 = Struct().append('val', param[1], Struct.Flags.Normalized)
    s = StructConverter(s1, s2)
    values_in = list(range(int(s1_range[0]), int(s1_range[1] + 1)))
    values_out = np.array(values_in, dtype=np.float64)
    values_out *= s2_range[1] / s1_range[1]
    values_out = np.rint(values_out)
    values_out = np.maximum(values_out, s2_range[0])
    values_out = np.minimum(values_out, s2_range[1])
    values_out = np.array(values_out, s2.dtype()['val'])
    check_conversion(s, '@' + (s1_dtype * len(values_in)),
                        '@' + (param[0] * len(values_in)),
                     values_in, values_out)
Пример #17
0
def test19_alpha_4():
    src_struct = Struct() \
        .append('value1', Struct.Type.UInt8, Struct.Flags.PremultipliedAlpha | Struct.Flags.Normalized | Struct.Flags.Gamma) \
        .append('value2', Struct.Type.UInt8, Struct.Flags.Normalized | Struct.Flags.Gamma) \
        .append('alpha', Struct.Type.UInt8, Struct.Flags.Normalized | Struct.Flags.Alpha)
    dst_struct = Struct() \
        .append('value1', Struct.Type.UInt8, Struct.Flags.Normalized | Struct.Flags.Gamma) \
        .append('value2', Struct.Type.UInt8, Struct.Flags.PremultipliedAlpha | Struct.Flags.Normalized | Struct.Flags.Gamma) \
        .append('alpha', Struct.Type.UInt8, Struct.Flags.Normalized | Struct.Flags.Alpha)
    s = StructConverter(src_struct, dst_struct)
    src_data = (24, 54, 127)

    src_data_float = np.array(src_data) / 255
    src_data_float[0] = from_srgb(src_data_float[0])
    src_data_float[0] /= src_data_float[2]
    src_data_float[0] = np.uint8(np.round(to_srgb(src_data_float[0]) * 255))

    src_data_float[1] = from_srgb(src_data_float[1])
    src_data_float[1] *= src_data_float[2]
    src_data_float[1] = np.uint8(np.round(to_srgb(src_data_float[1]) * 255))

    dst_data = (src_data_float[0], src_data_float[1], src_data[2])
    check_conversion(s, '@BBB', '@BBB',
                     src_data, dst_data)
Пример #18
0
def test13_blend_gamma():
    def to_srgb(value):
        if value <= 0.0031308:
            return 12.92 * value
        return 1.055 * (value ** (1.0 / 2.4)) - 0.055

    def from_srgb(value):
        if value <= 0.04045:
            return value * 1.0 / 12.92
        return ((value + 0.055) * (1.0 / 1.055)) ** 2.4

    src = Struct()
    src.append('a', Struct.Type.UInt8, Struct.Flags.Normalized | Struct.Flags.Gamma)
    src.append('b', Struct.Type.UInt8, Struct.Flags.Normalized | Struct.Flags.Gamma)

    target = Struct()
    target.append('v', Struct.Type.UInt8, Struct.Flags.Normalized | Struct.Flags.Gamma)
    target.field('v').blend = [(1, 'a'), (1, 'b')]

    s = StructConverter(src, target)
    ref = int(np.round(to_srgb(from_srgb(100 / 255.0) +
                               from_srgb(200 / 255.0)) * 255))

    check_conversion(s, '@BB', '@B', (100, 200), (ref,))
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)
Пример #20
0
def test01_basics():
    s = Struct()
    assert s.field_count() == 0
    assert s.alignment() == 1
    assert s.size() == 0

    s.append('float_val', Struct.Type.Float32)
    assert s.field_count() == 1
    assert s.alignment() == 4
    assert s.size() == 4

    s.append('byte_val', Struct.Type.UInt8)
    assert s.field_count() == 2
    assert s.alignment() == 4
    assert s.size() == 8

    s.append('half_val', Struct.Type.Float16)
    assert s.field_count() == 3
    assert s.alignment() == 4
    assert s.size() == 8

    assert len(s) == 3
    assert s[0].name == 'float_val'
    assert s[0].offset == 0
    assert s[0].size == 4
    assert s[0].type == Struct.Type.Float32

    assert s[1].name == 'byte_val'
    assert s[1].offset == 4
    assert s[1].size == 1
    assert s[1].type == Struct.Type.UInt8

    assert s[2].name == 'half_val'
    assert s[2].offset == 6
    assert s[2].size == 2
    assert s[2].type == Struct.Type.Float16
Пример #21
0
def test04_missing_field_error():
    s1 = Struct().append('val1', Struct.Type.UInt32)
    s2 = Struct().append('val2', Struct.Type.UInt32)
    with pytest.raises(RuntimeError, match='Unable to find field "val2"'):
        s = StructConverter(s1, s2)
        check_conversion(s, '@I', '@I', [1], [1])
Пример #22
0
def test12_blend():
    src = Struct()
    src.append('a', Struct.Type.Float32)
    src.append('b', Struct.Type.Float32)

    target = Struct()
    target.append('v', Struct.Type.Float32)
    target.field('v').blend = [(3.0, 'a'), (4.0, 'b')]

    s = StructConverter(
        src,
        target
    )
    check_conversion(s, '@ff', '@f',
                     (1.0, 2.0),
                     (3.0 + 8.0,))

    src = Struct()
    src.append('a', Struct.Type.UInt8, Struct.Flags.Normalized)
    src.append('b', Struct.Type.UInt8, Struct.Flags.Normalized)

    target = Struct()
    target.append('v', Struct.Type.Float32)
    target.field('v').blend = [(3.0, 'a'), (4.0, 'b')]

    s = StructConverter(
        src,
        target
    )

    check_conversion(s, '@BB', '@f',
                     (255, 127),
                     (3.0 + 4.0 * (127.0 / 255.0),))