Skip to content

Commit 87364d9

Browse files
committed
Ported sensor tests to load_dict
1 parent fc3ab82 commit 87364d9

File tree

4 files changed

+204
-247
lines changed

4 files changed

+204
-247
lines changed

src/sensors/tests/test_irradiancemeter.py

Lines changed: 71 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -5,52 +5,58 @@
55
import mitsuba
66

77

8-
def example_shape(radius, center):
9-
from mitsuba.core.xml import load_string
10-
11-
xml = f"""
12-
<shape version='2.0.0' type="sphere">
13-
<float name="radius" value="{radius}"/>
14-
<transform name="to_world">
15-
<translate x="{center.x}" y="{center.y}" z="{center.z}"/>
16-
</transform>
17-
<sensor type="irradiancemeter">
18-
<film type="hdrfilm">
19-
<integer name="width" value="1"/>
20-
<integer name="height" value="1"/>
21-
</film>
22-
</sensor>
23-
</shape>
24-
"""
25-
return load_string(xml)
8+
def sensor_shape_dict(radius, center):
9+
from mitsuba.core import ScalarTransform4f
10+
11+
d = {
12+
"type": "sphere",
13+
"radius": radius,
14+
"to_world": ScalarTransform4f.translate(center),
15+
"sensor": {
16+
"type": "irradiancemeter",
17+
"film": {
18+
"type": "hdrfilm",
19+
"width": 1,
20+
"height": 1,
21+
"rfilter": {"type": "box"}
22+
},
23+
}
24+
}
25+
26+
return d
27+
2628

2729
def test_construct(variant_scalar_rgb):
28-
"""
29-
We construct an irradiance meter attached to a sphere and assert that the
30+
"""We construct an irradiance meter attached to a sphere and assert that the
3031
following parameters get set correctly:
3132
- associated shape
3233
- film
3334
"""
34-
from mitsuba.core import Vector3f
35-
center_v = Vector3f(0.0)
35+
from mitsuba.core import ScalarVector3f
36+
from mitsuba.core.xml import load_dict
37+
38+
center_v = ScalarVector3f(0.0)
3639
radius = 1.0
37-
sphere = example_shape(radius, center_v)
40+
sphere = load_dict(sensor_shape_dict(radius, center_v))
3841
sensor = sphere.sensor()
3942

4043
assert sensor.shape() == sphere
4144
assert ek.allclose(sensor.film().size(), [1, 1])
4245

4346

44-
@pytest.mark.parametrize(("center", "radius"), [([2.0, 5.0, 8.3], 2.0), ([0.0, 0.0, 0.0], 1.0), ([1.0, 4.0, 0.0], 5.0)])
47+
@pytest.mark.parametrize(
48+
("center", "radius"),
49+
[([2.0, 5.0, 8.3], 2.0), ([0.0, 0.0, 0.0], 1.0), ([1.0, 4.0, 0.0], 5.0)]
50+
)
4551
def test_sampling(variant_scalar_rgb, center, radius):
52+
"""We construct an irradiance meter attached to a sphere and assert that
53+
sampled rays originate at the sphere's surface
4654
"""
47-
We construct an irradiance meter attached to a sphere and assert that sampled
48-
rays originate at the sphere's surface
49-
"""
50-
from mitsuba.core import Vector3f
55+
from mitsuba.core import ScalarVector3f
56+
from mitsuba.core.xml import load_dict
5157

52-
center_v = Vector3f(center)
53-
sphere = example_shape(radius, center_v)
58+
center_v = ScalarVector3f(center)
59+
sphere = load_dict(sensor_shape_dict(radius, center_v))
5460
sensor = sphere.sensor()
5561
num_samples = 100
5662

@@ -59,13 +65,22 @@ def test_sampling(variant_scalar_rgb, center, radius):
5965
dir_samples = np.random.rand(num_samples, 2)
6066

6167
for i in range(100):
62-
ray = sensor.sample_ray_differential(0.0, wav_samples[i], pos_samples[i], dir_samples[i])[0]
68+
ray = sensor.sample_ray_differential(
69+
0.0, wav_samples[i], pos_samples[i], dir_samples[i])[0]
6370

6471
# assert that the ray starts at the sphere surface
6572
assert ek.allclose(ek.norm(center_v - ray.o), radius)
6673
# assert that all rays point away from the sphere center
6774
assert ek.dot(ek.normalize(ray.o - center_v), ray.d) > 0.0
6875

76+
77+
def constant_emitter_dict(radiance):
78+
return {
79+
"type": "constant",
80+
"radiance": {"type": "uniform", "value": radiance}
81+
}
82+
83+
6984
@pytest.mark.parametrize("radiance", [2.04, 1.0, 0.0])
7085
def test_incoming_flux(variant_scalar_rgb, radiance):
7186
"""
@@ -77,39 +92,16 @@ def test_incoming_flux(variant_scalar_rgb, radiance):
7792
We expect the average value to be \\pi * L with L the radiance of the constant
7893
emitter.
7994
"""
80-
from mitsuba.core import Spectrum
81-
from mitsuba.core.xml import load_string
82-
83-
sensor_xml = f"""
84-
<shape version='2.0.0' type="sphere">
85-
<float name="radius" value="1"/>
86-
<transform name="to_world">
87-
<translate x="0" y="0" z="0"/>
88-
</transform>
89-
<sensor type="irradiancemeter">
90-
<film type="hdrfilm">
91-
<integer name="width" value="1"/>
92-
<integer name="height" value="1"/>
93-
</film>
94-
</sensor>
95-
</shape>
96-
"""
95+
from mitsuba.core import Spectrum, ScalarVector3f
96+
from mitsuba.core.xml import load_dict
9797

98-
emitter_xml = f"""
99-
<emitter type="constant">
100-
<spectrum name="radiance" type='uniform'>
101-
<float name="value" value="{radiance}"/>
102-
</spectrum>
103-
</emitter>
104-
"""
98+
scene_dict = {
99+
"type": "scene",
100+
"sensor": sensor_shape_dict(1, ScalarVector3f(0, 0, 0)),
101+
"emitter": constant_emitter_dict(radiance)
102+
}
105103

106-
scene_xml = f"""
107-
<scene version="2.0.0">
108-
{sensor_xml}
109-
{emitter_xml}
110-
</scene>
111-
"""
112-
scene = load_string(scene_xml)
104+
scene = load_dict(scene_dict)
113105
sensor = scene.sensors()[0]
114106

115107
power_density_cum = 0.0
@@ -120,14 +112,17 @@ def test_incoming_flux(variant_scalar_rgb, radiance):
120112
dir_samples = np.random.rand(num_samples, 2)
121113

122114
for i in range(100):
123-
ray, weight = sensor.sample_ray_differential(0.0, wav_samples[i], pos_samples[i], dir_samples[i])
115+
ray, weight = sensor.sample_ray_differential(
116+
0.0, wav_samples[i], pos_samples[i], dir_samples[i])
124117

125118
intersection = scene.ray_intersect(ray)
126-
power_density_cum += weight * intersection.emitter(scene).eval(intersection)
119+
power_density_cum += weight * \
120+
intersection.emitter(scene).eval(intersection)
127121
power_density_avg = power_density_cum / float(num_samples)
128122

129123
assert ek.allclose(power_density_avg, Spectrum(ek.pi * radiance))
130124

125+
131126
@pytest.mark.parametrize("radiance", [2.04, 1.0, 0.0])
132127
def test_incoming_flux_integrator(variant_scalar_rgb, radiance):
133128
"""
@@ -140,59 +135,24 @@ def test_incoming_flux_integrator(variant_scalar_rgb, radiance):
140135
emitter.
141136
"""
142137

143-
from mitsuba.core import Spectrum, Bitmap, Struct
144-
from mitsuba.core.xml import load_string
145-
146-
sensor_xml = f"""
147-
<shape version='2.0.0' type="sphere">
148-
<float name="radius" value="1"/>
149-
<transform name="to_world">
150-
<translate x="0" y="0" z="0"/>
151-
</transform>
152-
<sensor type="irradiancemeter">
153-
<film type="hdrfilm">
154-
<integer name="width" value="1"/>
155-
<integer name="height" value="1"/>
156-
</film>
157-
</sensor>
158-
</shape>
159-
"""
160-
161-
emitter_xml = f"""
162-
<emitter type="constant">
163-
<spectrum name="radiance" type='uniform'>
164-
<float name="value" value="{radiance}"/>
165-
</spectrum>
166-
</emitter>
167-
"""
138+
from mitsuba.core import Spectrum, Bitmap, Struct, ScalarVector3f
139+
from mitsuba.core.xml import load_dict
168140

169-
integrator_xml = f"""
170-
<integrator type="path">
141+
scene_dict = {
142+
"type": "scene",
143+
"sensor": sensor_shape_dict(1, ScalarVector3f(0, 0, 0)),
144+
"emitter": constant_emitter_dict(radiance),
145+
"integrator": {"type": "path"}
146+
}
171147

172-
<integer name="max_depth" value="-1"/>
173-
</integrator>
174-
"""
175-
176-
sampler_xml = f"""
177-
<sampler type="independent">
178-
<integer name="sample_count" value="100"/>
179-
</sampler>
180-
"""
181-
scene_xml = f"""
182-
<scene version="2.0.0">
183-
{integrator_xml}
184-
{sensor_xml}
185-
{emitter_xml}
186-
{sampler_xml}
187-
</scene>
188-
"""
189-
scene = load_string(scene_xml)
148+
scene = load_dict(scene_dict)
190149
sensor = scene.sensors()[0]
191150

192151
scene.integrator().render(scene, sensor)
193152
film = sensor.film()
194153

195-
img = film.bitmap(raw=True).convert(Bitmap.PixelFormat.Y, Struct.Type.Float32, srgb_gamma=False)
154+
img = film.bitmap(raw=True).convert(Bitmap.PixelFormat.Y,
155+
Struct.Type.Float32, srgb_gamma=False)
196156
image_np = np.array(img)
197157

198-
ek.allclose(image_np, (radiance*ek.pi))
158+
ek.allclose(image_np, (radiance * ek.pi))

src/sensors/tests/test_perspective.py

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,36 @@
33
import enoki as ek
44

55

6-
def create_camera(o, d, fov=34, fov_axis='x', s_open=1.5, s_close=5):
7-
from mitsuba.core.xml import load_string
8-
return load_string("""<sensor version='2.0.0' type='perspective'>
9-
<float name='near_clip' value='1'/>
10-
<float name='far_clip' value='35'/>
11-
<float name='focus_distance' value='15'/>
12-
<float name='fov' value='{fov}'/>
13-
<string name='fov_axis' value='{fov_axis}'/>
14-
<float name='shutter_open' value='{so}'/>
15-
<float name='shutter_close' value='{sc}'/>
16-
<transform name="to_world">
17-
<lookat origin="{ox}, {oy}, {oz}"
18-
target="{tx}, {ty}, {tz}"
19-
up =" 0.0, 1.0, 0.0"/>
20-
</transform>
21-
<film type="hdrfilm">
22-
<integer name="width" value="512"/>
23-
<integer name="height" value="256"/>
24-
</film>
25-
</sensor> """.format(ox=o[0], oy=o[1], oz=o[2],
26-
tx=o[0]+d[0], ty=o[1]+d[1], tz=o[2]+d[2],
27-
fov=fov, fov_axis=fov_axis, so=s_open, sc=s_close))
28-
29-
30-
origins = [[1.0, 0.0, 1.5], [1.0, 4.0, 1.5]]
6+
def create_camera(o, d, fov=34, fov_axis="x", s_open=1.5, s_close=5):
7+
from mitsuba.core.xml import load_dict
8+
from mitsuba.core import ScalarTransform4f, ScalarVector3f
9+
t = [o[0] + d[0], o[1] + d[1], o[2] + d[2]]
10+
11+
camera_dict = {
12+
"type": "perspective",
13+
"near_clip": 1.0,
14+
"far_clip": 35.0,
15+
"focus_distance": 15.0,
16+
"fov": fov,
17+
"fov_axis": fov_axis,
18+
"shutter_open": s_open,
19+
"shutter_close": s_close,
20+
"to_world": ScalarTransform4f.look_at(
21+
origin=o,
22+
target=t,
23+
up=[0, 1, 0]
24+
),
25+
"film": {
26+
"type": "hdrfilm",
27+
"width": 512,
28+
"height": 256,
29+
}
30+
}
31+
32+
return load_dict(camera_dict)
33+
34+
35+
origins = [[1.0, 0.0, 1.5], [1.0, 4.0, 1.5]]
3136
directions = [[0.0, 0.0, 1.0], [1.0, 0.0, 0.0]]
3237

3338

0 commit comments

Comments
 (0)