Пример #1
0
    def test_sample(self):
        """
        Test random sampling of polygons
        """

        p = g.Point([0, 0]).buffer(1.0)
        count = 100

        s = g.trimesh.path.polygons.sample(p, count=count)
        assert len(s) <= count
        assert s.shape[1] == 2

        radius = (s ** 2).sum(axis=1).max()
        assert radius < (1.0 + 1e-8)

        # test Path2D sample wiring
        path = g.trimesh.load_path(p)
        s = path.sample(count=count)
        assert len(s) <= count
        assert s.shape[1] == 2
        radius = (s ** 2).sum(axis=1).max()
        assert radius < (1.0 + 1e-8)

        # try getting OBB of samples
        T, extents = g.trimesh.path.polygons.polygon_obb(s)
        # OBB of samples should be less than diameter of circle
        diameter = g.np.reshape(p.bounds, (2, 2)).ptp(axis=0).max()
        assert (extents <= diameter).all()

        # test sampling with multiple bodies
        for i in range(3):
            assert g.np.isclose(path.area, p.area * (i + 1))
            path = path + g.trimesh.load_path(
                g.Point([(i + 2) * 2, 0]).buffer(1.0))
            s = path.sample(count=count)
            assert s.shape[1] == 2
Пример #2
0
    def test_rasterize(self):

        test_radius = 1.0
        test_pitch = test_radius / 10.0
        polygon = g.Point([0, 0]).buffer(test_radius)
        (offset, grid,
         grid_points) = g.trimesh.path.polygons.rasterize_polygon(
             polygon=polygon, pitch=test_pitch)
        assert g.trimesh.util.is_shape(grid_points, (-1, 2))

        grid_radius = (grid_points**2).sum(axis=1)**.5
        pixel_diagonal = (test_pitch * (2.0**.5)) / 2.0
        contained = grid_radius <= (test_radius + pixel_diagonal)

        assert contained.all()
Пример #3
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
Пример #4
0
    def test_extrusion(self):
        if not has_triangle:
            return

        transform = g.trimesh.transformations.random_rotation_matrix()
        polygon = g.Point([0, 0]).buffer(.5)
        e = g.trimesh.primitives.Extrusion(polygon=polygon,
                                           transform=transform)

        # will create an inflated version of the extrusion
        b = e.buffer(.1)
        assert b.to_mesh().volume > e.to_mesh().volume
        assert b.contains(e.vertices).all()

        # try making it smaller
        b = e.buffer(-.1)
        assert b.to_mesh().volume < e.to_mesh().volume
        assert e.contains(b.vertices).all()

        # try with negative height
        e = g.trimesh.primitives.Extrusion(polygon=polygon,
                                           height=-1.0,
                                           transform=transform)
        assert e.to_mesh().volume > 0.0

        # will create an inflated version of the extrusion
        b = e.buffer(.1)
        assert b.to_mesh().volume > e.to_mesh().volume
        assert b.contains(e.vertices).all()

        # try making it smaller
        b = e.buffer(-.1)
        assert b.to_mesh().volume < e.to_mesh().volume
        assert e.contains(b.vertices).all()

        # try with negative height and transform
        transform = [[1., 0., 0., -0.], [0., 1., 0., 0.], [-0., -0., -1., -0.],
                     [0., 0., 0., 1.]]
        e = g.trimesh.primitives.Extrusion(polygon=polygon,
                                           height=-1.0,
                                           transform=transform)
        assert e.to_mesh().volume > 0.0

        for T in g.transforms:
            current = e.copy().apply_transform(T)
            # get the special case OBB calculation for extrusions
            obb = current.bounding_box_oriented
            # check to make sure shortcutted OBB is the right size
            assert g.np.isclose(obb.volume,
                                current.to_mesh().bounding_box_oriented.volume)
            # use OBB transform to project vertices of extrusion to plane
            points = g.trimesh.transform_points(
                current.vertices, g.np.linalg.inv(obb.primitive.transform))
            # half extents of calculated oriented bounding box
            half = (g.np.abs(obb.primitive.extents) / 2.0) + 1e-3
            # every vertex should be inside OBB
            assert (points > -half).all()
            assert (points < half).all()

            assert current.direction.shape == (3, )
            assert current.origin.shape == (3, )