Example #1
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 #2
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, 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 #4
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 #5
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 #6
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 #7
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)
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 #10
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 #11
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 #12
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 #13
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 #14
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 #15
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 #16
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