Example #1
0
def test_different_from():
    """verify that `BSPNode.different_from` has the expected behavior

    Get a list of planes. Split the object using the first plane, then for each of the other planes, split the object,
    check if the plane is far enough away given the config, then assert that `BSPNode.different_from` returns the
    correct value. This skips any splits that fail.
    """
    config = Configuration.config
    print()
    mesh = trimesh.primitives.Sphere(radius=50)

    tree = bsp_tree.BSPTree(mesh)
    root = tree.nodes[0]
    normal = trimesh.unitize(np.random.rand(3))
    planes = bsp_tree.get_planes(mesh, normal)
    base_node = copy.deepcopy(root)
    base_node = bsp_node.split(base_node, planes[0])

    for plane in planes[1:]:
        # smaller origin offset, should not be different
        test_node = copy.deepcopy(root)
        test_node = bsp_node.split(test_node, plane)
        if abs((plane[0] - planes[0][0])
               @ planes[0][1]) > config.different_origin_th:
            assert base_node.different_from(test_node)
        else:
            assert not base_node.different_from(test_node)

    # smaller angle difference, should not be different
    test_node = copy.deepcopy(root)
    random_vector = trimesh.unitize(np.random.rand(3))
    axis = np.cross(random_vector, planes[0][1])
    rotation = trimesh.transformations.rotation_matrix(np.pi / 11, axis)
    normal = trimesh.transform_points(planes[0][1][None, :], rotation)[0]
    test_plane = (planes[0][0], normal)
    test_node = bsp_node.split(test_node, test_plane)
    assert not base_node.different_from(test_node)

    # larger angle difference, should be different
    test_node = copy.deepcopy(root)
    random_vector = trimesh.unitize(np.random.rand(3))
    axis = np.cross(random_vector, planes[0][1])
    rotation = trimesh.transformations.rotation_matrix(np.pi / 9, axis)
    normal = trimesh.transform_points(planes[0][1][None, :], rotation)[0]
    test_plane = (planes[0][0], normal)
    test_node = bsp_node.split(test_node, test_plane)
    assert base_node.different_from(test_node)
Example #2
0
 def test_align(self):
     log.info('Testing vector alignment')
     target = np.array([0, 0, 1])
     for i in range(100):
         vector = trimesh.unitize(np.random.random(3) - .5)
         T = trimesh.geometry.align_vectors(vector, target)
         result = np.dot(T, np.append(vector, 1))[0:3]
         aligned = np.abs(result - target).sum() < TOL_ZERO
         self.assertTrue(aligned)
Example #3
0
 def test_align(self):
     log.info('Testing vector alignment')
     target = np.array([0,0,1])
     for i in range(100):
         vector  = trimesh.unitize(np.random.random(3) - .5)
         T       = trimesh.geometry.align_vectors(vector, target)
         result  = np.dot(T, np.append(vector, 1))[0:3]
         aligned = np.abs(result-target).sum() < TOL_ZERO
         self.assertTrue(aligned)
Example #4
0
    def test_unitize_multi(self):
        vectors = np.ones(self.test_dim)
        vectors[0] = [0, 0, 0]
        vectors, valid = trimesh.unitize(vectors, check_valid=True)

        assert not valid[0]
        assert valid[1:].all()

        length = np.sum(vectors[1:]**2, axis=1)**.5
        assert np.allclose(length, 1.0)
Example #5
0
    def test_unitize_multi(self):
        vectors = np.ones(self.test_dim)
        vectors[0] = [0, 0, 0]
        vectors, valid = trimesh.unitize(vectors, check_valid=True)

        assert not valid[0]
        assert valid[1:].all()

        length = np.sum(vectors[1:] ** 2, axis=1) ** .5
        assert np.allclose(length, 1.0)
Example #6
0
    def test_unitize_multi(self):
        vectors = np.ones(self.test_dim)
        vectors[0] = [0, 0, 0]
        vectors, valid = trimesh.unitize(vectors, check_valid=True)

        self.assertFalse(valid[0])
        self.assertTrue(np.all(valid[1:]))

        length = np.sum(vectors[1:]**2, axis=1)**2
        length_check = np.abs(length - 1.0) < TOL_ZERO
        self.assertTrue(np.all(length_check))
Example #7
0
 def test_unitize_multi(self):
     vectors = np.ones(self.test_dim)
     vectors[0] = [0,0,0]
     vectors, valid = trimesh.unitize(vectors, check_valid=True)
     
     self.assertFalse(valid[0])
     self.assertTrue(np.all(valid[1:]))
     
     length       = np.sum(vectors[1:] ** 2, axis=1) ** 2
     length_check = np.abs(length - 1.0) < TOL_ZERO
     self.assertTrue(np.all(length_check))
Example #8
0
 def test_horn(self):
     log.info('Testing absolute orientation')
     for i in range(10):
         points_A = (np.random.random(self.test_dim) - .5) * 100
         angle    = 4*np.pi*(np.random.random() - .5)
         vector   = trimesh.unitize(np.random.random(3) - .5)
         offset   = 100*(np.random.random(3)-.5)
         T        = trimesh.transformations.rotation_matrix(angle, vector)
         T[0:3,3] = offset
         points_B = trimesh.points.transform_points(points_A, T)
         M, error = trimesh.points.absolute_orientation(points_A, points_B, return_error=True)
         self.assertTrue(np.all(error < TOL_ZERO))
Example #9
0
    def test_hemisphere(self):
        v = trimesh.unitize(np.random.random((10000, 3)) - .5)
        v[0] = [0, 1, 0]
        v[1] = [1, 0, 0]
        v[2] = [0, 0, 1]
        v = np.column_stack((v, -v)).reshape((-1, 3))

        resigned = trimesh.util.vector_hemisphere(v)

        check = (abs(np.diff(resigned.reshape((-1, 2, 3)),
                             axis=1).sum(axis=2)) < trimesh.constants.tol.zero).all()
        self.assertTrue(check)
Example #10
0
def test_get_planes(config):
    """verify that for the default bunny mesh, which is a single part, all planes returned by `bsp_tree.get_planes`
        cut through the mesh (they have a good cross section)
    """
    mesh = trimesh.load(config.mesh, validate=True)

    for i in range(100):
        normal = trimesh.unitize(np.random.rand(3))
        planes = bsp_tree.get_planes(mesh, normal)

        for origin, normal in planes:
            path3d = mesh.section(plane_origin=origin, plane_normal=normal)
            assert path3d is not None
Example #11
0
 def test_horn(self):
     log.info('Testing absolute orientation')
     for i in range(10):
         points_A = (np.random.random(self.test_dim) - .5) * 100
         angle = 4 * np.pi * (np.random.random() - .5)
         vector = trimesh.unitize(np.random.random(3) - .5)
         offset = 100 * (np.random.random(3) - .5)
         T = trimesh.transformations.rotation_matrix(angle, vector)
         T[0:3, 3] = offset
         points_B = trimesh.transformations.transform_points(points_A, T)
         M, error = trimesh.points.absolute_orientation(
             points_A, points_B, return_error=True)
         self.assertTrue(np.all(error < TOL_ZERO))
Example #12
0
def camera_to_rays(camera):
    """
    Convert a trimesh.scene.Camera object to ray origins
    and direction vectors.

    Parameters
    --------------
    camera : trimesh.scene.Camera
      Camera with transform defined

    Returns
    --------------
    origins : (n, 3) float
      Ray origins in space
    vectors : (n, 3) float
      Ray direction unit vectors
    angles : (n, 2) float
      Ray spherical coordinate angles in radians
    """
    # radians of half the field of view
    half = np.radians(camera.fov / 2.0)
    # scale it down by two pixels to keep image under resolution
    half *= (camera.resolution - 2) / camera.resolution
    # get FOV angular bounds in radians

    # create an evenly spaced list of angles
    angles = trimesh.util.grid_linspace(bounds=[-half, half],
                                        count=camera.resolution)

    # turn the angles into unit vectors
    vectors = trimesh.unitize(
        np.column_stack((np.sin(angles), np.ones(len(angles)))))

    # flip the camera transform to change sign of Z
    transform = np.dot(camera.transform,
                       trimesh.geometry.align_vectors([1, 0, 0], [-1, 0, 0]))

    # apply the rotation to the direction vectors
    vectors = trimesh.transform_points(vectors, transform, translate=False)

    # camera origin is single point, extract from transform
    origin = trimesh.transformations.translation_from_matrix(transform)
    # tile it into corresponding list of ray vectorsy
    origins = np.ones_like(vectors) * origin

    return origins, vectors, angles
Example #13
0
def random_rotate(mesh):
    mesh = mesh.copy()
    angle_rad = np.random.rand() * 2 * np.pi
    direction = trimesh.unitize(np.random.rand(3))
    rot = trimesh.transformations.rotation_matrix(angle_rad, direction, [0, 0, 0])
    return mesh.apply_transform(rot)