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 #2
0
    def bsdfs(self, ctx: KernelDictContext) -> KernelDict:
        from mitsuba.core import ScalarTransform4f

        returndict = KernelDict({
            f"bsdf_{self.id}": {
                "type": "blendbsdf",
                "inner_bsdf": onedict_value(self.central_patch.bsdfs(ctx=ctx)),
                "outer_bsdf":
                onedict_value(self.background_surface.bsdfs(ctx=ctx)),
                "weight": {
                    "type":
                    "bitmap",
                    "filename":
                    str(
                        eradiate.path_resolver.resolve(
                            "textures/rami4atm_experiment_surface_mask.bmp")),
                    "filter_type":
                    "nearest",
                    "wrap_mode":
                    "clamp",
                },
            }
        })

        scale = self._compute_scale_parameter(ctx=ctx)
        trafo = ScalarTransform4f.scale(scale) * ScalarTransform4f.translate((
            -0.5 + (0.5 / scale),
            -0.5 + (0.5 / scale),
            0,
        ))

        returndict[f"bsdf_{self.id}"]["weight"]["to_uv"] = trafo

        return returndict
Example #3
0
def test_ramiatm_experiment_surface_adjustment(mode_mono):
    """Create a Rami4ATM experiment and assert the central patch surface is created with the
    correct parameters, according to the canopy and atmosphere."""
    from mitsuba.core import ScalarTransform4f

    ctx = KernelDictContext()

    s = Rami4ATMExperiment(
        atmosphere=HomogeneousAtmosphere(width=ureg.Quantity(42.0, "km")),
        canopy=DiscreteCanopy.homogeneous(
            lai=3.0,
            leaf_radius=0.1 * ureg.m,
            l_horizontal=10.0 * ureg.m,
            l_vertical=2.0 * ureg.m,
            padding=0,
        ),
        surface=CentralPatchSurface(central_patch=LambertianSurface(),
                                    background_surface=LambertianSurface()),
    )

    expected_trafo = ScalarTransform4f.scale(
        1400) * ScalarTransform4f.translate((-0.499642857, -0.499642857, 0.0))

    kernel_dict = s.kernel_dict(ctx=ctx)

    assert np.allclose(kernel_dict["bsdf_surface"]["weight"]["to_uv"].matrix,
                       expected_trafo.matrix)
Example #4
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
Example #5
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 #6
0
def test_construct(variant_scalar_rgb):
    from mitsuba.core.xml import load_dict
    from mitsuba.core import ScalarTransform4f

    # Test construct from to_world
    sensor = make_sensor(to_world=ScalarTransform4f.look_at(
        origin=[0, 0, 0],
        target=[0, 1, 0],
        up=[0, 0, 1]
    ))
    assert not sensor.bbox().valid()  # Degenerate bounding box
    assert ek.allclose(
        sensor.world_transform().eval(0.).matrix,
        [[-1, 0, 0, 0],
         [0, 0, 1, 0],
         [0, 1, 0, 0],
         [0, 0, 0, 1]]
    )

    # Test construct from origin and direction
    sensor = make_sensor(origin=[0, 0, 0], direction=[0, 1, 0])
    assert not sensor.bbox().valid()  # Degenerate bounding box
    assert ek.allclose(
        sensor.world_transform().eval(0.).matrix,
        [[0, 0, 1, 0],
         [1, 0, 0, 0],
         [0, 1, 0, 0],
         [0, 0, 0, 1]]
    )

    # Test to_world overriding direction + origin
    sensor = make_sensor(
        to_world=ScalarTransform4f.look_at(
            origin=[0, 0, 0],
            target=[0, 1, 0],
            up=[0, 0, 1]
        ),
        origin=[1, 0, 0],
        direction=[4, 1, 0]
    )
    assert not sensor.bbox().valid()  # Degenerate bounding box
    assert ek.allclose(
        sensor.world_transform().eval(0.).matrix,
        [[-1, 0, 0, 0],
         [0, 0, 1, 0],
         [0, 1, 0, 0],
         [0, 0, 0, 1]]
    )

    # Test raise on missing direction or origin
    with pytest.raises(RuntimeError):
        sensor = make_sensor(direction=[0, 1, 0])

    with pytest.raises(RuntimeError):
        sensor = make_sensor(origin=[0, 1, 0])

    # Test raise on wrong film size
    with pytest.raises(RuntimeError):
        sensor = make_sensor(pixels=2)
def velocity_transform(dr, dq, dt):
    linvel = dr * dt

    rotvel_z = ScalarTransform4f.rotate([0, 0, 1], dq[2] * dt)
    rotvel_y = ScalarTransform4f.rotate([0, 1, 0], dq[1] * dt)
    rotvel_x = ScalarTransform4f.rotate([1, 0, 0], dq[0] * dt)
    rotvel = rotvel_x * rotvel_y * rotvel_z

    return ScalarTransform4f.translate(linvel) * rotvel
def position_transform(r, q):
    pos = r

    rot_z = ScalarTransform4f.rotate([0, 0, 1], q[2])
    rot_y = ScalarTransform4f.rotate([0, 1, 0], q[1])
    rot_x = ScalarTransform4f.rotate([1, 0, 0], q[0])
    rot = rot_x * rot_y * rot_z

    return ScalarTransform4f.translate(pos) * rot
Example #9
0
    def shapes(self, ctx: KernelDictContext) -> t.Dict:
        """
        Return shape plugin specifications.

        Parameters
        ----------
        ctx : :class:`.KernelDictContext`
            A context data structure containing parameters relevant for kernel
            dictionary generation.

        Returns
        -------
        dict
            A dictionary suitable for merge with a
            :class:`~eradiate.scenes.core.KernelDict` containing all the shapes
            in the abstract tree.
        """
        from mitsuba.core import ScalarTransform4f

        kernel_length = uck.get("length")

        kernel_height = self.trunk_height.m_as(kernel_length)
        kernel_radius = self.trunk_radius.m_as(kernel_length)

        leaf_cloud = self.leaf_cloud.translated(
            [0.0, 0.0, kernel_height] * kernel_length +
            self.leaf_cloud_extra_offset.to(kernel_length))

        if ctx.ref:
            bsdf = {"type": "ref", "id": f"bsdf_{self.id}"}
        else:
            bsdf = self.bsdfs(ctx=ctx)[f"bsdf_{self.id}"]

        shapes_dict = leaf_cloud.shapes(ctx=ctx)

        shapes_dict[f"trunk_cyl_{self.id}"] = {
            "type": "cylinder",
            "bsdf": bsdf,
            "radius": kernel_radius,
            "p0": [0, 0, -0.1],
            "p1": [0, 0, kernel_height],
        }

        shapes_dict[f"trunk_cap_{self.id}"] = {
            "type":
            "disk",
            "bsdf":
            bsdf,
            "to_world":
            ScalarTransform4f.scale(kernel_radius) *
            ScalarTransform4f.translate(((0, 0, kernel_height))),
        }

        return shapes_dict
Example #10
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)
Example #11
0
def test_onedim_experiment_kernel_dict(modes_all):
    """
    Test non-trivial kernel dict generation behaviour.
    """
    from mitsuba.core import ScalarTransform4f

    ctx = KernelDictContext()

    # Surface width is appropriately inherited from atmosphere
    exp = OneDimExperiment(atmosphere=HomogeneousAtmosphere(
        width=ureg.Quantity(42.0, "km")))
    kernel_dict = exp.kernel_dict(ctx)
    assert np.allclose(
        kernel_dict["surface"]["to_world"].matrix,
        ScalarTransform4f.scale([21000, 21000, 1]).matrix,
    )

    # Setting atmosphere to None
    exp = OneDimExperiment(
        atmosphere=None,
        surface={
            "type": "lambertian",
            "width": 100.0,
            "width_units": "m"
        },
        measures=[
            {
                "type": "distant",
                "id": "distant_measure"
            },
            {
                "type": "radiancemeter",
                "origin": [1, 0, 0],
                "id": "radiancemeter"
            },
        ],
    )
    # -- Surface width is not overridden
    kernel_dict = exp.kernel_dict(ctx)
    assert np.allclose(
        kernel_dict["surface"]["to_world"].matrix,
        ScalarTransform4f.scale([50, 50, 1]).matrix,
    )
    # -- Atmosphere is not in kernel dictionary
    assert "atmosphere" not in kernel_dict

    # -- Measures get no external medium assigned
    assert "medium" not in kernel_dict["distant_measure"]
    assert "medium" not in kernel_dict["radiancemeter"]
Example #12
0
    def _kernel_dict(self, sensor_id, spp):
        from mitsuba.core import ScalarTransform4f

        target = self.target.m_as(uck.get("length"))
        origin = self.origin.m_as(uck.get("length"))

        result = {
            "type":
            "perspective",
            "id":
            sensor_id,
            "far_clip":
            self.far_clip.m_as(uck.get("length")),
            "fov":
            self.fov.m_as(ureg.deg),
            "to_world":
            ScalarTransform4f.look_at(origin=origin, target=target,
                                      up=self.up),
            "sampler": {
                "type": "independent",
                "sample_count": spp,
            },
            "film": {
                "type": "hdrfilm",
                "width": self.film_resolution[0],
                "height": self.film_resolution[1],
                "pixel_format": "luminance",
                "component_format": "float32",
                "rfilter": {
                    "type": "box"
                },
            },
        }

        return result
Example #13
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 #14
0
    def shapes(self, ctx: KernelDictContext) -> t.Dict:
        from mitsuba.core import ScalarTransform4f

        if ctx.ref:
            bsdf = {"type": "ref", "id": f"bsdf_{self.id}"}
        else:
            bsdf = self.bsdfs(ctx=ctx)[f"bsdf_{self.id}"]

        if self.mesh_units is None:
            scaling_factor = 1.0
        else:
            kernel_length = uck.get("length")
            scaling_factor = (1.0 * self.mesh_units).m_as(kernel_length)

        base_dict = {
            "filename": str(self.mesh_filename),
            "bsdf": bsdf,
            "to_world": ScalarTransform4f.scale(scaling_factor),
        }

        if self.mesh_filename.suffix == ".obj":
            base_dict["type"] = "obj"
        elif self.mesh_filename.suffix == ".ply":
            base_dict["type"] = "ply"
        else:
            raise ValueError(
                f"unsupported file extension '{self.mesh_filename.suffix}'")

        return {self.id: base_dict}
Example #15
0
    def instances(self, ctx: KernelDictContext) -> t.Dict:
        """
        Return instance plugin specifications.

        Parameters
        ----------
        ctx : :class:`.KernelDictContext`
            A context data structure containing parameters relevant for kernel
            dictionary generation.

        Returns
        -------
        dict
            A dictionary suitable for merge with a
            :class:`~eradiate.scenes.core.KernelDict` containing instances.
        """
        from mitsuba.core import ScalarTransform4f

        kernel_length = uck.get("length")

        return {
            f"{self.canopy_element.id}_instance_{i}": {
                "type":
                "instance",
                "group": {
                    "type": "ref",
                    "id": self.canopy_element.id
                },
                "to_world":
                ScalarTransform4f.translate(position.m_as(kernel_length)),
            }
            for i, position in enumerate(self.instance_positions)
        }
Example #16
0
    def shapes(self, ctx: KernelDictContext) -> t.Dict:
        """
        Return shape plugin specifications.

        Parameters
        ----------
        ctx : :class:`.KernelDictContext`
            A context data structure containing parameters relevant for kernel
            dictionary generation.

        Returns
        -------
        dict
            A dictionary suitable for merge with a :class:`.KernelDict`
            containing all the shapes in the leaf cloud.
        """
        from mitsuba.core import ScalarTransform4f, coordinate_system

        kernel_length = uck.get("length")
        shapes_dict = {}

        if ctx.ref:
            bsdf = {"type": "ref", "id": f"bsdf_{self.id}"}
        else:
            bsdf = self.bsdfs(ctx=ctx)[f"bsdf_{self.id}"]

        for i_leaf, (position, normal, radius) in enumerate(
            zip(
                self.leaf_positions.m_as(kernel_length),
                self.leaf_orientations,
                self.leaf_radii.m_as(kernel_length),
            )
        ):
            _, up = coordinate_system(normal)
            to_world = ScalarTransform4f.look_at(
                origin=position, target=position + normal, up=up
            ) * ScalarTransform4f.scale(radius)

            shapes_dict[f"{self.id}_leaf_{i_leaf}"] = {
                "type": "disk",
                "bsdf": bsdf,
                "to_world": to_world,
            }

        return shapes_dict
Example #17
0
    def kernel_item(self) -> t.Dict:
        """Return kernel item."""
        from mitsuba.core import ScalarTransform4f

        xmin = self.xmin.m_as(uck.get("length"))
        xmax = self.xmax.m_as(uck.get("length"))
        ymin = self.ymin.m_as(uck.get("length"))
        ymax = self.ymax.m_as(uck.get("length"))
        z = self.z.m_as(uck.get("length"))

        dx = xmax - xmin
        dy = ymax - ymin

        to_world = ScalarTransform4f.translate([
            0.5 * dx + xmin, 0.5 * dy + ymin, z
        ]) * ScalarTransform4f.scale([0.5 * dx, 0.5 * dy, 1.0])

        return {"type": "rectangle", "to_world": to_world}
Example #18
0
def test_centralpatch_scale_kernel_dict(mode_mono):
    from mitsuba.core import ScalarTransform4f

    cs = CentralPatchSurface(
        width=3000.0 * ureg.km,
        central_patch=LambertianSurface(width=100 * ureg.km),
        id="surface",
    )

    ctx = KernelDictContext()

    kernel_dict = cs.bsdfs(ctx=ctx)

    assert np.allclose(
        kernel_dict["bsdf_surface"]["weight"]["to_uv"].matrix,
        (ScalarTransform4f.scale(10) * ScalarTransform4f.translate(
            (-0.45, -0.45, 0))).matrix,
    )
Example #19
0
def camera(origin,
           lookat,
           up,
           fov,
           ext=None,
           near=0.01,
           far=1000.0,
           w=256,
           h=256,
           nsamples=4):
    if (not (ext is None)):
        transform = ScalarTransform4f(ext.cpu().numpy()[0])
    elif (type(origin) == torch.Tensor):
        origin = origin[0]
        lookat = lookat[0]
        up = up[0]

        transform = ScalarTransform4f.look_at(origin=origin,
                                              target=lookat,
                                              up=up)
    film = """<film type="hdrfilm">
            <integer name="width" value="%i"/>
            <integer name="height" value="%i"/>

            <rfilter type="gaussian"/>
        </film>""" % (w, h)
    sampler = """<sampler type="independent">
    <integer name="sample_count" value="%i"/>
        </sampler>""" % (nsamples)

    transform = """<transform version="2.0.0" name="to_world">\n
            <lookat origin="%f, %f, %f" target="%f, %f, %f" up="%f, %f, %f"/>\n
        </transform>""" % (origin[0], origin[1], origin[2], lookat[0],
                           lookat[1], lookat[2], up[0], up[1], up[2])

    xmlstr = """<sensor version="2.0.0" type="perspective">\n
        %s\n
        <float name="near_clip" value="%f"/>\n
        <float name="far_clip" value="%f"/>\n
        <float name="fov" value="%f"/>\n
        %s\n
        %s\n
    </sensor>""" % (transform, near, far, fov, film, sampler)
    return xmlstr
Example #20
0
def map_cube(xmin: float, xmax: float, ymin: float, ymax: float, zmin: float,
             zmax: float) -> "mitsuba.core.ScalarTransform4f":
    r"""
    Map the cube :math:`[-1, 1]^3` to
    :math:`[x_\mathrm{min}, x_\mathrm{max}] \times [y_\mathrm{min}, y_\mathrm{max}] \times [z_\mathrm{min}, z_\mathrm{max}]`.

    Parameters
    ----------
    xmin : float
        Minimum X value.

    xmax : float
        Maximum X value.

    ymin : float
        Minimum Y value.

    ymax : float
        Maximum Y value.

    zmin : float
        Minimum Z value.

    zmax : float
        Maximum Z value.

    Returns
    -------
    :class:`mitsuba.core.ScalarTransform4f`
        Computed transform matrix.

    Warnings
    --------
    You must select a Mitsuba variant before calling this function.
    """
    from mitsuba.core import ScalarTransform4f

    half_dx = (xmax - xmin) * 0.5
    half_dy = (ymax - ymin) * 0.5
    half_dz = (zmax - zmin) * 0.5
    scale_trafo = ScalarTransform4f.scale([half_dx, half_dy, half_dz])
    translate_trafo = ScalarTransform4f.translate(
        [xmin + half_dx, ymin + half_dy, half_dz + zmin])
    return translate_trafo * scale_trafo
Example #21
0
def test_ramiatm_experiment_kernel_dict(mode_mono, padding):
    from mitsuba.core import ScalarTransform4f

    ctx = KernelDictContext()

    # Surface width is appropriately inherited from canopy, when no atmosphere is present
    s = Rami4ATMExperiment(
        atmosphere=None,
        canopy=DiscreteCanopy.homogeneous(
            lai=3.0,
            leaf_radius=0.1 * ureg.m,
            l_horizontal=10.0 * ureg.m,
            l_vertical=2.0 * ureg.m,
            padding=padding,
        ),
        measures=[
            {
                "type": "distant",
                "id": "distant_measure"
            },
            {
                "type": "radiancemeter",
                "origin": [1, 0, 0],
                "id": "radiancemeter"
            },
        ],
    )
    kernel_scene = s.kernel_dict(ctx)
    assert np.allclose(
        kernel_scene["surface"]["to_world"].transform_point([1, -1, 0]),
        [5 * (2 * padding + 1), -5 * (2 * padding + 1), 0],
    )

    # -- Measures get no external medium assigned
    assert "medium" not in kernel_scene["distant_measure"]
    assert "medium" not in kernel_scene["radiancemeter"]

    # Surface width is appropriately inherited from atmosphere
    s = Rami4ATMExperiment(
        atmosphere=HomogeneousAtmosphere(width=ureg.Quantity(42.0, "km")),
        canopy=DiscreteCanopy.homogeneous(
            lai=3.0,
            leaf_radius=0.1 * ureg.m,
            l_horizontal=10.0 * ureg.m,
            l_vertical=2.0 * ureg.m,
            padding=padding,
        ),
    )
    kernel_dict = s.kernel_dict(ctx)
    assert np.allclose(
        kernel_dict["surface"]["to_world"].matrix,
        ScalarTransform4f.scale([21000, 21000, 1]).matrix,
    )
Example #22
0
    def shapes(self, ctx: KernelDictContext) -> KernelDict:
        """
        Return shape plugin specifications only.

        Parameters
        ----------
        ctx : :class:`.KernelDictContext`
            A context data structure containing parameters relevant for kernel
            dictionary generation.

        Returns
        -------
        :class:`.KernelDict`
            A kernel dictionary containing all the shapes attached to the
            surface.
        """
        from mitsuba.core import ScalarTransform4f, ScalarVector3f

        if ctx.ref:
            bsdf = {"type": "ref", "id": f"bsdf_{self.id}"}
        else:
            bsdf = self.bsdfs(ctx)[f"bsdf_{self.id}"]

        w = self.kernel_width(ctx).m_as(uck.get("length"))
        z = self.altitude.m_as(uck.get("length"))
        translate_trafo = ScalarTransform4f.translate(
            ScalarVector3f(0.0, 0.0, z))
        scale_trafo = ScalarTransform4f.scale(
            ScalarVector3f(w / 2.0, w / 2.0, 1.0))
        trafo = translate_trafo * scale_trafo

        return KernelDict({
            f"shape_{self.id}": {
                "type": "rectangle",
                "to_world": trafo,
                "bsdf": bsdf,
            }
        })
Example #23
0
def sensor_shape_dict(radius, center):
    from mitsuba.core import ScalarTransform4f

    d = {
        "type": "sphere",
        "radius": radius,
        "to_world": ScalarTransform4f.translate(center),
        "sensor": {
            "type": "irradiancemeter",
            "film": {
                "type": "hdrfilm",
                "width": 1,
                "height": 1,
                "rfilter": {"type": "box"}
            },
        }
    }

    return d
Example #24
0
def genXML(lx, ly, material, scale):
    scene = xml.load_dict({
        "type": "scene",
        "myintegrator": {
            "type": "path",
        },
        "mysensor": {
            "type":
            "perspective",
            "near_clip":
            0.1,
            "far_clip":
            1000.0,
            "to_world":
            ScalarTransform4f.look_at(origin=[0.0, 0.001, 1],
                                      target=[0, 0, 0],
                                      up=[0, 0, 1]),
            "myfilm": {
                "type": "hdrfilm",
                "rfilter": {
                    "type": "box"
                },
                "width": 256,
                "height": 256,
            },
            "mysampler": {
                "type": "independent",
                "sample_count": 4,
            },
        },
        "myemitter": {
            "type": "point",
            "intensity": 1.0,
            'position': [lx * scale, ly * scale, 1.1]
        },
        "myshape": {
            "type": "sphere",
            "radius": 0.2,
            "mybsdf": material,
        }
    })
    return scene
Example #25
0
    def _kernel_dict(self, sensor_id, spp):
        from mitsuba.core import ScalarTransform4f, ScalarVector3f, coordinate_system

        _, up = coordinate_system(self.direction)

        result = {
            "type":
            "distantflux",
            "id":
            sensor_id,
            "to_world":
            ScalarTransform4f.look_at(
                origin=[0, 0, 0],
                target=ScalarVector3f(self.direction),
                up=up,
            ),
            "sampler": {
                "type": "independent",
                "sample_count": spp,
            },
            "film": {
                "type": "hdrfilm",
                "width": self.film_resolution[0],
                "height": self.film_resolution[1],
                "pixel_format": "luminance",
                "component_format": "float32",
                "rfilter": {
                    "type": "box"
                },
            },
        }

        if self.target is not None:
            result["target"] = self.target.kernel_item()

        return result
Example #26
0
    def add_object(self, scene_dict):
        """
        Add registered meshes to given scene file format
        """

        if len(self.bssrdf) != len(self.mesh):
            exit("The number of registerd mesh and bssrdf are different!")

        num_mesh = len(self.bssrdf)
        num_obj = len(self.bssrdf_obj)

        for i in range(num_obj):
            i += 1

            scene_dict["obj_" + str(i)] = {
                "type": "shapegroup"
            }

        for i in range(num_mesh):
            i += 1
            bssrdf = self.bssrdf[i]
            mesh = self.mesh[i]

            axis = None
            if(mesh["rotate"]["axis"] == "x"):
                axis = [1, 0, 0]
            elif(mesh["rotate"]["axis"] == "y"):
                axis = [0, 1, 0]
            elif(mesh["rotate"]["axis"] == "z"):
                axis = [0, 0, 1]
            angle = mesh["rotate"]["angle"]


            if mesh["type"] == "rectangle":
                shape = {
                    "type": mesh["type"],
                    "to_world": ScalarTransform4f.translate(mesh["translate"])
                                * ScalarTransform4f.rotate(axis, angle)
                                * ScalarTransform4f.scale(mesh["scale"]),
                }
        
            else:
                shape = {
                    "type": mesh["type"],
                    "filename": mesh["filename"],
                    "to_world": ScalarTransform4f.translate(mesh["translate"])
                                * ScalarTransform4f.rotate(axis, angle)
                                * ScalarTransform4f.scale(mesh["scale"]),
                }

            bssrdf["trans"] = mesh["translate"]
            if(mesh["rotate"]["axis"] == "x"):
                bssrdf["rotate_x"] = angle
            elif(mesh["rotate"]["axis"] == "y"):
                bssrdf["rotate_y"] = angle
            elif(mesh["rotate"]["axis"] == "z"):
                bssrdf["rotate_z"] = angle

            bssrdf["height_max"] = mesh["height_max"]

            bsdf = {
                "bsdf_" + str(i): bssrdf
            }

            shape.update(bsdf)
            
            for j in range(num_obj):
                j += 1

                if i in self.bssrdf_obj[j]:
                    scene_dict["obj_" + str(j)][str(i)] = shape

        for i in range(num_obj):
            i += 1
            scene_dict["instance_" + str(i)] = {
                "type": "instance",
                "group":{
                    "type": "ref",
                    "id": "obj_" + str(i)
                }
            }

        return scene_dict
Example #27
0
params = traverse(scene)
print(params)
positions_buf = params['grid_mesh.vertex_positions_buf']
positions_initial = ravel(positions_buf)
normals_initial = ravel(params['grid_mesh.vertex_normals_buf'])
vertex_count = ek.slices(positions_initial)

filename = 'scene/diffuser_surface_1.jpg'
Thread.thread().file_resolver().append(os.path.dirname(filename))

# Create a texture with the reference displacement map
disp_tex_1 = xml.load_dict({
	"type" : "bitmap",
	"filename": "diffuser_surface_1.jpg",
	"to_uv" : ScalarTransform4f.scale([1, -1, 1]) # texture is upside-down
}).expand()[0]

# Create a texture with another displacement map
disp_tex_2 = xml.load_dict({
        "type" : "bitmap",
        "filename": "diffuser_surface_2.jpg",
        "to_uv" : ScalarTransform4f.scale([1, -1, 1]) # texture is upside-down
}).expand()[0]

# Create a fake surface interaction with an entry per vertex on the mesh
mesh_si = SurfaceInteraction3f.zero(vertex_count)
mesh_si.uv = ravel(params['grid_mesh.vertex_texcoords_buf'], dim=2)

# Evaluate the displacement map for the entire mesh
disp_tex_diffuser_1 = disp_tex_1.eval_1(mesh_si)
Example #28
0
def scene_dict(sensor_to_world=None):
    if sensor_to_world is None:
        sensor_to_world = ScalarTransform4f.look_at(
            origin=[0, 0, 0],
            target=[0, 0, 1],
            up=[0, 1, 0],
        )

    return {
        "type": "scene",
        "shape": {
            "type": "rectangle",
            "bsdf": {
                "type": "roughconductor"
            },
        },
        "illumination_r": {
            "type": "directional",
            "direction": direction_r,
            "irradiance": {
                "type": "rgb",
                "value": [1, 0, 0],
            },
        },
        "illumination_g": {
            "type": "directional",
            "direction": direction_g,
            "irradiance": {
                "type": "rgb",
                "value": [0, 1, 0],
            },
        },
        "illumination_b": {
            "type": "directional",
            "direction": direction_b,
            "irradiance": {
                "type": "rgb",
                "value": [0, 0, 1],
            },
        },
        "hdistant": {
            "type": "hdistant",
            "to_world": sensor_to_world,
            "sampler": {
                "type": "independent",
                "sample_count": 3200,
            },
            "film": {
                "type": "hdrfilm",
                "width": film_resolution,
                "height": film_resolution,
                "pixel_format": "rgb",
                "component_format": "float32",
                "rfilter": {
                    "type": "box"
                },
            }
        },
        #"camera": {
        #    "type": "perspective",
        #    "to_world": ScalarTransform4f.look_at(
        #        origin=[5, 5, 5],
        #        target=[0, 0, 0],
        #        up=[0, 0, 1],
        #    ),
        #    "sampler": {
        #        "type": "independent",
        #        "sample_count": 32,
        #    },
        #    "film": {
        #        "type": "hdrfilm",
        #        "width": 320,
        #        "height": 240,
        #        "pixel_format": "luminance",
        #        "component_format": "float32",
        #    }
        #},
        "integrator": {
            "type": "path"
        },
    }
def test_maximum_scene_size(mode_mono_double, json_metadata):
    r"""
    Maximum scene size (``path``)
    =============================

    This test searches for an order of magnitude of the maximum size a scene using
    a ``distant`` sensor without ray origin control can have. An arbitrary threshold
    is used as the pass/fail criterion for regression control.

    Rationale
    ---------

    - Geometry: a square surface with increasing sizes from 1.0 to 1e9.
      and a Lambertian BRDF with reflectance :math:`\rho = 0.5`.
    - Illumination: a directional light source at the zenith with radiance
      :math:`L_\mathrm{i} = 1.0`.
    - Sensor: a ``distant`` sensor targeting (0, 0, 0) with default ray origin control.

    Expected behaviour
    ------------------

    For all scene sizes below the parametrized size :code:`min_expected_size`
    the computational results must be equal to the theoretical prediction within
    a relative tolerance of 1e-5.
    """
    from mitsuba.core import ScalarTransform4f, ScalarVector3f

    min_expected_size = 1e2
    results = dict()
    spp = 1
    rho = 0.5
    li = 1.0
    expected = rho * li / np.pi

    for scene_size in sorted(
        [10.0 ** i for i in range(1, 9)]
        + [2.0 * 10 ** i for i in range(1, 8)]
        + [5.0 * 10 ** i for i in range(1, 8)]
    ):
        kernel_dict = KernelDict(
            {
                "type": "scene",
                "bsdf_surface": {
                    "type": "diffuse",
                    "reflectance": rho,
                },
                "surface": {
                    "type": "rectangle",
                    "to_world": ScalarTransform4f.scale(
                        ScalarVector3f(scene_size, scene_size, 1)
                    ),
                    "bsdf": {"type": "ref", "id": "bsdf_surface"},
                },
                "illumination": {
                    "type": "directional",
                    "direction": [0, 0, -1],
                    "irradiance": li,
                },
                "measure": {
                    "type": "distant",
                    "id": "measure",
                    "ray_target": [0, 0, 0],
                    "sampler": {"type": "independent", "sample_count": spp},
                    "film": {
                        "type": "hdrfilm",
                        "width": 32,
                        "height": 32,
                        "pixel_format": "luminance",
                        "component_format": "float32",
                        "rfilter": {"type": "box"},
                    },
                },
                "integrator": {"type": "path"},
            }
        )

        result = mitsuba_run(kernel_dict)["values"]["measure"].img
        results[scene_size] = np.allclose(result, expected, rtol=1e-5)

    # Report test metrics
    passed_sizes = [size for size in results if results[size]]
    maxsize = np.max(passed_sizes)

    json_metadata["metrics"] = {
        "test_maximum_scene_size": {
            "name": "Maximum scene size",
            "description": "The maximum scene size is:",
            "value": f"{float(maxsize):1.1e}",
            "units": "length units",
        }
    }

    # Final assertion
    assert np.all(
        [
            result
            for result in [
                results[size] for size in results if size <= min_expected_size
            ]
        ]
    )
Example #30
0
        #        "height": 240,
        #        "pixel_format": "luminance",
        #        "component_format": "float32",
        #    }
        #},
        "integrator": {
            "type": "path"
        },
    }


for name, sensor_to_world in {
        "default":
        ScalarTransform4f.look_at(
            origin=[0, 0, 0],
            target=[0, 0, 1],
            up=[0, 1, 0],
        ),
        "rotated":
        ScalarTransform4f.look_at(
            origin=[0, 0, 0],
            target=[0, 0, 1],
            up=[1, 1, 0],
        ),
}.items():
    scene = load_dict(scene_dict(sensor_to_world=sensor_to_world))
    sensor = scene.sensors()[0]
    scene.integrator().render(scene, sensor)

    # Plot recorded leaving radiance
    img = np.array(sensor.film().bitmap()).squeeze()