-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpathrecord.py
59 lines (45 loc) · 1.66 KB
/
pathrecord.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import mitsuba as mi
from typing import overload
import drjit as dr
def drjitstruct(cls):
annotations = cls.__dict__.get('__annotations__', {})
drjit_struct = {}
for name, type in annotations.items():
drjit_struct[name] = type
cls.DRJIT_STRUCT = drjit_struct
return cls
# Need to record parameters to reconstruct surface intaraction
@drjitstruct
class PVert:
f: mi.Spectrum
L: mi.Spectrum
i: mi.Interaction3f
ps: mi.PositionSample3f
def __init__(self, f=mi.Spectrum(), L=mi.Spectrum(), i=mi.Interaction3f(), ps=mi.PositionSample3f):
self.f = f
self.L = L
self.i = i
self.ps = ps
class Path:
idx: mi.UInt32
def __init__(self, n_rays: int, max_depth: int, dtype=PVert):
self.n_rays = n_rays
self.max_depth = max_depth
self.idx = dr.arange(mi.UInt32, n_rays)
self.dtype = dtype
self.vertices = dr.zeros(dtype, shape=(self.max_depth * self.n_rays))
def __setitem__(self, depth: mi.UInt32, value):
dr.scatter(self.vertices, value, depth * self.n_rays + self.idx)
# Return vertex at depth
@overload
def __getitem__(self, depth: mi.UInt32) -> PVert:
...
# Return a vertex at (depth, ray_index)
@overload
def __getitem__(self, idx: (mi.UInt32, mi.UInt32)) -> PVert:
...
def __getitem__(self, idx):
if isinstance(idx, mi.UInt32):
return dr.gather(self.dtype, self.vertices, idx * self.n_rays + self.idx)
if isinstance(idx, tuple) and isinstance(idx[0], mi.UInt32) and isinstance(idx[1], mi.UInt32):
return dr.gather(self.dtype, self.vertices, idx[0] * self.n_rays + idx[1])