55import 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
2729def 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+ )
4551def 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 ])
7085def 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 ])
132127def 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 ))
0 commit comments