Пример #1
0
    def test_lookat(self):
        """
        Test the "look at points" function
        """
        # original points
        ori = np.array([[-1, -1],
                        [1, -1],
                        [1, 1],
                        [-1, 1]])

        for i in range(10):
            # set the extents to be random but positive
            extents = g.random() * 10
            points = g.trimesh.util.stack_3D(ori.copy() * extents)

            fov = g.np.array([20, 50])

            # offset the points by a random amount
            offset = (g.random(3) - 0.5) * 100
            T = g.trimesh.scene.cameras.look_at(points + offset, fov)

            # check using trig
            check = (points.ptp(axis=0)[:2] / 2.0) / \
                g.np.tan(np.radians(fov / 2))
            check += points[:, 2].mean()

            # Z should be the same as maximum trig option
            assert np.linalg.inv(T)[2, 3] >= check.max()

        # just run to test other arguments
        # TODO(unknown): find the way to test it correctly
        g.trimesh.scene.cameras.look_at(points, fov, center=points[0])
        g.trimesh.scene.cameras.look_at(points, fov, distance=1)
Пример #2
0
    def test_svg(self):
        from trimesh.path.segments import to_svg
        # create some 2D segments
        seg = g.random((1000, 2, 2))
        # make one of the segments a duplicate
        seg[0] = seg[-1]
        # create an SVG path string
        svg = to_svg(seg, merge=False)
        # should be one move and one line per segment
        assert svg.count('M') == len(seg)
        assert svg.count('L') == len(seg)

        # try with a transform
        svg = to_svg(seg, matrix=g.np.eye(3), merge=False)
        assert svg.count('M') == len(seg)
        assert svg.count('L') == len(seg)

        # remove the duplicate segments
        svg = to_svg(seg, matrix=g.np.eye(3), merge=True)
        assert svg.count('M') < len(seg)
        assert svg.count('L') < len(seg)

        try:
            to_svg(g.random((100, 2, 3)))
        except ValueError:
            return
        raise ValueError('to_svg accepted wrong input!')
Пример #3
0
    def test_lookat(self):
        """
        Test the "look at points" function
        """
        # original points
        ori = np.array([[-1, -1],
                        [1, -1],
                        [1, 1],
                        [-1, 1]])

        for i in range(10):
            # set the extents to be random but positive
            extents = g.random() * 10
            points = g.trimesh.util.stack_3D(ori.copy() * extents)

            fov = g.np.array([20, 50])

            # offset the points by a random amount
            offset = (g.random(3) - 0.5) * 100
            T = g.trimesh.scene.cameras.look_at(points + offset, fov)

            # check using trig
            check = (points.ptp(axis=0)[:2] / 2.0) / \
                g.np.tan(np.radians(fov / 2))
            check += points[:, 2].mean()

            # Z should be the same as maximum trig option
            assert np.linalg.inv(T)[2, 3] >= check.max()

        # just run to test other arguments
        # TODO(unknown): find the way to test it correctly
        g.trimesh.scene.cameras.look_at(points, fov, center=points[0])
        g.trimesh.scene.cameras.look_at(points, fov, distance=1)
Пример #4
0
    def test_svg(self):
        from trimesh.path.segments import to_svg
        # create some 2D segments
        seg = g.random((1000, 2, 2))
        # create an SVG path string
        svg = to_svg(seg)
        # should be one move and one line per segment
        assert svg.count('M') == len(seg)
        assert svg.count('L') == len(seg)

        try:
            to_svg(g.random((100, 2, 3)))
        except ValueError:
            return
        raise ValueError('to_svg accepted wrong input!')
Пример #5
0
    def test_truncated(self, count=10):
        # create some random triangles
        tri = g.random((count, 3, 3))

        m = g.trimesh.creation.truncated_prisms(tri)
        split = m.split()
        assert m.body_count == count
        assert len(split) == count
        assert all(s.volume > 0 for s in split)
Пример #6
0
 def test_resample(self):
     from trimesh.path.segments import length, resample
     # create some random segments
     seg = g.random((1000, 2, 3))
     # set a maximum segment length
     maxlen = 0.1
     # one of the original segments should be longer than maxlen
     assert (length(seg, summed=False) > maxlen).any()
     # resample to be all shorter than maxlen
     res = resample(seg, maxlen=maxlen)
     # check lengths of the resampled result
     assert (length(res, summed=False) < maxlen).all()
     # make sure overall length hasn't changed
     assert g.np.isclose(length(res), length(seg))
Пример #7
0
    def test_extrude(self):
        from trimesh.path.segments import extrude
        # hand tuned segments
        manual = g.np.column_stack((g.np.zeros(
            (3, 2)), [[0, 1], [0, -1], [1, 2]])).reshape((-1, 2, 2))

        for seg in [manual, g.random((10, 2, 2))]:
            height = 1.22
            v, f = extrude(segments=seg, height=height)
            # load extrusion as mesh
            mesh = g.trimesh.Trimesh(vertices=v, faces=f)
            # load line segments as path
            path = g.trimesh.load_path(seg)
            # compare area of mesh with source path
            assert g.np.isclose(mesh.area, path.length * height)
Пример #8
0
 def test_bounds_tree(self):
     # test r-tree intersections
     for dimension in (2, 3):
         # create some (n, 2, 3) bounds
         bounds = g.np.array(
             [[i.min(axis=0), i.max(axis=0)]
              for i in [g.random((4, dimension)) for i in range(10)]])
         tree = g.trimesh.util.bounds_tree(bounds)
         for i, b in enumerate(bounds):
             assert i in set(tree.intersection(b.ravel()))
         # construct tree with per-row bounds
         tree = g.trimesh.util.bounds_tree(
             bounds.reshape((-1, dimension * 2)))
         for i, b in enumerate(bounds):
             assert i in set(tree.intersection(b.ravel()))
Пример #9
0
    def test_kmeans(self, cluster_count=5, points_per_cluster=100):
        """
        Test K-means clustering
        """
        clustered = []
        for i in range(cluster_count):
            # use repeatable random- ish coordinatez
            clustered.append(g.random((points_per_cluster, 3)) + (i * 10.0))
        clustered = g.np.vstack(clustered)

        # run k- means clustering on our nicely separated data
        centroids, klabel = g.trimesh.points.k_means(points=clustered,
                                                     k=cluster_count)

        # reshape to make sure all groups have the same index
        variance = klabel.reshape(
            (cluster_count, points_per_cluster)).ptp(axis=1)

        assert len(centroids) == cluster_count
        assert (variance == 0).all()
Пример #10
0
    def test_kmeans(self,
                    cluster_count=5,
                    points_per_cluster=100):
        """
        Test K-means clustering
        """
        clustered = []
        for i in range(cluster_count):
            # use repeatable random- ish coordinatez
            clustered.append(
                g.random((points_per_cluster, 3)) + (i * 10.0))
        clustered = g.np.vstack(clustered)

        # run k- means clustering on our nicely separated data
        centroids, klabel = g.trimesh.points.k_means(points=clustered,
                                                     k=cluster_count)

        # reshape to make sure all groups have the same index
        variance = klabel.reshape(
            (cluster_count, points_per_cluster)).ptp(
            axis=1)

        assert len(centroids) == cluster_count
        assert (variance == 0).all()
Пример #11
0
    def check_nearest_point_function(self, fun):
        # def plot_tri(tri, color='g'):
        #     plottable = g.np.vstack((tri, tri[0]))
        #     plt.plot(plottable[:, 0], plottable[:, 1], color=color)

        def points_on_circle(count):
            theta = g.np.linspace(0, g.np.pi * 2, count + 1)[:count]
            s = g.np.column_stack((theta, [g.np.pi / 2] * count))
            t = g.trimesh.util.spherical_to_vector(s)
            return t

        # generate some pseudorandom triangles
        # use our random to avoid spurious failures
        triangles = g.random((100, 3, 3)) - 0.5
        # put them on- plane
        triangles[:, :, 2] = 0.0

        # make one of the triangles equilaterial
        triangles[-1] = points_on_circle(3)

        # a circle of points surrounding the triangle
        query = points_on_circle(63) * 2
        # set the points up in space
        query[:, 2] = 10
        # a circle of points inside-ish the triangle
        query = g.np.vstack((query, query * .1))

        # loop through each triangle
        for triangle in triangles:
            # create a mesh with one triangle
            mesh = g.Trimesh(**g.trimesh.triangles.to_kwargs([triangle]))

            result, result_distance, result_tid = fun(mesh, query)

            polygon = g.Polygon(triangle[:, 0:2])
            polygon_buffer = polygon.buffer(1e-5)

            # all of the points returned should be on the triangle we're
            # querying
            assert all(polygon_buffer.intersects(
                g.Point(i)) for i in result[:, 0:2])

            # see what distance shapely thinks the nearest point
            # is for the 2D triangle and the query points
            distance_shapely = g.np.array([polygon.distance(g.Point(i))
                                           for i in query[:, :2]])

            # see what distance our function returned for the nearest point
            distance_ours = ((query[:, :2] - result[:, :2])
                             ** 2).sum(axis=1) ** .5

            # how far was our distance from the one shapely gave
            distance_test = g.np.abs(distance_shapely - distance_ours)  # NOQA

            # we should have calculated the same distance as shapely
            assert g.np.allclose(distance_ours, distance_shapely)

        # now check to make sure closest point doesn't depend on
        # the frame, IE the results should be the same after
        # any rigid transform
        # chop query off to same length as triangles
        assert len(query) > len(triangles)
        query = query[:len(triangles)]
        # run the closest point query as a corresponding query
        close = g.trimesh.triangles.closest_point(triangles=triangles,
                                                  points=query)
        # distance between closest point and query point
        # this should stay the same regardless of frame
        distance = g.np.linalg.norm(close - query, axis=1)
        for T in g.transforms:
            # transform the query points
            points = g.trimesh.transform_points(query, T)
            # transform the triangles we're checking
            tri = g.trimesh.transform_points(
                triangles.reshape((-1, 3)), T).reshape((-1, 3, 3))
            # run the closest point check
            check = g.trimesh.triangles.closest_point(triangles=tri,
                                                      points=points)
            check_distance = g.np.linalg.norm(check - points, axis=1)
            # should be the same in any frame
            assert g.np.allclose(check_distance, distance)

        return result, result_distance
Пример #12
0
    def check_nearest_point_function(self, fun):
        # def plot_tri(tri, color='g'):
        #     plottable = g.np.vstack((tri, tri[0]))
        #     plt.plot(plottable[:, 0], plottable[:, 1], color=color)

        def points_on_circle(count):
            theta = g.np.linspace(0, g.np.pi * 2, count + 1)[:count]
            s = g.np.column_stack((theta, [g.np.pi / 2] * count))
            t = g.trimesh.util.spherical_to_vector(s)
            return t

        # generate some pseudorandom triangles
        # use our random to avoid spurious failures
        triangles = g.random((100, 3, 3)) - 0.5
        # put them on- plane
        triangles[:, :, 2] = 0.0

        # make one of the triangles equilaterial
        triangles[-1] = points_on_circle(3)

        # a circle of points surrounding the triangle
        query = points_on_circle(63) * 2
        # set the points up in space
        query[:, 2] = 10
        # a circle of points inside-ish the triangle
        query = g.np.vstack((query, query * .1))

        # loop through each triangle
        for triangle in triangles:
            # create a mesh with one triangle
            mesh = g.Trimesh(**g.trimesh.triangles.to_kwargs([triangle]))

            result, result_distance, result_tid = fun(mesh, query)

            polygon = g.Polygon(triangle[:, 0:2])
            polygon_buffer = polygon.buffer(1e-5)

            # all of the points returned should be on the triangle we're
            # querying
            assert all(polygon_buffer.intersects(
                g.Point(i)) for i in result[:, 0:2])

            # see what distance shapely thinks the nearest point
            # is for the 2D triangle and the query points
            distance_shapely = g.np.array([polygon.distance(g.Point(i))
                                           for i in query[:, :2]])

            # see what distance our function returned for the nearest point
            distance_ours = ((query[:, :2] - result[:, :2])
                             ** 2).sum(axis=1) ** .5

            # how far was our distance from the one shapely gave
            distance_test = g.np.abs(distance_shapely - distance_ours)  # NOQA

            # we should have calculated the same distance as shapely
            assert g.np.allclose(distance_ours, distance_shapely)

        # now check to make sure closest point doesn't depend on
        # the frame, IE the results should be the same after
        # any rigid transform
        # chop query off to same length as triangles
        assert len(query) > len(triangles)
        query = query[:len(triangles)]
        # run the closest point query as a corresponding query
        close = g.trimesh.triangles.closest_point(triangles=triangles,
                                                  points=query)
        # distance between closest point and query point
        # this should stay the same regardless of frame
        distance = g.np.linalg.norm(close - query, axis=1)
        for T in g.transforms:
            # transform the query points
            points = g.trimesh.transform_points(query, T)
            # transform the triangles we're checking
            tri = g.trimesh.transform_points(
                triangles.reshape((-1, 3)), T).reshape((-1, 3, 3))
            # run the closest point check
            check = g.trimesh.triangles.closest_point(triangles=tri,
                                                      points=points)
            check_distance = g.np.linalg.norm(check - points, axis=1)
            # should be the same in any frame
            assert g.np.allclose(check_distance, distance)

        return result, result_distance