Example #1
0
 def __init__(self, v=None, w=1.0):
     """Default constructor for Quaternion."""
     if v is None:
         self.v = Vector(0.0, 0.0, 0.0)
     else:
         self.v = Vector.from_vector(v)
     self.w = w
Example #2
0
    def generate_ray(self, sample):
        """Generate a Ray 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 = Ray(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.time = sample.time
        ray = self.camera_to_world(ray)

        return 1.0, ray
Example #3
0
 def from_transform(cls, transform):
     """Constructor from a Transform."""
     m = transform.m
     trace = m.m[0][0] + m.m[1][1] + m.m[2][2]
     v = Vector()
     w = 1.0
     if trace > 0.0:
         # Compute w from matrix trace, then xyz
         # 4w^2 = m[0][0] + m[1][1] + m[2][2] + m[3][3] (but m[3][3] == 1)
         s = math.sqrt(trace + 1.0)
         w = s / 2.0
         s = 0.5 / s
         v.x = (m.m[2][1] - m.m[1][2]) * s
         v.y = (m.m[0][2] - m.m[2][0]) * s
         v.z = (m.m[1][0] - m.m[0][1]) * s
     else:
         # Compute largest of $x$, $y$, or $z$, then remaining components
         q = [0.0, 0.0, 0.0]
         i = 0
         if m.m[1][1] > m.m[0][0]:
             i = 1
         if m.m[2][2] > m.m[i][i]:
             i = 2
         j = (i+1) % 3
         k = (j+1) % 3
         s = math.sqrt((m.m[i][i] - (m.m[j][j] + m.m[k][k])) + 1.0)
         q[i] = s * 0.5
         if s != 0.0:
             s = 0.5 / s
         w = (m.m[k][j] - m.m[j][k]) * s
         q[j] = (m.m[j][i] + m.m[i][j]) * s
         q[k] = (m.m[k][i] + m.m[i][k]) * s
         v.x = q[0]
         v.y = q[1]
         v.z = q[2]
     return cls(v, w)
Example #4
0
    def __init__(self, primitives, refine_immediately):
        """Default constructor for GridAccel."""
        # initialize self.primitives with primitives for grid
        if refine_immediately:
            self.primitives = []
            for primitive in primitives:
                primitive.fully_refine(self.primitives)
        else:
            self.primitives = list(primitives)

        # compute bounds and choose grid resolution
        self.bounds = BBox()
        for primitive in self.primitives:
            self.bounds = union(self.bounds, primitive.world_bound())
        delta = self.bounds.p_max - self.bounds.p_min

        # find voxels_per_unit_dist for grid
        max_axis = self.bounds.maximum_extent()
        inv_max_width = 1.0 / delta[max_axis]
        cube_root = 3.0 * pow(len(self.primitives), 1.0 / 3.0)
        voxels_per_unit_dist = cube_root * inv_max_width
        self.n_voxels = []
        for axis in range(3):
            self.n_voxels.append(
                clamp(round_to_int(delta[axis] * voxels_per_unit_dist), 1, 64))

        # compute voxel widths and allocate voxels
        self.width = Vector()
        self.inv_width = Vector()
        for axis in range(3):
            self.width[axis] = delta[axis] / self.n_voxels[axis]
            if self.width[axis] == 0.0:
                self.inv_width[axis] = 0.0
            else:
                self.inv_width[axis] = 1.0 / self.width[axis]
        nv = self.n_voxels[0] * self.n_voxels[1] * self.n_voxels[2]

        # array of voxels, initialized at None
        self.voxels = [None] * nv

        # add primitives to grid voxels
        for primitive in self.primitives:
            # find voxel extent of primitive
            primitive_bound = primitive.world_bound()
            v_min = []
            v_max = []
            for axis in range(3):
                v_min.append(self._pos_to_voxel(primitive_bound.p_min, axis))
                v_max.append(self._pos_to_voxel(primitive_bound.p_max, axis))

            # add primitive to overlapping voxels
            for z in range(v_min[2], v_max[2] + 1):
                for y in range(v_min[1], v_max[1] + 1):
                    for x in range(v_min[0], v_max[0] + 1):
                        index = self._offset(x, y, z)
                        if self.voxels[index] is None:
                            self.voxels[index] = Voxel(primitive)
                        else:
                            self.voxels[index].add_primitive(primitive)

        # create reader-writer mutex for grid
        self.rw_lock = DummyRWLock()
Example #5
0
 def setUp(self):
     self.v1 = Vector(1, 1, 1)
     self.v2 = Vector(2, 2, 2)
     self.p1 = Point(1, 1, 1)
     self.p2 = Point(2, 2, 2)
Example #6
0
class TestGeometry(unittest.TestCase):
    
    def setUp(self):
        self.v1 = Vector(1, 1, 1)
        self.v2 = Vector(2, 2, 2)
        self.p1 = Point(1, 1, 1)
        self.p2 = Point(2, 2, 2)

    def get_random_point(self):
        return Point(float(random.randint(0,100)) / 20.0,
                     float(random.randint(0,100)) / 20.0,
                     float(random.randint(0,100)) / 20.0)
    
    def test_point(self):
        # operator[]
        p = Point(1.0, 2.0, 3.0)
        self.assertEqual(p[0], 1.0)
        self.assertEqual(p[1], 2.0)
        self.assertEqual(p[2], 3.0)

        self.assertEqual(self.p1 * 4, 2 * self.p2)
        self.assertEqual(self.p2 - self.p1, self.v1)

        # operator[] for assignments
        p = Point(1.0, 2.0, 3.0)
        for i in range(3):
            p[i] = 9.0
            self.assertEqual(p[i], 9.0)

    def test_vector(self):
        # operator[]
        v = Vector(1.0, 2.0, 3.0)
        self.assertEqual(v[0], 1.0)
        self.assertEqual(v[1], 2.0)
        self.assertEqual(v[2], 3.0)

        # misc operators
        self.assertEqual(self.v1 * 4, 2 * self.v2)
        self.assertEqual(self.p2 - self.p1, self.v1)

        # length functions
        self.assertEqual(self.v1.length_squared(), 3)
        self.assertEqual(self.v1.length(), math.sqrt(3))

        # operator[] for assignments
        v = Vector(1.0, 2.0, 3.0)
        for i in range(3):
            v[i] = 9.0
            self.assertEqual(v[i], 9.0)

    def test_normal(self):
        # operator[]
        n = Normal(1.0, 2.0, 3.0)
        self.assertEqual(n[0], 1.0)
        self.assertEqual(n[1], 2.0)
        self.assertEqual(n[2], 3.0)

        # face_forward
        n2 = Normal(1, 0, 0)
        v = Vector(-0.5, -0.1, 0.2)
        self.assertEqual(face_forward(n, v), -n)

        # operator[] for assignments
        n = Normal(1.0, 2.0, 3.0)
        for i in range(3):
            n[i] = 9.0
            self.assertEqual(n[i], 9.0)
    
    def test_ray(self):
        r = Ray(Point(0, 0, 0), Vector(1, 2, 3))
        
        # test copy constructor
        r2 = Ray.from_ray(r)
        self.assertTrue(isinstance(r2, Ray))
        self.assertEqual(r2.d, r.d)

        # test constructor from parent ray
        r3 = Ray.from_ray_parent(r.o, r.d, r, r.mint)
        self.assertTrue(isinstance(r3, Ray))
        self.assertEqual(r3.depth, r.depth+1)

        # test operator()
        p = r(1.7)        
        self.assertEqual(p, Point(1.7, 3.4, 5.1))        

    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 test_bounding_box_1(self):
        # test default constructor
        b = BBox()
        self.assertEqual(b.p_min,
                         Point(float('inf'), float('inf'), float('inf')))
        self.assertEqual(b.p_max,
                         Point(-float('inf'), -float('inf'), -float('inf')))

    def test_bounding_box_2(self):
        # test constructor from one point
        p = self.get_random_point()
        b1 = BBox(p)
        self.assertEqual(b1.p_min, p)
        self.assertEqual(b1.p_min, b1.p_max)

    def test_bounding_box_3(self):
        # test constructor from two points
        p1 = self.get_random_point()
        p2 = self.get_random_point()
        b2 = BBox(p1, p2)
        for i in range(3):
            self.assertEqual(b2.p_min[i], min(p1[i], p2[i]))
            self.assertEqual(b2.p_max[i], max(p1[i], p2[i]))

    def test_bounding_box_4(self):
        # test copy constructor
        bbox = BBox(Point(5, 5, 5),
                    Point(7, 7, 7))
        bbox2 = BBox.from_bbox(bbox)
        self.assertEqual(bbox.p_min, bbox2.p_min)
        self.assertEqual(bbox.p_max, bbox2.p_max)

        p1 = Point(6, 5.5, 7)
        p2 = Point(6, 7.5, 7)
        p3 = Point(6, 6.5, 4.5)
        
        # test methods
        self.assertEqual(bbox.inside(p1), True)
        self.assertEqual(bbox.inside(p2), False)
        self.assertEqual(bbox.inside(p3), False)
        
        bbox.expand(1)
        self.assertEqual(bbox.inside(p1), True)
        self.assertEqual(bbox.inside(p2), True)
        self.assertEqual(bbox.inside(p3), True)

    def test_bounding_box_5(self):
        bbox1 = BBox(Point(0, -2, 0),
                     Point(1, -1, 1))
        p1 = Point(-3,3,0.5)
        bbox2 = union(bbox1, p1)
        self.assertEqual(bbox2.p_min, Point(-3, -2, 0))
        self.assertEqual(bbox2.p_max, Point(1, 3, 1))

    def test_bounding_box_6(self):
        bbox1 = BBox(Point(0, -2, 0),
                     Point(1, -1, 1))
        bbox2 = BBox(Point(-2, 0, -2),
                     Point(-1, 1, -1))
        bbox3 = union(bbox1, bbox2)
        self.assertEqual(bbox3.p_min, Point(-2, -2, -2))
        self.assertEqual(bbox3.p_max, Point(1, 1, 1))

    def test_bounding_box_7(self):
        bbox1 = BBox(Point(0, 0, 0),
                     Point(2, 2, 2))

        bbox2 = BBox(Point(2.5, 2.5, 2.5),
                     Point(3, 3, 3))
        self.assertEqual(bbox1.overlaps(bbox2), False)

        bbox3 = BBox(Point(-1, -1, -1),
                     Point(0.5, 0.5, 0.5))
        self.assertEqual(bbox1.overlaps(bbox3), True)

    def test_bounding_box_8(self):
        bbox = BBox(Point(0, 0, 0),
                    Point(2, 3, 2))
        p, r = bbox.bounding_sphere()
        
        self.assertEqual(p, Point(1,1.5,1))
        self.assertEqual(r, math.sqrt(1.5*1.5+1+1))

    def test_bounding_box_9(self):
        bbox = BBox(Point(-1, -1, -1),
                    Point(1, 1, 1))
        ray1 = Ray(Point(10, 10, 10), Vector(-1, -1, -1))
        intersect, hit0, hit1 = bbox.intersect_p(ray1)
        self.assertTrue(intersect)

        ray2 = Ray(Point(10, 10, 10), Vector(-1, 1, -1))
        intersect, hit0, hit1 = bbox.intersect_p(ray2)
        self.assertFalse(intersect)

        ray3 = Ray(Point(0, 0, 10), Vector(0, 0, -1))
        intersect, hit0, hit1 = bbox.intersect_p(ray3)
        self.assertTrue(intersect)
        self.assertEqual(hit0, 9.0)
        self.assertEqual(hit1, 11.0)
Example #7
0
    def test_transform_handedness(self):
        m1 = translate(Point(-17, 2, 31)) * scale(0.5, 6 , 1.4) * rotate(35, Vector(-15, 20, 0.2))
        self.assertFalse(m1.swap_handedness())

        m2 = translate(Point(5, 6, 7)) * scale(2, -3 , 4) * rotate(17, Vector(-1, 4, -2))
        self.assertTrue(m2.swap_handedness())
Example #8
0
 def setUp(self):
     self.q = Quaternion()
     self.q1 = Quaternion(Vector(0.0, 0.0, 1.0), 0.5)
     self.q2 = Quaternion(Vector(1.0, 2.0, 3.0), 0.5)
Example #9
0
 def test_constructor(self):
     self.assertEqual(self.q.v, Vector(0.0, 0.0, 0.0))
     self.assertEqual(self.q.w, 1.0)
Example #10
0
 def setUp(self):
     self.v1 = Vector(1, 1, 1)
     self.v2 = Vector(2, 2, 2)
     self.p1 = Point(1, 1, 1)
     self.p2 = Point(2, 2, 2)
Example #11
0
class TestGeometry(unittest.TestCase):
    def setUp(self):
        self.v1 = Vector(1, 1, 1)
        self.v2 = Vector(2, 2, 2)
        self.p1 = Point(1, 1, 1)
        self.p2 = Point(2, 2, 2)

    def get_random_point(self):
        return Point(
            float(random.randint(0, 100)) / 20.0,
            float(random.randint(0, 100)) / 20.0,
            float(random.randint(0, 100)) / 20.0)

    def test_point(self):
        # operator[]
        p = Point(1.0, 2.0, 3.0)
        self.assertEqual(p[0], 1.0)
        self.assertEqual(p[1], 2.0)
        self.assertEqual(p[2], 3.0)

        self.assertEqual(self.p1 * 4, 2 * self.p2)
        self.assertEqual(self.p2 - self.p1, self.v1)

        # operator[] for assignments
        p = Point(1.0, 2.0, 3.0)
        for i in range(3):
            p[i] = 9.0
            self.assertEqual(p[i], 9.0)

    def test_vector(self):
        # operator[]
        v = Vector(1.0, 2.0, 3.0)
        self.assertEqual(v[0], 1.0)
        self.assertEqual(v[1], 2.0)
        self.assertEqual(v[2], 3.0)

        # misc operators
        self.assertEqual(self.v1 * 4, 2 * self.v2)
        self.assertEqual(self.p2 - self.p1, self.v1)

        # length functions
        self.assertEqual(self.v1.length_squared(), 3)
        self.assertEqual(self.v1.length(), math.sqrt(3))

        # operator[] for assignments
        v = Vector(1.0, 2.0, 3.0)
        for i in range(3):
            v[i] = 9.0
            self.assertEqual(v[i], 9.0)

    def test_normal(self):
        # operator[]
        n = Normal(1.0, 2.0, 3.0)
        self.assertEqual(n[0], 1.0)
        self.assertEqual(n[1], 2.0)
        self.assertEqual(n[2], 3.0)

        # face_forward
        n2 = Normal(1, 0, 0)
        v = Vector(-0.5, -0.1, 0.2)
        self.assertEqual(face_forward(n, v), -n)

        # operator[] for assignments
        n = Normal(1.0, 2.0, 3.0)
        for i in range(3):
            n[i] = 9.0
            self.assertEqual(n[i], 9.0)

    def test_ray(self):
        r = Ray(Point(0, 0, 0), Vector(1, 2, 3))

        # test copy constructor
        r2 = Ray.from_ray(r)
        self.assertTrue(isinstance(r2, Ray))
        self.assertEqual(r2.d, r.d)

        # test constructor from parent ray
        r3 = Ray.from_ray_parent(r.o, r.d, r, r.mint)
        self.assertTrue(isinstance(r3, Ray))
        self.assertEqual(r3.depth, r.depth + 1)

        # test operator()
        p = r(1.7)
        self.assertEqual(p, Point(1.7, 3.4, 5.1))

    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 test_bounding_box_1(self):
        # test default constructor
        b = BBox()
        self.assertEqual(b.p_min,
                         Point(float('inf'), float('inf'), float('inf')))
        self.assertEqual(b.p_max,
                         Point(-float('inf'), -float('inf'), -float('inf')))

    def test_bounding_box_2(self):
        # test constructor from one point
        p = self.get_random_point()
        b1 = BBox(p)
        self.assertEqual(b1.p_min, p)
        self.assertEqual(b1.p_min, b1.p_max)

    def test_bounding_box_3(self):
        # test constructor from two points
        p1 = self.get_random_point()
        p2 = self.get_random_point()
        b2 = BBox(p1, p2)
        for i in range(3):
            self.assertEqual(b2.p_min[i], min(p1[i], p2[i]))
            self.assertEqual(b2.p_max[i], max(p1[i], p2[i]))

    def test_bounding_box_4(self):
        # test copy constructor
        bbox = BBox(Point(5, 5, 5), Point(7, 7, 7))
        bbox2 = BBox.from_bbox(bbox)
        self.assertEqual(bbox.p_min, bbox2.p_min)
        self.assertEqual(bbox.p_max, bbox2.p_max)

        p1 = Point(6, 5.5, 7)
        p2 = Point(6, 7.5, 7)
        p3 = Point(6, 6.5, 4.5)

        # test methods
        self.assertEqual(bbox.inside(p1), True)
        self.assertEqual(bbox.inside(p2), False)
        self.assertEqual(bbox.inside(p3), False)

        bbox.expand(1)
        self.assertEqual(bbox.inside(p1), True)
        self.assertEqual(bbox.inside(p2), True)
        self.assertEqual(bbox.inside(p3), True)

    def test_bounding_box_5(self):
        bbox1 = BBox(Point(0, -2, 0), Point(1, -1, 1))
        p1 = Point(-3, 3, 0.5)
        bbox2 = union(bbox1, p1)
        self.assertEqual(bbox2.p_min, Point(-3, -2, 0))
        self.assertEqual(bbox2.p_max, Point(1, 3, 1))

    def test_bounding_box_6(self):
        bbox1 = BBox(Point(0, -2, 0), Point(1, -1, 1))
        bbox2 = BBox(Point(-2, 0, -2), Point(-1, 1, -1))
        bbox3 = union(bbox1, bbox2)
        self.assertEqual(bbox3.p_min, Point(-2, -2, -2))
        self.assertEqual(bbox3.p_max, Point(1, 1, 1))

    def test_bounding_box_7(self):
        bbox1 = BBox(Point(0, 0, 0), Point(2, 2, 2))

        bbox2 = BBox(Point(2.5, 2.5, 2.5), Point(3, 3, 3))
        self.assertEqual(bbox1.overlaps(bbox2), False)

        bbox3 = BBox(Point(-1, -1, -1), Point(0.5, 0.5, 0.5))
        self.assertEqual(bbox1.overlaps(bbox3), True)

    def test_bounding_box_8(self):
        bbox = BBox(Point(0, 0, 0), Point(2, 3, 2))
        p, r = bbox.bounding_sphere()

        self.assertEqual(p, Point(1, 1.5, 1))
        self.assertEqual(r, math.sqrt(1.5 * 1.5 + 1 + 1))

    def test_bounding_box_9(self):
        bbox = BBox(Point(-1, -1, -1), Point(1, 1, 1))
        ray1 = Ray(Point(10, 10, 10), Vector(-1, -1, -1))
        intersect, hit0, hit1 = bbox.intersect_p(ray1)
        self.assertTrue(intersect)

        ray2 = Ray(Point(10, 10, 10), Vector(-1, 1, -1))
        intersect, hit0, hit1 = bbox.intersect_p(ray2)
        self.assertFalse(intersect)

        ray3 = Ray(Point(0, 0, 10), Vector(0, 0, -1))
        intersect, hit0, hit1 = bbox.intersect_p(ray3)
        self.assertTrue(intersect)
        self.assertEqual(hit0, 9.0)
        self.assertEqual(hit1, 11.0)