Ejemplo n.º 1
0
    def parse_transform(self, node):
        from mitsuba.core import Transform4f
        trao = Transform4f()
        for child in node:
            if (child.tag == 'translate' or child.tag == 'rotate'):
                components = [0.0]*3
            elif (child.tag == "scale"):
                components = [1.0]*3
            if('x' in child.attrib): components[0] = float(self.replace_default(child.attrib['x']))
            if('y' in child.attrib): components[1] = float(self.replace_default(child.attrib['y']))
            if('z' in child.attrib): components[2] = float(self.replace_default(child.attrib['z']))
            if('value' in child.attrib and child.tag in ['scale', 'translate', 'rotate']): 
                value = float(self.replace_default(child.attrib['value']))
                components = [value]*3

            # print("components", components)
            if( child.tag == 'translate'):    
                trao = Transform4f.translate(components)*trao
            elif( child.tag == 'scale'):
                trao = Transform4f.scale(components)*trao
            elif( child.tag == 'rotate'):
                angle = float(self.replace_default(child.attrib['angle']))
                trao = Transform4f.rotate(components, angle)*trao
            elif(child.tag == "matrix"):
                mat = child.attrib["value"]
                local_trao = np.array([float(val) for val in mat.split()])
                local_trao = np.reshape(local_trao, (4,4))
                trao = Transform4f(local_trao.tolist())*trao

        return trao
def test03_ray_intersect_transform(variant_scalar_rgb):
    from mitsuba.core import xml, Ray3f, Transform4f

    for r in [1, 3]:
        s = xml.load_dict({
            "type":
            "sphere",
            "radius":
            r,
            "to_world":
            Transform4f.translate([0, 1, 0]) *
            Transform4f.rotate([0, 1, 0], 30.0)
        })

        # grid size
        n = 21
        inv_n = 1.0 / n

        for x in range(n):
            for y in range(n):
                x_coord = r * (2 * (x * inv_n) - 1)
                y_coord = r * (2 * (y * inv_n) - 1)

                ray = Ray3f(o=[x_coord, y_coord + 1, -8],
                            d=[0.0, 0.0, 1.0],
                            time=0.0,
                            wavelengths=[])
                si_found = s.ray_test(ray)

                assert si_found == (x_coord ** 2 + y_coord ** 2 <= r * r) \
                    or ek.abs(x_coord ** 2 + y_coord ** 2 - r * r) < 1e-8

                if si_found:
                    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)
                    if si_u.is_valid():
                        du = (si_u.uv - si.uv) / eps
                        assert ek.allclose(du, [1, 0], atol=2e-2)
                    if si_v.is_valid():
                        dv = (si_v.uv - si.uv) / eps
                        assert ek.allclose(dv, [0, 1], atol=2e-2)
Ejemplo n.º 3
0
def test15_differentiable_surface_interaction_params_forward(
        variant_gpu_autodiff_rgb):
    from mitsuba.core import xml, Float, Ray3f, Vector3f, UInt32, Transform4f

    # Convert flat array into a vector of arrays (will be included in next enoki release)
    def ravel(buf, dim=3):
        idx = dim * UInt32.arange(ek.slices(buf) // dim)
        if dim == 2:
            return Vector2f(ek.gather(buf, idx), ek.gather(buf, idx + 1))
        elif dim == 3:
            return Vector3f(ek.gather(buf, idx), ek.gather(buf, idx + 1),
                            ek.gather(buf, idx + 2))

    # Return contiguous flattened array (will be included in next enoki release)
    def unravel(source, target, dim=3):
        idx = UInt32.arange(ek.slices(source))
        for i in range(dim):
            ek.scatter(target, source[i], dim * idx + i)

    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>
    ''')

    params = traverse(scene)
    shape_param_key = 'rect.vertex_positions_buf'
    positions_buf = params[shape_param_key]
    positions_initial = ravel(positions_buf)

    # Create differential parameter to be optimized
    diff_vector = Vector3f(0.0)
    ek.set_requires_gradient(diff_vector)

    # Apply the transformation to mesh vertex position and update scene
    def apply_transformation(trasfo):
        trasfo = trasfo(diff_vector)
        new_positions = trasfo.transform_point(positions_initial)
        unravel(new_positions, params[shape_param_key])
        params.set_dirty(shape_param_key)
        params.update()

    # ---------------------------------------
    # Test translation

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

    # # If the vertices are shifted along z-axis, so does si.t
    apply_transformation(lambda v: Transform4f.translate(v))
    si = pi.compute_surface_interaction(ray)
    ek.forward(diff_vector.z)
    assert ek.allclose(ek.gradient(si.t), 1)

    # If the vertices are shifted along z-axis, so does si.p
    apply_transformation(lambda v: Transform4f.translate(v))
    si = pi.compute_surface_interaction(ray)
    ek.forward(diff_vector.z)
    assert ek.allclose(ek.gradient(si.p), [0.0, 0.0, 1.0])

    # If the vertices are shifted along x-axis, so does si.uv (times 0.5)
    apply_transformation(lambda v: Transform4f.translate(v))
    si = pi.compute_surface_interaction(ray)
    ek.forward(diff_vector.x)
    assert ek.allclose(ek.gradient(si.uv), [-0.5, 0.0])

    # If the vertices are shifted along y-axis, so does si.uv (times 0.5)
    apply_transformation(lambda v: Transform4f.translate(v))
    si = pi.compute_surface_interaction(ray)
    ek.forward(diff_vector.y)
    assert ek.allclose(ek.gradient(si.uv), [0.0, -0.5])

    # ---------------------------------------
    # Test rotation

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

    # If the vertices are rotated around the center, so does si.uv (times 0.5)
    apply_transformation(lambda v: Transform4f.rotate([0, 0, 1], v.x))
    si = pi.compute_surface_interaction(ray)
    ek.forward(diff_vector.x)
    du = 0.5 * ek.sin(2 * ek.pi / 360.0)
    assert ek.allclose(ek.gradient(si.uv), [-du, du], atol=1e-6)
Ejemplo n.º 4
0
 def rotate_vector(v, axis, angle):
     return Transform4f.rotate(axis, angle).transform_vector(v)