def test_ray_differential(self): r = Ray(Point(0, 0, 0), Vector(1, 2, 3)) rd = RayDifferential(Point(0, 0, 0), Vector(1, 2, 3)) # test copy constructor from Ray rd.has_differentials = True rd1 = RayDifferential.from_ray_differential(rd) self.assertTrue(isinstance(rd1, RayDifferential)) self.assertEqual(rd1.o, rd.o) self.assertEqual(rd1.d, rd.d) self.assertEqual(rd1.rx_origin, rd.rx_origin) self.assertEqual(rd1.ry_origin, rd.ry_origin) self.assertEqual(rd1.rx_direction, rd.rx_direction) self.assertEqual(rd1.ry_direction, rd.ry_direction) self.assertEqual(rd1.has_differentials, rd.has_differentials) # test copy constructor from Ray rd2 = RayDifferential.from_ray(r) self.assertTrue(isinstance(rd2, RayDifferential)) self.assertEqual(rd2.d, r.d) self.assertEqual(rd2.has_differentials, False) # test constructor from parent ray rd3 = RayDifferential.from_ray_parent(r.o, r.d, r, r.mint) self.assertTrue(isinstance(rd3, RayDifferential)) self.assertEqual(rd3.depth, r.depth+1) # test operator() p = rd(1.7) self.assertEqual(p, Point(1.7, 3.4, 5.1))
def generate_ray_differential(self, sample): """Generate a RayDifferential from the camera.""" # generate the ray weight, ray = self.generate_ray(sample) ray_diff = RayDifferential.from_ray(ray) # find ray after shifting one pixel in the x direction sshift = CameraSample.from_sample(sample) sshift.image_x += 1 weight_x, ray_x = self.generate_ray(sshift) ray_diff.rx_origin = ray_x.o ray_diff.rx_direction = ray_x.d # find ray after shifting one pixel in the y direction sshift.image_x -= 1 sshift.image_y += 1 weight_y, ray_y = self.generate_ray(sshift) ray_diff.ry_origin = ray_y.o ray_diff.ry_direction = ray_y.d if (weight_x == 0.0) or (weight_y == 0.0): return 0.0, ray_diff ray_diff.has_differentials = True return weight, ray_diff
def test_ray_differential(self): r = Ray(Point(0, 0, 0), Vector(1, 2, 3)) rd = RayDifferential(Point(0, 0, 0), Vector(1, 2, 3)) # test copy constructor from Ray rd.has_differentials = True rd1 = RayDifferential.from_ray_differential(rd) self.assertTrue(isinstance(rd1, RayDifferential)) self.assertEqual(rd1.o, rd.o) self.assertEqual(rd1.d, rd.d) self.assertEqual(rd1.rx_origin, rd.rx_origin) self.assertEqual(rd1.ry_origin, rd.ry_origin) self.assertEqual(rd1.rx_direction, rd.rx_direction) self.assertEqual(rd1.ry_direction, rd.ry_direction) self.assertEqual(rd1.has_differentials, rd.has_differentials) # test copy constructor from Ray rd2 = RayDifferential.from_ray(r) self.assertTrue(isinstance(rd2, RayDifferential)) self.assertEqual(rd2.d, r.d) self.assertEqual(rd2.has_differentials, False) # test constructor from parent ray rd3 = RayDifferential.from_ray_parent(r.o, r.d, r, r.mint) self.assertTrue(isinstance(rd3, RayDifferential)) self.assertEqual(rd3.depth, r.depth + 1) # test operator() p = rd(1.7) self.assertEqual(p, Point(1.7, 3.4, 5.1))
def generate_ray_differential(self, sample): """Generate a RayDifferential from the camera.""" # Generate raster and camera samples p_ras = Point(sample.image_x, sample.image_y, 0) p_camera = self.raster_to_camera(p_ras) ray = RayDifferential(Point(0, 0, 0), normalize(Vector.from_point(p_camera)), 0.0, float('inf')) # Modify ray for depth of field if self.lens_radius > 0.0: # Sample point on lens lens_u, lens_v = concentric_sample_disk(sample.lens_u, sample.lens_v) lens_u *= self.lens_radius lens_v *= self.lens_radius # Compute point on plane of focus ft = self.focal_distance / ray.d.z p_focus = ray(ft) # Update ray for effect of lens ray.o = Point(lens_u, lens_v, 0.0) ray.d = normalize(p_focus - ray.o) ray.rx_origin = Point.from_point(ray.o) ray.ry_origin = Point.from_point(ray.o) ray.rx_direction = normalize(Vector.from_point(p_camera) + \ self.dx_camera) ray.ry_direction = normalize(Vector.from_point(p_camera) + \ self.dy_camera) ray.time = sample.time ray = self.camera_to_world(ray) ray.has_differentials = True return 1.0, ray
def test_transform_ray(self): ray_differential = RayDifferential(origin=Point(1,2,3), direction=Vector(10,20,30)) ray_differential.rx_origin = Point(4,5,6) ray_differential.ry_origin = Point(5,6,7) ray_differential.rx_direction = Vector(2,3,4) ray_differential.ry_direction = Vector(3,4,5) ray_transformed = translate(Point(10,20,30))(ray_differential) self.assertTrue(isinstance(ray_transformed, RayDifferential)) self.assertEqual(ray_transformed.o, Point(11,22,33)) self.assertEqual(ray_transformed.d, Vector(10,20,30)) self.assertEqual(ray_transformed.rx_origin, Point(14,25,36)) self.assertEqual(ray_transformed.ry_origin, Point(15,26,37)) self.assertEqual(ray_transformed.rx_direction, Vector(2,3,4)) self.assertEqual(ray_transformed.ry_direction, Vector(3,4,5))
def __call__(self, elt): """Overload the operator(). Supported operations: * Transform(Point) * Transform(Vector) * Transform(Normal) * Transform(Ray) * Transform(RayDifferential) * Transform(BBox) """ if isinstance(elt, Point): x = elt.x y = elt.y z = elt.z xp = self.m.m[0][0] * x + self.m.m[0][1] * y + self.m.m[0][ 2] * z + self.m.m[0][3] yp = self.m.m[1][0] * x + self.m.m[1][1] * y + self.m.m[1][ 2] * z + self.m.m[1][3] zp = self.m.m[2][0] * x + self.m.m[2][1] * y + self.m.m[2][ 2] * z + self.m.m[2][3] wp = self.m.m[3][0] * x + self.m.m[3][1] * y + self.m.m[3][ 2] * z + self.m.m[3][3] if wp == 1.0: return Point(xp, yp, zp) else: return Point(xp, yp, zp) / wp elif isinstance(elt, Vector): x = elt.x y = elt.y z = elt.z xp = self.m.m[0][0] * x + self.m.m[0][1] * y + self.m.m[0][2] * z yp = self.m.m[1][0] * x + self.m.m[1][1] * y + self.m.m[1][2] * z zp = self.m.m[2][0] * x + self.m.m[2][1] * y + self.m.m[2][2] * z return Vector(xp, yp, zp) elif isinstance(elt, Normal): x = elt.x y = elt.y z = elt.z return Normal( self.m_inv.m[0][0] * x + self.m_inv.m[1][0] * y + self.m_inv.m[2][0] * z, self.m_inv.m[0][1] * x + self.m_inv.m[1][1] * y + self.m_inv.m[2][1] * z, self.m_inv.m[0][2] * x + self.m_inv.m[1][2] * y + self.m_inv.m[2][2] * z) elif isinstance(elt, RayDifferential): ray = RayDifferential.from_ray_differential(elt) ray.o = self(ray.o) ray.d = self(ray.d) ray.rx_origin = self(ray.rx_origin) ray.ry_origin = self(ray.ry_origin) ray.rx_direction = self(ray.rx_direction) ray.ry_direction = self(ray.ry_direction) return ray elif isinstance(elt, Ray): ray = Ray.from_ray(elt) ray.o = self(ray.o) ray.d = self(ray.d) return ray elif isinstance(elt, BBox): ret = BBox(self(Point(elt.p_min.x, elt.p_min.y, elt.p_min.z))) ret = union(ret, self(Point(elt.p_max.x, elt.p_min.y, elt.p_min.z))) ret = union(ret, self(Point(elt.p_min.x, elt.p_max.y, elt.p_min.z))) ret = union(ret, self(Point(elt.p_min.x, elt.p_min.y, elt.p_max.z))) ret = union(ret, self(Point(elt.p_min.x, elt.p_max.y, elt.p_max.z))) ret = union(ret, self(Point(elt.p_max.x, elt.p_max.y, elt.p_min.z))) ret = union(ret, self(Point(elt.p_max.x, elt.p_min.y, elt.p_max.z))) ret = union(ret, self(Point(elt.p_max.x, elt.p_max.y, elt.p_max.z))) return ret
def __call__(self, elt): """Overload the operator(). Supported operations: * Transform(Point) * Transform(Vector) * Transform(Normal) * Transform(Ray) * Transform(RayDifferential) * Transform(BBox) """ if isinstance(elt, Point): x = elt.x y = elt.y z = elt.z xp = self.m.m[0][0]*x + self.m.m[0][1]*y + self.m.m[0][2]*z + self.m.m[0][3] yp = self.m.m[1][0]*x + self.m.m[1][1]*y + self.m.m[1][2]*z + self.m.m[1][3] zp = self.m.m[2][0]*x + self.m.m[2][1]*y + self.m.m[2][2]*z + self.m.m[2][3] wp = self.m.m[3][0]*x + self.m.m[3][1]*y + self.m.m[3][2]*z + self.m.m[3][3] if wp == 1.0: return Point(xp, yp, zp) else: return Point(xp, yp, zp)/wp elif isinstance(elt, Vector): x = elt.x y = elt.y z = elt.z xp = self.m.m[0][0]*x + self.m.m[0][1]*y + self.m.m[0][2]*z yp = self.m.m[1][0]*x + self.m.m[1][1]*y + self.m.m[1][2]*z zp = self.m.m[2][0]*x + self.m.m[2][1]*y + self.m.m[2][2]*z return Vector(xp, yp, zp) elif isinstance(elt, Normal): x = elt.x y = elt.y z = elt.z return Normal(self.m_inv.m[0][0]*x + self.m_inv.m[1][0]*y + self.m_inv.m[2][0]*z, self.m_inv.m[0][1]*x + self.m_inv.m[1][1]*y + self.m_inv.m[2][1]*z, self.m_inv.m[0][2]*x + self.m_inv.m[1][2]*y + self.m_inv.m[2][2]*z) elif isinstance(elt, RayDifferential): ray = RayDifferential.from_ray_differential(elt) ray.o = self(ray.o) ray.d = self(ray.d) ray.rx_origin = self(ray.rx_origin) ray.ry_origin = self(ray.ry_origin) ray.rx_direction = self(ray.rx_direction) ray.ry_direction = self(ray.ry_direction) return ray elif isinstance(elt, Ray): ray = Ray.from_ray(elt) ray.o = self(ray.o) ray.d = self(ray.d) return ray elif isinstance(elt, BBox): ret = BBox(self(Point(elt.p_min.x, elt.p_min.y, elt.p_min.z))) ret = union(ret, self(Point(elt.p_max.x, elt.p_min.y, elt.p_min.z))) ret = union(ret, self(Point(elt.p_min.x, elt.p_max.y, elt.p_min.z))) ret = union(ret, self(Point(elt.p_min.x, elt.p_min.y, elt.p_max.z))) ret = union(ret, self(Point(elt.p_min.x, elt.p_max.y, elt.p_max.z))) ret = union(ret, self(Point(elt.p_max.x, elt.p_max.y, elt.p_min.z))) ret = union(ret, self(Point(elt.p_max.x, elt.p_min.y, elt.p_max.z))) ret = union(ret, self(Point(elt.p_max.x, elt.p_max.y, elt.p_max.z))) return ret